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
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index c5adafe..ddd16e2 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -852,9 +852,14 @@
* @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 946b233..6f8f8eb 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 @@
}
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 @@
* 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<UserInfo> profiles = mUserManager.getEnabledProfiles(userId);
if (profiles != null) {
for (int i = 0; i < profiles.size(); i++) {
@@ -431,7 +431,7 @@
* 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 @@
}
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 @@
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 0a8c014..f18617e 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 @@
}
@Override
- public void onStartUser(int userHandle) {
- mPrintManagerImpl.handleUserStarted(userHandle);
+ public void onUnlockUser(int userHandle) {
+ mPrintManagerImpl.handleUserUnlocked(userHandle);
}
@Override
@@ -473,14 +473,11 @@
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 @@
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 @@
@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 @@
@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 @@
@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 @@
}
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 @@
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() {