Cache default home
Bug: 162102512 Cache the default home app (package) in the slice manager. The cache is invalidated whenever the HOME role is changed. Test: Tested with a debug build that computed the cached value and then compared it to the original computation. Verify that no discrepancies are detected. * Manual test - 1. Install the 3P Nova Launcher app. 2. Choose Nova Launcher as the default home app 3. Choose Pixel Launcher as the default home app 4. Choose NOva Launcher as the default and then uninstall the app * FrameworksServicesTests:UserSystemPackageInstallerTest * UserLifecycleTests Change-Id: I8e31acced3b41262641c522842e5f553c63af102
This commit is contained in:
@@ -28,6 +28,8 @@ import static android.os.Process.SYSTEM_UID;
|
||||
import android.Manifest.permission;
|
||||
import android.annotation.NonNull;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.role.OnRoleHoldersChangedListener;
|
||||
import android.app.role.RoleManager;
|
||||
import android.app.slice.ISliceManager;
|
||||
import android.app.slice.SliceSpec;
|
||||
import android.app.usage.UsageStatsManagerInternal;
|
||||
@@ -77,6 +79,7 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class SliceManagerService extends ISliceManager.Stub {
|
||||
@@ -121,6 +124,7 @@ public class SliceManagerService extends ISliceManager.Stub {
|
||||
filter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
|
||||
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
|
||||
filter.addDataScheme("package");
|
||||
mRoleObserver = new RoleObserver();
|
||||
mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
|
||||
}
|
||||
|
||||
@@ -478,10 +482,26 @@ public class SliceManagerService extends ISliceManager.Stub {
|
||||
return cn.getPackageName();
|
||||
}
|
||||
|
||||
/**
|
||||
* A cached value of the default home app
|
||||
*/
|
||||
private String mCachedDefaultHome = null;
|
||||
|
||||
// Based on getDefaultHome in ShortcutService.
|
||||
// TODO: Unify if possible
|
||||
@VisibleForTesting
|
||||
protected String getDefaultHome(int userId) {
|
||||
|
||||
// Set VERIFY to true to run the cache in "shadow" mode for cache
|
||||
// testing. Do not commit set to true;
|
||||
final boolean VERIFY = false;
|
||||
|
||||
if (mCachedDefaultHome != null) {
|
||||
if (!VERIFY) {
|
||||
return mCachedDefaultHome;
|
||||
}
|
||||
}
|
||||
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
final List<ResolveInfo> allHomeCandidates = new ArrayList<>();
|
||||
@@ -490,10 +510,12 @@ public class SliceManagerService extends ISliceManager.Stub {
|
||||
final ComponentName defaultLauncher = mPackageManagerInternal
|
||||
.getHomeActivitiesAsUser(allHomeCandidates, userId);
|
||||
|
||||
ComponentName detected = null;
|
||||
if (defaultLauncher != null) {
|
||||
detected = defaultLauncher;
|
||||
}
|
||||
ComponentName detected = defaultLauncher;
|
||||
|
||||
// Cache the default launcher. It is not a problem if the
|
||||
// launcher is null - eventually, the default launcher will be
|
||||
// set to something non-null.
|
||||
mCachedDefaultHome = ((detected != null) ? detected.getPackageName() : null);
|
||||
|
||||
if (detected == null) {
|
||||
// If we reach here, that means it's the first check since the user was created,
|
||||
@@ -517,12 +539,54 @@ public class SliceManagerService extends ISliceManager.Stub {
|
||||
lastPriority = ri.priority;
|
||||
}
|
||||
}
|
||||
return detected != null ? detected.getPackageName() : null;
|
||||
final String ret = ((detected != null) ? detected.getPackageName() : null);
|
||||
if (VERIFY) {
|
||||
if (mCachedDefaultHome != null && !mCachedDefaultHome.equals(ret)) {
|
||||
Slog.e(TAG, "getDefaultHome() cache failure, is " +
|
||||
mCachedDefaultHome + " should be " + ret);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
public void invalidateCachedDefaultHome() {
|
||||
mCachedDefaultHome = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for changes in the roles, and invalidate the cached default
|
||||
* home as necessary.
|
||||
*/
|
||||
private RoleObserver mRoleObserver;
|
||||
|
||||
class RoleObserver implements OnRoleHoldersChangedListener {
|
||||
private RoleManager mRm;
|
||||
private final Executor mExecutor;
|
||||
|
||||
RoleObserver() {
|
||||
mExecutor = mContext.getMainExecutor();
|
||||
register();
|
||||
}
|
||||
|
||||
public void register() {
|
||||
mRm = mContext.getSystemService(RoleManager.class);
|
||||
if (mRm != null) {
|
||||
mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL);
|
||||
invalidateCachedDefaultHome();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
|
||||
if (RoleManager.ROLE_HOME.equals(roleName)) {
|
||||
invalidateCachedDefaultHome();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isGrantedFullAccess(String pkg, int userId) {
|
||||
return mPermissions.hasFullAccess(pkg, userId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user