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

Commit 0999c0d6 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Make printing framework encryption-aware.

Only create UserState objects when a user has been unlocked, meaning
we can connect to the spooler.  Ignore package events that occur
while a user is locked, since we'll kick off updateIfNeededLocked()
when that user is eventually unlocked.

In all other cases, throw if someone tries obtaining UserState for
a still-locked user.  This should help catch any edge cases in the
system, and communicate clearly through public APIs that printing
isn't available until the user is unlocked.

Bug: 26246836
Change-Id: If15744621890baee206d355484fe20933afc65d8
parent af6ec296
Loading
Loading
Loading
Loading
+7 −2
Original line number Original line Diff line number Diff line
@@ -852,9 +852,14 @@ public class UserManager {
     * @param user to retrieve the unlocked state for.
     * @param user to retrieve the unlocked state for.
     */
     */
    public boolean isUserUnlocked(UserHandle user) {
    public boolean isUserUnlocked(UserHandle user) {
        return isUserUnlocked(user.getIdentifier());
    }

    /** {@hide} */
    public boolean isUserUnlocked(int userId) {
        try {
        try {
            return ActivityManagerNative.getDefault().isUserRunning(
            return ActivityManagerNative.getDefault().isUserRunning(userId,
                    user.getIdentifier(), ActivityManager.FLAG_AND_UNLOCKED);
                    ActivityManager.FLAG_AND_UNLOCKED);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            return false;
            return false;
        }
        }
+4 −13
Original line number Original line Diff line number Diff line
@@ -336,7 +336,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
    }
    }


    private void onPackageBroadcastReceived(Intent intent, int userId) {
    private void onPackageBroadcastReceived(Intent intent, int userId) {
        if (!isUserRunningAndUnlocked(userId)) return;
        if (!mUserManager.isUserUnlocked(userId)) return;


        final String action = intent.getAction();
        final String action = intent.getAction();
        boolean added = false;
        boolean added = false;
@@ -417,7 +417,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
     * Refresh the masked state for all profiles under the given user.
     * Refresh the masked state for all profiles under the given user.
     */
     */
    private void refreshProfileWidgetsMaskedState(int userId) {
    private void refreshProfileWidgetsMaskedState(int userId) {
        if (!isUserRunningAndUnlocked(userId)) return;
        if (!mUserManager.isUserUnlocked(userId)) return;
        List<UserInfo> profiles = mUserManager.getEnabledProfiles(userId);
        List<UserInfo> profiles = mUserManager.getEnabledProfiles(userId);
        if (profiles != null) {
        if (profiles != null) {
            for (int i = 0; i < profiles.size(); i++) {
            for (int i = 0; i < profiles.size(); i++) {
@@ -431,7 +431,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
     * Mask/unmask widgets in the given profile, depending on the quiet state of the profile.
     * Mask/unmask widgets in the given profile, depending on the quiet state of the profile.
     */
     */
    private void refreshWidgetMaskedState(int profileId) {
    private void refreshWidgetMaskedState(int profileId) {
        if (!isUserRunningAndUnlocked(profileId)) return;
        if (!mUserManager.isUserUnlocked(profileId)) return;
        final long identity = Binder.clearCallingIdentity();
        final long identity = Binder.clearCallingIdentity();
        try {
        try {
            UserInfo user  = mUserManager.getUserInfo(profileId);
            UserInfo user  = mUserManager.getUserInfo(profileId);
@@ -481,7 +481,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
    }
    }


    private void ensureGroupStateLoadedLocked(int userId) {
    private void ensureGroupStateLoadedLocked(int userId) {
        if (!isUserRunningAndUnlocked(userId)) {
        if (!mUserManager.isUserUnlocked(userId)) {
            throw new IllegalStateException(
            throw new IllegalStateException(
                    "User " + userId + " must be unlocked for widgets to be available");
                    "User " + userId + " must be unlocked for widgets to be available");
        }
        }
@@ -2512,15 +2512,6 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        mWidgetPackages.clear();
        mWidgetPackages.clear();
    }
    }


    private boolean isUserRunningAndUnlocked(int userId) {
        if (userId == UserHandle.USER_NULL) {
            return false;
        } else {
            return mContext.getSystemService(ActivityManager.class)
                    .isUserRunningAndUnlocked(userId);
        }
    }

    @Override
    @Override
    public boolean isBoundWidgetPackage(String packageName, int userId) {
    public boolean isBoundWidgetPackage(String packageName, int userId) {
        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+18 −11
Original line number Original line Diff line number Diff line
@@ -77,8 +77,8 @@ public final class PrintManagerService extends SystemService {
    }
    }


    @Override
    @Override
    public void onStartUser(int userHandle) {
    public void onUnlockUser(int userHandle) {
        mPrintManagerImpl.handleUserStarted(userHandle);
        mPrintManagerImpl.handleUserUnlocked(userHandle);
    }
    }


    @Override
    @Override
@@ -473,14 +473,11 @@ public final class PrintManagerService extends SystemService {
                public void onChange(boolean selfChange, Uri uri, int userId) {
                public void onChange(boolean selfChange, Uri uri, int userId) {
                    if (enabledPrintServicesUri.equals(uri)) {
                    if (enabledPrintServicesUri.equals(uri)) {
                        synchronized (mLock) {
                        synchronized (mLock) {
                            if (userId != UserHandle.USER_ALL) {
                                UserState userState = getOrCreateUserStateLocked(userId);
                                userState.updateIfNeededLocked();
                            } else {
                            final int userCount = mUserStates.size();
                            final int userCount = mUserStates.size();
                            for (int i = 0; i < userCount; i++) {
                            for (int i = 0; i < userCount; i++) {
                                    UserState userState = mUserStates.valueAt(i);
                                if (userId == UserHandle.USER_ALL
                                    userState.updateIfNeededLocked();
                                        || userId == mUserStates.keyAt(i)) {
                                    mUserStates.valueAt(i).updateIfNeededLocked();
                                }
                                }
                            }
                            }
                        }
                        }
@@ -496,6 +493,7 @@ public final class PrintManagerService extends SystemService {
            PackageMonitor monitor = new PackageMonitor() {
            PackageMonitor monitor = new PackageMonitor() {
                @Override
                @Override
                public void onPackageModified(String packageName) {
                public void onPackageModified(String packageName) {
                    if (!mUserManager.isUserUnlocked(getChangingUserId())) return;
                    synchronized (mLock) {
                    synchronized (mLock) {
                        // A background user/profile's print jobs are running but there is
                        // A background user/profile's print jobs are running but there is
                        // no UI shown. Hence, if the packages of such a user change we need
                        // no UI shown. Hence, if the packages of such a user change we need
@@ -517,6 +515,7 @@ public final class PrintManagerService extends SystemService {


                @Override
                @Override
                public void onPackageRemoved(String packageName, int uid) {
                public void onPackageRemoved(String packageName, int uid) {
                    if (!mUserManager.isUserUnlocked(getChangingUserId())) return;
                    synchronized (mLock) {
                    synchronized (mLock) {
                        // A background user/profile's print jobs are running but there is
                        // A background user/profile's print jobs are running but there is
                        // no UI shown. Hence, if the packages of such a user change we need
                        // no UI shown. Hence, if the packages of such a user change we need
@@ -544,6 +543,7 @@ public final class PrintManagerService extends SystemService {
                @Override
                @Override
                public boolean onHandleForceStop(Intent intent, String[] stoppedPackages,
                public boolean onHandleForceStop(Intent intent, String[] stoppedPackages,
                        int uid, boolean doit) {
                        int uid, boolean doit) {
                    if (!mUserManager.isUserUnlocked(getChangingUserId())) return false;
                    synchronized (mLock) {
                    synchronized (mLock) {
                        // A background user/profile's print jobs are running but there is
                        // A background user/profile's print jobs are running but there is
                        // no UI shown. Hence, if the packages of such a user change we need
                        // no UI shown. Hence, if the packages of such a user change we need
@@ -574,6 +574,8 @@ public final class PrintManagerService extends SystemService {


                @Override
                @Override
                public void onPackageAdded(String packageName, int uid) {
                public void onPackageAdded(String packageName, int uid) {
                    if (!mUserManager.isUserUnlocked(getChangingUserId())) return;

                    // A background user/profile's print jobs are running but there is
                    // A background user/profile's print jobs are running but there is
                    // no UI shown. Hence, if the packages of such a user change we need
                    // no UI shown. Hence, if the packages of such a user change we need
                    // to handle it as the change may affect ongoing print jobs.
                    // to handle it as the change may affect ongoing print jobs.
@@ -634,6 +636,11 @@ public final class PrintManagerService extends SystemService {
        }
        }


        private UserState getOrCreateUserStateLocked(int userId) {
        private UserState getOrCreateUserStateLocked(int userId) {
            if (!mUserManager.isUserUnlocked(userId)) {
                throw new IllegalStateException(
                        "User " + userId + " must be unlocked for printing to be available");
            }

            UserState userState = mUserStates.get(userId);
            UserState userState = mUserStates.get(userId);
            if (userState == null) {
            if (userState == null) {
                userState = new UserState(mContext, userId, mLock);
                userState = new UserState(mContext, userId, mLock);
@@ -642,7 +649,7 @@ public final class PrintManagerService extends SystemService {
            return userState;
            return userState;
        }
        }


        private void handleUserStarted(final int userId) {
        private void handleUserUnlocked(final int userId) {
            // This code will touch the remote print spooler which
            // This code will touch the remote print spooler which
            // must be called off the main thread, so post the work.
            // must be called off the main thread, so post the work.
            BackgroundThread.getHandler().post(new Runnable() {
            BackgroundThread.getHandler().post(new Runnable() {