From 0999c0d6e9c83873d9595ee764b6388dbc49dcb8 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Thu, 17 Dec 2015 15:12:22 -0700 Subject: [PATCH] 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 --- core/java/android/os/UserManager.java | 9 ++++-- .../appwidget/AppWidgetServiceImpl.java | 17 +++-------- .../server/print/PrintManagerService.java | 29 ++++++++++++------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index c5adafe9d16db..ddd16e21b066f 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -852,9 +852,14 @@ public class UserManager { * @param user to retrieve the unlocked state for. */ public boolean isUserUnlocked(UserHandle user) { + return isUserUnlocked(user.getIdentifier()); + } + + /** {@hide} */ + public boolean isUserUnlocked(int userId) { try { - return ActivityManagerNative.getDefault().isUserRunning( - user.getIdentifier(), ActivityManager.FLAG_AND_UNLOCKED); + return ActivityManagerNative.getDefault().isUserRunning(userId, + ActivityManager.FLAG_AND_UNLOCKED); } catch (RemoteException e) { return false; } diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index 946b2339db4b1..6f8f8eba75f42 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -336,7 +336,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } private void onPackageBroadcastReceived(Intent intent, int userId) { - if (!isUserRunningAndUnlocked(userId)) return; + if (!mUserManager.isUserUnlocked(userId)) return; final String action = intent.getAction(); 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. */ private void refreshProfileWidgetsMaskedState(int userId) { - if (!isUserRunningAndUnlocked(userId)) return; + if (!mUserManager.isUserUnlocked(userId)) return; List profiles = mUserManager.getEnabledProfiles(userId); if (profiles != null) { 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. */ private void refreshWidgetMaskedState(int profileId) { - if (!isUserRunningAndUnlocked(profileId)) return; + if (!mUserManager.isUserUnlocked(profileId)) return; final long identity = Binder.clearCallingIdentity(); try { UserInfo user = mUserManager.getUserInfo(profileId); @@ -481,7 +481,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } private void ensureGroupStateLoadedLocked(int userId) { - if (!isUserRunningAndUnlocked(userId)) { + if (!mUserManager.isUserUnlocked(userId)) { throw new IllegalStateException( "User " + userId + " must be unlocked for widgets to be available"); } @@ -2512,15 +2512,6 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku mWidgetPackages.clear(); } - private boolean isUserRunningAndUnlocked(int userId) { - if (userId == UserHandle.USER_NULL) { - return false; - } else { - return mContext.getSystemService(ActivityManager.class) - .isUserRunningAndUnlocked(userId); - } - } - @Override public boolean isBoundWidgetPackage(String packageName, int userId) { if (Binder.getCallingUid() != Process.SYSTEM_UID) { diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java index 0a8c014c4d37d..f18617ef47488 100644 --- a/services/print/java/com/android/server/print/PrintManagerService.java +++ b/services/print/java/com/android/server/print/PrintManagerService.java @@ -77,8 +77,8 @@ public final class PrintManagerService extends SystemService { } @Override - public void onStartUser(int userHandle) { - mPrintManagerImpl.handleUserStarted(userHandle); + public void onUnlockUser(int userHandle) { + mPrintManagerImpl.handleUserUnlocked(userHandle); } @Override @@ -473,14 +473,11 @@ public final class PrintManagerService extends SystemService { public void onChange(boolean selfChange, Uri uri, int userId) { if (enabledPrintServicesUri.equals(uri)) { synchronized (mLock) { - if (userId != UserHandle.USER_ALL) { - UserState userState = getOrCreateUserStateLocked(userId); - userState.updateIfNeededLocked(); - } else { - final int userCount = mUserStates.size(); - for (int i = 0; i < userCount; i++) { - UserState userState = mUserStates.valueAt(i); - userState.updateIfNeededLocked(); + final int userCount = mUserStates.size(); + for (int i = 0; i < userCount; i++) { + if (userId == UserHandle.USER_ALL + || userId == mUserStates.keyAt(i)) { + mUserStates.valueAt(i).updateIfNeededLocked(); } } } @@ -496,6 +493,7 @@ public final class PrintManagerService extends SystemService { PackageMonitor monitor = new PackageMonitor() { @Override public void onPackageModified(String packageName) { + if (!mUserManager.isUserUnlocked(getChangingUserId())) return; synchronized (mLock) { // 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 @@ -517,6 +515,7 @@ public final class PrintManagerService extends SystemService { @Override public void onPackageRemoved(String packageName, int uid) { + if (!mUserManager.isUserUnlocked(getChangingUserId())) return; synchronized (mLock) { // 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 @@ -544,6 +543,7 @@ public final class PrintManagerService extends SystemService { @Override public boolean onHandleForceStop(Intent intent, String[] stoppedPackages, int uid, boolean doit) { + if (!mUserManager.isUserUnlocked(getChangingUserId())) return false; synchronized (mLock) { // 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 @@ -574,6 +574,8 @@ public final class PrintManagerService extends SystemService { @Override public void onPackageAdded(String packageName, int uid) { + if (!mUserManager.isUserUnlocked(getChangingUserId())) return; + // 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 // 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) { + if (!mUserManager.isUserUnlocked(userId)) { + throw new IllegalStateException( + "User " + userId + " must be unlocked for printing to be available"); + } + UserState userState = mUserStates.get(userId); if (userState == null) { userState = new UserState(mContext, userId, mLock); @@ -642,7 +649,7 @@ public final class PrintManagerService extends SystemService { return userState; } - private void handleUserStarted(final int userId) { + private void handleUserUnlocked(final int userId) { // This code will touch the remote print spooler which // must be called off the main thread, so post the work. BackgroundThread.getHandler().post(new Runnable() {