Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c72fc674 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Implement multi-user PackageMonitor.

New APIs let you indicate what user(s) to monitor, and tell you
what user is changing when receiving a callback.

Fix package manager to only deliver package brpadcasts to the
running users.  (This isn't really a change in behavior, since
the activity manager would not deliver to stopped users anyway).
Make sure all broadcasts that package monitor receives also include
user information for it to use.

Update wallpaper service to (hopefully) now Really Correctly
monitor package changes per user.

Change-Id: Idd952dd274abcaeab452277d9160d1ae62919aa0
parent 4046e012
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -1611,6 +1611,14 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            return true;
        }

        case GET_RUNNING_USER_IDS_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            int[] result = getRunningUserIds();
            reply.writeNoException();
            reply.writeIntArray(result);
            return true;
        }

        case REMOVE_SUB_TASK_TRANSACTION:
        {
            data.enforceInterface(IActivityManager.descriptor);
@@ -3846,6 +3854,18 @@ class ActivityManagerProxy implements IActivityManager
        return result;
    }

    public int[] getRunningUserIds() throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        mRemote.transact(GET_RUNNING_USER_IDS_TRANSACTION, data, reply, 0);
        reply.readException();
        int[] result = reply.createIntArray();
        reply.recycle();
        data.recycle();
        return result;
    }

    public boolean removeSubTask(int taskId, int subTaskIndex) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
