Merge "OMS: Setup state for users on boot and when added" into oc-dev

This commit is contained in:
TreeHugger Robot
2017-05-13 00:35:39 +00:00
committed by Android (Google) Code Review
4 changed files with 76 additions and 46 deletions

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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<>();

View File

@@ -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);