MainActivity: add option to temporarily show all apps

This can be useful when certain necessary system apps are not
enabled by default on some faulty vendor-customized ROMs.
This commit is contained in:
Peter Cai 2019-01-30 19:46:37 +08:00
parent bcbab7f7db
commit 6cb0a47dc8
No known key found for this signature in database
GPG key ID: 71F5FB4E4F3FD54F
8 changed files with 66 additions and 16 deletions

View file

@ -12,7 +12,7 @@ import net.typeblog.shelter.util.UriForwardProxy;
interface IShelterService {
void ping();
void stopShelterService(boolean kill);
void getApps(IGetAppsCallback callback);
void getApps(IGetAppsCallback callback, boolean showAll);
void loadIcon(in ApplicationInfoWrapper info, ILoadIconCallback callback);
void installApp(in ApplicationInfoWrapper app, IAppInstallCallback callback);
void installApk(in UriForwardProxy uri, IAppInstallCallback callback);

View file

@ -61,7 +61,7 @@ public class ShelterService extends Service {
}
@Override
public void getApps(IGetAppsCallback callback) {
public void getApps(IGetAppsCallback callback, boolean showAll) {
new Thread(() -> {
int pmFlags = PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_UNINSTALLED_PACKAGES;
List<ApplicationInfoWrapper> list = mPackageManager.getInstalledApplications(pmFlags)
@ -73,7 +73,7 @@ public class ShelterService extends Service {
boolean isInstalled = (it.flags & ApplicationInfo.FLAG_INSTALLED) != 0;
boolean canLaunch = mPackageManager.getLaunchIntentForPackage(it.packageName) != null;
return (!isSystem && isInstalled) || isHidden || canLaunch;
return showAll || (!isSystem && isInstalled) || isHidden || canLaunch;
})
.map(ApplicationInfoWrapper::new)
.map((it) -> it.loadLabel(mPackageManager)

View file

@ -46,7 +46,7 @@ import java.util.Set;
import java.util.stream.Collectors;
public class AppListFragment extends BaseFragment {
private static final String BROADCAST_REFRESH = "net.typeblog.shelter.broadcast.REFRESH";
static final String BROADCAST_REFRESH = "net.typeblog.shelter.broadcast.REFRESH";
// Menu Items
private static final int MENU_ITEM_CLONE = 10001;
@ -202,7 +202,7 @@ public class AppListFragment extends BaseFragment {
mRefreshing = false;
});
}
});
}, ((MainActivity) getActivity()).mShowAll);
} catch (RemoteException e) {
// Just... do nothing for now
}
@ -260,15 +260,24 @@ public class AppListFragment extends BaseFragment {
if (mSelectedApp == null) return;
if (mIsRemote) {
// Determine if the app is able to launch
// Un-launchable apps are normally hidden, but can be shown with the "show all" option
// All launching-related menu options should be hidden for apps that cannot be launched
boolean canLaunch = mSelectedApp.canLaunch(getContext().getPackageManager());
if (!mSelectedApp.isSystem())
menu.add(Menu.NONE, MENU_ITEM_CLONE, Menu.NONE, R.string.clone_to_main_profile);
// Freezing / Unfreezing is only available in profiles that we can control
if (mSelectedApp.isHidden()) {
menu.add(Menu.NONE, MENU_ITEM_UNFREEZE, Menu.NONE, R.string.unfreeze_app);
menu.add(Menu.NONE, MENU_ITEM_LAUNCH, Menu.NONE, R.string.unfreeze_and_launch);
if (canLaunch)
menu.add(Menu.NONE, MENU_ITEM_LAUNCH, Menu.NONE, R.string.unfreeze_and_launch);
} else {
menu.add(Menu.NONE, MENU_ITEM_FREEZE, Menu.NONE, R.string.freeze_app);
menu.add(Menu.NONE, MENU_ITEM_LAUNCH, Menu.NONE, R.string.launch);
if (canLaunch)
menu.add(Menu.NONE, MENU_ITEM_LAUNCH, Menu.NONE, R.string.launch);
}
// Cross-profile widget settings is also limited to work profile
MenuItem crossProfileWdiegt =
@ -277,15 +286,19 @@ public class AppListFragment extends BaseFragment {
crossProfileWdiegt.setCheckable(true);
crossProfileWdiegt.setChecked(
mCrossProfileWidgetProviders.contains(mSelectedApp.getPackageName()));
// TODO: If we implement God Mode (i.e. Shelter as device owner), we should
// TODO: use two different lists to store auto freeze apps because we'll be
// TODO: able to freeze apps in main profile.
MenuItem autoFreeze = menu.add(Menu.NONE, MENU_ITEM_AUTO_FREEZE, Menu.NONE, R.string.auto_freeze);
autoFreeze.setCheckable(true);
autoFreeze.setChecked(
LocalStorageManager.getInstance().stringListContains(
LocalStorageManager.PREF_AUTO_FREEZE_LIST_WORK_PROFILE, mSelectedApp.getPackageName()));
menu.add(Menu.NONE, MENU_ITEM_CREATE_UNFREEZE_SHORTCUT, Menu.NONE, R.string.create_unfreeze_shortcut);
// Auto-freeze only works with launchable apps
if (canLaunch) {
// TODO: If we implement God Mode (i.e. Shelter as device owner), we should
// TODO: use two different lists to store auto freeze apps because we'll be
// TODO: able to freeze apps in main profile.
MenuItem autoFreeze = menu.add(Menu.NONE, MENU_ITEM_AUTO_FREEZE, Menu.NONE, R.string.auto_freeze);
autoFreeze.setCheckable(true);
autoFreeze.setChecked(
LocalStorageManager.getInstance().stringListContains(
LocalStorageManager.PREF_AUTO_FREEZE_LIST_WORK_PROFILE, mSelectedApp.getPackageName()));
menu.add(Menu.NONE, MENU_ITEM_CREATE_UNFREEZE_SHORTCUT, Menu.NONE, R.string.create_unfreeze_shortcut);
}
} else {
menu.add(Menu.NONE, MENU_ITEM_CLONE, Menu.NONE, R.string.clone_to_work_profile);
}

View file

@ -64,6 +64,10 @@ public class MainActivity extends AppCompatActivity {
private ViewPager mPager = null;
private TabLayout mTabs = null;
// Show all applications or not
// default to false
boolean mShowAll = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -367,6 +371,25 @@ public class MainActivity extends AppCompatActivity {
openApkIntent.setType("application/vnd.android.package-archive");
startActivityForResult(openApkIntent, REQUEST_DOCUMENTS_CHOOSE_APK);
return true;
case R.id.main_menu_show_all:
Runnable update = () -> {
mShowAll = !item.isChecked();
item.setChecked(mShowAll);
LocalBroadcastManager.getInstance(this)
.sendBroadcast(new Intent(AppListFragment.BROADCAST_REFRESH));
};
if (!item.isChecked()) {
new AlertDialog.Builder(this)
.setMessage(R.string.show_all_warning)
.setPositiveButton(R.string.first_run_alert_continue,
(dialog, which) -> update.run())
.setNegativeButton(R.string.first_run_alert_cancel, null)
.show();
} else {
update.run();
}
return true;
}
return super.onOptionsItemSelected(item);
}

View file

@ -37,6 +37,10 @@ public class ApplicationInfoWrapper implements Parcelable {
return this;
}
public boolean canLaunch(PackageManager pm) {
return pm.getLaunchIntentForPackage(mInfo.packageName) != null;
}
// Only used from ShelterService
public ApplicationInfoWrapper setHidden(boolean hidden) {
mIsHidden = hidden;

View file

@ -20,4 +20,10 @@
<item
android:id="@+id/main_menu_install_app_to_profile"
android:title="@string/install_app_to_profile" />
<item
android:id="@+id/main_menu_show_all"
android:title="@string/show_all"
android:checkable="true"
android:checked="false" />
</menu>

View file

@ -36,6 +36,8 @@
<string name="freeze_all_shortcut">冻结</string>
<string name="install_app_to_profile">安装 APK 到 Shelter</string>
<string name="install_app_to_profile_success">已成功在工作用户内安装 APK</string>
<string name="show_all">显示全部应用</string>
<string name="show_all_warning">对列表中默认隐藏的应用执行操作可能导致崩溃以及其他各种无法预料的行为。但是当您的手机厂商没有正确在工作用户中开启所有必要的系统组件应用的时候这个功能可以帮助您解决问题。如果您选择继续您确保您了解您在做什么Shelter 无法提供任何保证。</string>
<!-- Settings Options -->
<string name="settings">设置</string>

View file

@ -38,6 +38,8 @@
<string name="freeze_all_shortcut">Freeze</string>
<string name="install_app_to_profile">Install APK into Shelter</string>
<string name="install_app_to_profile_success">Application installation finished in work profile.</string>
<string name="show_all">Show All Apps</string>
<string name="show_all_warning">Manipulating apps that are hidden from the list could cause crashes and all sorts of unexpected behavior. However, this feature can be useful when faulty vendor-customized ROMs does not enable all necessary system apps in work profile by default. If you continue, you are on your own.</string>
<!-- Settings Options -->
<string name="settings">Settings</string>