+2 −0
Original line number Diff line number Diff line
@@ -327,6 +327,7 @@ public interface IActivityManager extends IInterface {
    public int stopUser(int userid, IStopUserCallback callback) throws RemoteException;
    public UserInfo getCurrentUser() throws RemoteException;
    public boolean isUserRunning(int userid) throws RemoteException;
    public int[] getRunningUserIds() throws RemoteException;

    public boolean removeSubTask(int taskId, int subTaskIndex) throws RemoteException;

@@ -611,4 +612,5 @@ public interface IActivityManager extends IInterface {
    int STOP_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+153;
    int REGISTER_USER_SWITCH_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+154;
    int UNREGISTER_USER_SWITCH_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+155;
    int GET_RUNNING_USER_IDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+156;
}
+9 −0
Original line number Diff line number Diff line
@@ -2796,6 +2796,15 @@ public class Intent implements Parcelable, Cloneable {
     */
    public static final String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED";

    /**
     * @hide
     * Used as a boolean extra field in {@link android.content.Intent#ACTION_PACKAGE_REMOVED}
     * intents to indicate that at this point the package has been removed for
     * all users on the device.
     */
    public static final String EXTRA_REMOVED_FOR_ALL_USERS
            = "android.intent.extra.REMOVED_FOR_ALL_USERS";

    /**
     * Used as a boolean extra field in {@link android.content.Intent#ACTION_PACKAGE_REMOVED}
     * intents to indicate that this is a replacement of the package, so this
+44 −7
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.UserHandle;

import java.util.HashSet;

@@ -62,11 +63,17 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver {
    String[] mAppearingPackages;
    String[] mModifiedPackages;
    int mChangeType;
    int mChangeUserId = UserHandle.USER_NULL;
    boolean mSomePackagesChanged;

    String[] mTempArray = new String[1];

    public void register(Context context, Looper thread, boolean externalStorage) {
        register(context, thread, null, externalStorage);
    }

    public void register(Context context, Looper thread, UserHandle user,
            boolean externalStorage) {
        if (mRegisteredContext != null) {
            throw new IllegalStateException("Already registered");
        }
@@ -84,12 +91,21 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver {
        } else {
            mRegisteredHandler = new Handler(thread);
        }
        if (user != null) {
            context.registerReceiverAsUser(this, user, sPackageFilt, null, mRegisteredHandler);
            context.registerReceiverAsUser(this, user, sNonDataFilt, null, mRegisteredHandler);
            if (externalStorage) {
                context.registerReceiverAsUser(this, user, sExternalFilt, null,
                        mRegisteredHandler);
            }
        } else {
            context.registerReceiver(this, sPackageFilt, null, mRegisteredHandler);
            context.registerReceiver(this, sNonDataFilt, null, mRegisteredHandler);
            if (externalStorage) {
                context.registerReceiver(this, sExternalFilt, null, mRegisteredHandler);
            }
        }
    }

    public Handler getRegisteredHandler() {
        return mRegisteredHandler;
@@ -125,6 +141,13 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver {
    public void onPackageRemoved(String packageName, int uid) {
    }

    /**
     * Called when a package is really removed (and not replaced) for
     * all users on the device.
     */
    public void onPackageRemovedAllUsers(String packageName, int uid) {
    }

    public void onPackageUpdateStarted(String packageName, int uid) {
    }

@@ -221,6 +244,10 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver {
    public void onFinishPackageChanges() {
    }

    public int getChangingUserId() {
        return mChangeUserId;
    }

    String getPackageName(Intent intent) {
        Uri uri = intent.getData();
        String pkg = uri != null ? uri.getSchemeSpecificPart() : null;
@@ -229,6 +256,12 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver {
    
    @Override
    public void onReceive(Context context, Intent intent) {
        mChangeUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
                UserHandle.USER_NULL);
        if (mChangeUserId == UserHandle.USER_NULL) {
            throw new IllegalArgumentException(
                    "Intent broadcast does not contain user handle: " + intent);
        }
        onBeginPackageChanges();
        
        mDisappearingPackages = mAppearingPackages = null;
@@ -281,6 +314,9 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver {
                    // it when it is re-added.
                    mSomePackagesChanged = true;
                    onPackageRemoved(pkg, uid);
                    if (intent.getBooleanExtra(Intent.EXTRA_REMOVED_FOR_ALL_USERS, false)) {
                        onPackageRemovedAllUsers(pkg, uid);
                    }
                }
                onPackageDisappeared(pkg, mChangeType);
            }
@@ -344,5 +380,6 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver {
        }
        
        onFinishPackageChanges();
        mChangeUserId = UserHandle.USER_NULL;
    }
}
+29 −16
Original line number Diff line number Diff line
@@ -293,16 +293,17 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
        @Override
        public void onPackageUpdateFinished(String packageName, int uid) {
            synchronized (mLock) {
                for (int i = 0; i < mWallpaperMap.size(); i++) {
                    WallpaperData wallpaper = mWallpaperMap.valueAt(i);
                if (mCurrentUserId != getChangingUserId()) {
                    return;
                }
                WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
                if (wallpaper != null) {
                    if (wallpaper.wallpaperComponent != null
                            && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
                        wallpaper.wallpaperUpdating = false;
                        ComponentName comp = wallpaper.wallpaperComponent;
                        clearWallpaperComponentLocked(wallpaper);
                        // Do this only for the current user's wallpaper
                        if (wallpaper.userId == mCurrentUserId
                                && !bindWallpaperComponentLocked(comp, false, false,
                        if (!bindWallpaperComponentLocked(comp, false, false,
                                wallpaper, null)) {
                            Slog.w(TAG, "Wallpaper no longer available; reverting to default");
                            clearWallpaperLocked(false, wallpaper.userId, null);
@@ -315,11 +316,14 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
        @Override
        public void onPackageModified(String packageName) {
            synchronized (mLock) {
                for (int i = 0; i < mWallpaperMap.size(); i++) {
                    WallpaperData wallpaper = mWallpaperMap.valueAt(i);
                if (mCurrentUserId != getChangingUserId()) {
                    return;
                }
                WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
                if (wallpaper != null) {
                    if (wallpaper.wallpaperComponent == null
                            || !wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
                        continue;
                        return;
                    }
                    doPackagesChangedLocked(true, wallpaper);
                }
@@ -329,8 +333,11 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
        @Override
        public void onPackageUpdateStarted(String packageName, int uid) {
            synchronized (mLock) {
                for (int i = 0; i < mWallpaperMap.size(); i++) {
                    WallpaperData wallpaper = mWallpaperMap.valueAt(i);
                if (mCurrentUserId != getChangingUserId()) {
                    return;
                }
                WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
                if (wallpaper != null) {
                    if (wallpaper.wallpaperComponent != null
                            && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
                        wallpaper.wallpaperUpdating = true;
@@ -343,8 +350,11 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
            synchronized (mLock) {
                boolean changed = false;
                for (int i = 0; i < mWallpaperMap.size(); i++) {
                    WallpaperData wallpaper = mWallpaperMap.valueAt(i);
                if (mCurrentUserId != getChangingUserId()) {
                    return false;
                }
                WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
                if (wallpaper != null) {
                    boolean res = doPackagesChangedLocked(doit, wallpaper);
                    changed |= res;
                }
@@ -355,8 +365,11 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
        @Override
        public void onSomePackagesChanged() {
            synchronized (mLock) {
                for (int i = 0; i < mWallpaperMap.size(); i++) {
                    WallpaperData wallpaper = mWallpaperMap.valueAt(i);
                if (mCurrentUserId != getChangingUserId()) {
                    return;
                }
                WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
                if (wallpaper != null) {
                    doPackagesChangedLocked(true, wallpaper);
                }
            }
@@ -416,7 +429,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
                ServiceManager.getService(Context.WINDOW_SERVICE));
        mIPackageManager = AppGlobals.getPackageManager();
        mMonitor = new MyPackageMonitor();
        mMonitor.register(context, null, true);
        mMonitor.register(context, null, UserHandle.ALL, true);
        getWallpaperDir(UserHandle.USER_OWNER).mkdirs();
        loadSettingsLocked(UserHandle.USER_OWNER);
    }
Loading