Merge "OMS: Setup state for users on boot and when added" into oc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
47fe4a0bef
@@ -19,6 +19,7 @@ package android.os;
|
||||
import android.Manifest;
|
||||
import android.accounts.AccountManager;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemApi;
|
||||
@@ -2129,7 +2130,7 @@ public class UserManager {
|
||||
* @return the list of users that were created.
|
||||
* @hide
|
||||
*/
|
||||
public List<UserInfo> getUsers(boolean excludeDying) {
|
||||
public @NonNull List<UserInfo> getUsers(boolean excludeDying) {
|
||||
try {
|
||||
return mService.getUsers(excludeDying);
|
||||
} catch (RemoteException re) {
|
||||
|
||||
@@ -20,6 +20,7 @@ import static android.app.AppGlobals.getPackageManager;
|
||||
import static android.content.Intent.ACTION_PACKAGE_ADDED;
|
||||
import static android.content.Intent.ACTION_PACKAGE_CHANGED;
|
||||
import static android.content.Intent.ACTION_PACKAGE_REMOVED;
|
||||
import static android.content.Intent.ACTION_USER_ADDED;
|
||||
import static android.content.Intent.ACTION_USER_REMOVED;
|
||||
import static android.content.pm.PackageManager.SIGNATURE_MATCH;
|
||||
|
||||
@@ -46,6 +47,7 @@ import android.os.ResultReceiver;
|
||||
import android.os.ShellCallback;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
@@ -243,11 +245,14 @@ public final class OverlayManagerService extends SystemService {
|
||||
packageFilter, null, null);
|
||||
|
||||
final IntentFilter userFilter = new IntentFilter();
|
||||
userFilter.addAction(ACTION_USER_ADDED);
|
||||
userFilter.addAction(ACTION_USER_REMOVED);
|
||||
getContext().registerReceiverAsUser(new UserReceiver(), UserHandle.ALL,
|
||||
userFilter, null, null);
|
||||
|
||||
restoreSettings();
|
||||
|
||||
initIfNeeded();
|
||||
onSwitchUser(UserHandle.USER_SYSTEM);
|
||||
|
||||
publishBinderService(Context.OVERLAY_SERVICE, mService);
|
||||
@@ -269,14 +274,31 @@ public final class OverlayManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private void initIfNeeded() {
|
||||
final UserManager um = getContext().getSystemService(UserManager.class);
|
||||
final List<UserInfo> users = um.getUsers(true /*excludeDying*/);
|
||||
synchronized (mLock) {
|
||||
final int userCount = users.size();
|
||||
for (int i = 0; i < userCount; i++) {
|
||||
final UserInfo userInfo = users.get(i);
|
||||
if (!userInfo.supportsSwitchTo() && userInfo.id != UserHandle.USER_SYSTEM) {
|
||||
// Initialize any users that can't be switched to, as there state would
|
||||
// never be setup in onSwitchUser(). We will switch to the system user right
|
||||
// after this, and its state will be setup there.
|
||||
final List<String> targets = mImpl.updateOverlaysForUser(users.get(i).id);
|
||||
updateOverlayPaths(users.get(i).id, targets);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwitchUser(final int newUserId) {
|
||||
// ensure overlays in the settings are up-to-date, and propagate
|
||||
// any asset changes to the rest of the system
|
||||
final List<String> targets;
|
||||
synchronized (mLock) {
|
||||
targets = mImpl.onSwitchUser(newUserId);
|
||||
updateAssetsLocked(newUserId, targets);
|
||||
final List<String> targets = mImpl.updateOverlaysForUser(newUserId);
|
||||
updateAssets(newUserId, targets);
|
||||
}
|
||||
schedulePersistSettings();
|
||||
}
|
||||
@@ -428,10 +450,19 @@ public final class OverlayManagerService extends SystemService {
|
||||
private final class UserReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(@NonNull final Context context, @NonNull final Intent intent) {
|
||||
final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
|
||||
switch (intent.getAction()) {
|
||||
case ACTION_USER_ADDED:
|
||||
if (userId != UserHandle.USER_NULL) {
|
||||
final ArrayList<String> targets;
|
||||
synchronized (mLock) {
|
||||
targets = mImpl.updateOverlaysForUser(userId);
|
||||
}
|
||||
updateOverlayPaths(userId, targets);
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTION_USER_REMOVED:
|
||||
final int userId =
|
||||
intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
|
||||
if (userId != UserHandle.USER_NULL) {
|
||||
synchronized (mLock) {
|
||||
mImpl.onUserRemoved(userId);
|
||||
@@ -647,9 +678,7 @@ public final class OverlayManagerService extends SystemService {
|
||||
public void onOverlaysChanged(@NonNull final String targetPackageName, final int userId) {
|
||||
schedulePersistSettings();
|
||||
FgThread.getHandler().post(() -> {
|
||||
synchronized (mLock) {
|
||||
updateAssetsLocked(userId, targetPackageName);
|
||||
}
|
||||
updateAssets(userId, targetPackageName);
|
||||
|
||||
final Intent intent = new Intent(Intent.ACTION_OVERLAY_CHANGED,
|
||||
Uri.fromParts("package", targetPackageName, null));
|
||||
@@ -670,13 +699,10 @@ public final class OverlayManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAssetsLocked(final int userId, final String targetPackageName) {
|
||||
final List<String> list = new ArrayList<>();
|
||||
list.add(targetPackageName);
|
||||
updateAssetsLocked(userId, list);
|
||||
}
|
||||
|
||||
private void updateAssetsLocked(final int userId, List<String> targetPackageNames) {
|
||||
/**
|
||||
* Updates the target packages' set of enabled overlays in PackageManager.
|
||||
*/
|
||||
private void updateOverlayPaths(int userId, List<String> targetPackageNames) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Updating overlay assets");
|
||||
}
|
||||
@@ -706,12 +732,19 @@ public final class OverlayManagerService extends SystemService {
|
||||
}
|
||||
|
||||
if (!pm.setEnabledOverlayPackages(
|
||||
userId, targetPackageName, pendingChanges.get(targetPackageName))) {
|
||||
userId, targetPackageName, pendingChanges.get(targetPackageName))) {
|
||||
Slog.e(TAG, String.format("Failed to change enabled overlays for %s user %d",
|
||||
targetPackageName, userId));
|
||||
targetPackageName, userId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAssets(final int userId, final String targetPackageName) {
|
||||
updateAssets(userId, Collections.singletonList(targetPackageName));
|
||||
}
|
||||
|
||||
private void updateAssets(final int userId, List<String> targetPackageNames) {
|
||||
updateOverlayPaths(userId, targetPackageNames);
|
||||
final IActivityManager am = ActivityManager.getService();
|
||||
try {
|
||||
am.scheduleApplicationInfoChanged(targetPackageNames, userId);
|
||||
|
||||
@@ -68,15 +68,15 @@ final class OverlayManagerServiceImpl {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call this when switching to a new Android user. Will return a list of
|
||||
* target packages that must refresh their overlays. This list is the union
|
||||
/**
|
||||
* Call this to synchronize the Settings for a user with what PackageManager knows about a user.
|
||||
* Returns a list of target packages that must refresh their overlays. This list is the union
|
||||
* of two sets: the set of targets with currently active overlays, and the
|
||||
* set of targets that had, but no longer have, active overlays.
|
||||
*/
|
||||
List<String> onSwitchUser(final int newUserId) {
|
||||
ArrayList<String> updateOverlaysForUser(final int newUserId) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onSwitchUser newUserId=" + newUserId);
|
||||
Slog.d(TAG, "updateOverlaysForUser newUserId=" + newUserId);
|
||||
}
|
||||
|
||||
final Set<String> packagesToUpdateAssets = new ArraySet<>();
|
||||
|
||||
@@ -22,12 +22,14 @@ import static com.android.server.om.OverlayManagerService.TAG;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.om.OverlayInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.util.AndroidRuntimeException;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Slog;
|
||||
import android.util.Xml;
|
||||
|
||||
import com.android.internal.util.FastXmlSerializer;
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
import com.android.internal.util.XmlUtils;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
@@ -266,32 +268,32 @@ final class OverlayManagerSettings {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final String TAB1 = " ";
|
||||
private static final String TAB2 = TAB1 + TAB1;
|
||||
private static final String TAB3 = TAB2 + TAB1;
|
||||
|
||||
void dump(@NonNull final PrintWriter pw) {
|
||||
void dump(@NonNull final PrintWriter p) {
|
||||
final IndentingPrintWriter pw = new IndentingPrintWriter(p, " ");
|
||||
pw.println("Settings");
|
||||
pw.println(TAB1 + "Items");
|
||||
pw.increaseIndent();
|
||||
|
||||
if (mItems.isEmpty()) {
|
||||
pw.println(TAB2 + "<none>");
|
||||
pw.println("<none>");
|
||||
return;
|
||||
}
|
||||
|
||||
final int N = mItems.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
final SettingsItem item = mItems.get(i);
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(TAB2 + item.mPackageName + ":" + item.getUserId() + " {\n");
|
||||
sb.append(TAB3 + "mPackageName.......: " + item.mPackageName + "\n");
|
||||
sb.append(TAB3 + "mUserId............: " + item.getUserId() + "\n");
|
||||
sb.append(TAB3 + "mTargetPackageName.: " + item.getTargetPackageName() + "\n");
|
||||
sb.append(TAB3 + "mBaseCodePath......: " + item.getBaseCodePath() + "\n");
|
||||
sb.append(TAB3 + "mState.............: " + OverlayInfo.stateToString(item.getState()) + "\n");
|
||||
sb.append(TAB3 + "mIsEnabled.........: " + item.isEnabled() + "\n");
|
||||
sb.append(TAB2 + "}");
|
||||
pw.println(sb.toString());
|
||||
pw.println(item.mPackageName + ":" + item.getUserId() + " {");
|
||||
pw.increaseIndent();
|
||||
|
||||
pw.print("mPackageName.......: "); pw.println(item.mPackageName);
|
||||
pw.print("mUserId............: "); pw.println(item.getUserId());
|
||||
pw.print("mTargetPackageName.: "); pw.println(item.getTargetPackageName());
|
||||
pw.print("mBaseCodePath......: "); pw.println(item.getBaseCodePath());
|
||||
pw.print("mState.............: "); pw.println(OverlayInfo.stateToString(item.getState()));
|
||||
pw.print("mIsEnabled.........: "); pw.println(item.isEnabled());
|
||||
pw.print("mIsStatic..........: "); pw.println(item.isStatic());
|
||||
|
||||
pw.decreaseIndent();
|
||||
pw.println("}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,12 +529,6 @@ final class OverlayManagerSettings {
|
||||
.filter(item -> item.getTargetPackageName().equals(targetPackageName));
|
||||
}
|
||||
|
||||
private void assertNotNull(@Nullable final Object o) {
|
||||
if (o == null) {
|
||||
throw new AndroidRuntimeException("object must not be null");
|
||||
}
|
||||
}
|
||||
|
||||
static final class BadKeyException extends RuntimeException {
|
||||
BadKeyException(@NonNull final String packageName, final int userId) {
|
||||
super("Bad key mPackageName=" + packageName + " mUserId=" + userId);
|
||||
|
||||
Reference in New Issue
Block a user