consider hidden apps as frozen, instead of disabled ones

This commit is contained in:
Peter Cai 2018-08-22 18:15:08 +08:00
parent db326949f3
commit 271304240f
No known key found for this signature in database
GPG key ID: 71F5FB4E4F3FD54F
3 changed files with 38 additions and 8 deletions

View file

@ -33,6 +33,7 @@ public class ShelterService extends Service {
private DevicePolicyManager mPolicyManager = null;
private boolean mIsProfileOwner = false;
private PackageManager mPackageManager = null;
private ComponentName mAdminComponent = null;
private IShelterService.Stub mBinder = new IShelterService.Stub() {
@Override
public void stopShelterService(boolean kill) {
@ -56,19 +57,30 @@ public class ShelterService extends Service {
@Override
public void getApps(IGetAppsCallback callback) {
new Thread(() -> {
List<ApplicationInfoWrapper> list = mPackageManager.getInstalledApplications(PackageManager.MATCH_DISABLED_COMPONENTS)
List<ApplicationInfoWrapper> list = mPackageManager.getInstalledApplications(PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_UNINSTALLED_PACKAGES)
.stream()
.filter((it) -> !it.packageName.equals(getPackageName()))
.filter((it) ->
// Show if:
// - Isn't system app OR
// - Is disabled OR
// - Is hidden ("frozen") OR
// - Has a launch method
(it.flags & ApplicationInfo.FLAG_SYSTEM) == 0
|| !it.enabled
|| isHidden(it.packageName)
|| mPackageManager.getLaunchIntentForPackage(it.packageName) != null)
.map(ApplicationInfoWrapper::new)
.map((it) -> it.loadLabel(mPackageManager))
.map((it) -> it.loadLabel(mPackageManager)
.setHidden(isHidden(it.getPackageName())))
.sorted((x, y) -> {
// Sort hidden apps at the last
if (x.isHidden() && !y.isHidden()) {
return 1;
} else if (!x.isHidden() && y.isHidden()) {
return -1;
} else {
return x.getLabel().compareTo(y.getLabel());
}
})
.collect(Collectors.toList());
try {
@ -113,12 +125,12 @@ public class ShelterService extends Service {
if (mIsProfileOwner) {
// We can only enable system apps in our own profile
mPolicyManager.enableSystemApp(
new ComponentName(getApplicationContext(), ShelterDeviceAdminReceiver.class),
mAdminComponent,
app.getPackageName());
// Also set the hidden state to false.
mPolicyManager.setApplicationHidden(
new ComponentName(getApplicationContext(), ShelterDeviceAdminReceiver.class),
mAdminComponent,
app.getPackageName(), false);
callback.callback(Activity.RESULT_OK);
@ -147,7 +159,7 @@ public class ShelterService extends Service {
// This is essentially the same as disabling the system app
// There is no way to reverse the "enableSystemApp" operation here
mPolicyManager.setApplicationHidden(
new ComponentName(getApplicationContext(), ShelterDeviceAdminReceiver.class),
mAdminComponent,
app.getPackageName(), true);
callback.callback(Activity.RESULT_OK);
} else {
@ -162,6 +174,7 @@ public class ShelterService extends Service {
mPolicyManager = getSystemService(DevicePolicyManager.class);
mPackageManager = getPackageManager();
mIsProfileOwner = mPolicyManager.isProfileOwnerApp(getPackageName());
mAdminComponent = new ComponentName(getApplicationContext(), ShelterDeviceAdminReceiver.class);
}
@Nullable
@ -173,6 +186,10 @@ public class ShelterService extends Service {
return mBinder;
}
private boolean isHidden(String packageName) {
return mIsProfileOwner && mPolicyManager.isApplicationHidden(mAdminComponent, packageName);
}
private void setForeground() {
// Android O and later: Notification Channel
// TODO: Maybe backport to pre-O?

View file

@ -59,7 +59,7 @@ public class AppListAdapter extends RecyclerView.Adapter<AppListAdapter.ViewHold
ApplicationInfoWrapper info = mList.get(mIndex);
mPackage.setText(info.getPackageName());
if (!info.getEnabled()) {
if (info.isHidden()) {
String label = String.format(mLabelDisabled, info.getLabel());
mTitle.setText(label);
mView.setBackgroundResource(R.color.disabledAppBackground);

View file

@ -17,12 +17,14 @@ public class ApplicationInfoWrapper implements Parcelable {
ApplicationInfoWrapper info = new ApplicationInfoWrapper();
info.mInfo = source.readParcelable(ApplicationInfo.class.getClassLoader());
info.mLabel = source.readString();
info.mIsHidden = source.readByte() != 0;
return info;
}
};
private ApplicationInfo mInfo = null;
private String mLabel = null;
private boolean mIsHidden = false;
private ApplicationInfoWrapper() {}
@ -35,6 +37,12 @@ public class ApplicationInfoWrapper implements Parcelable {
return this;
}
// Only used from ShelterService
public ApplicationInfoWrapper setHidden(boolean hidden) {
mIsHidden = hidden;
return this;
}
public String getPackageName() {
return mInfo.packageName;
}
@ -52,6 +60,10 @@ public class ApplicationInfoWrapper implements Parcelable {
return mInfo.enabled;
}
public boolean isHidden() {
return mIsHidden;
}
public ApplicationInfo getInfo() {
return mInfo;
}
@ -64,6 +76,7 @@ public class ApplicationInfoWrapper implements Parcelable {
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(mInfo, flags);
dest.writeString(mLabel);
dest.writeByte((byte) (mIsHidden ? 1 : 0));
}
@Override