summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSvetoslav <svetoslavganov@google.com>2014-08-21 14:22:53 -0700
committerSvetoslav <svetoslavganov@google.com>2014-08-26 18:19:13 -0700
commit86b1df234397802895771fe14cd8f2813fa43415 (patch)
tree62152dc66e9c90420240b17d851e0a202751a1b1
parent105f6ceb0f123d365e1ff5837f0442b3e377a056 (diff)
downloadframeworks_base-86b1df234397802895771fe14cd8f2813fa43415.zip
frameworks_base-86b1df234397802895771fe14cd8f2813fa43415.tar.gz
frameworks_base-86b1df234397802895771fe14cd8f2813fa43415.tar.bz2
Print services setting changes not handled for managed profiles.
We keep per user settings for enabled print services which are observed to update the print manager service state. We were listening to all user changes but the handling code was not updating the state of the user whose settings changed, rather the current user. Added hidden APIs in content observer to know which user changed and now the print manager serivce handles content changes for the correct user. bug:16977006 Change-Id: I71ec88c8f3f38cb405844c13ab83695c2029eb79
-rw-r--r--core/java/android/database/ContentObserver.java48
-rw-r--r--core/java/android/database/CursorToBulkCursorAdaptor.java10
-rw-r--r--core/java/android/database/IContentObserver.aidl18
-rw-r--r--services/core/java/com/android/server/content/ContentService.java2
-rw-r--r--services/print/java/com/android/server/print/PrintManagerService.java161
5 files changed, 114 insertions, 125 deletions
diff --git a/core/java/android/database/ContentObserver.java b/core/java/android/database/ContentObserver.java
index e4fbc28..5f01e30 100644
--- a/core/java/android/database/ContentObserver.java
+++ b/core/java/android/database/ContentObserver.java
@@ -18,6 +18,7 @@ package android.database;
import android.net.Uri;
import android.os.Handler;
+import android.os.UserHandle;
/**
* Receives call backs for changes to content.
@@ -130,6 +131,21 @@ public abstract class ContentObserver {
}
/**
+ * Dispatches a change notification to the observer. Includes the changed
+ * content Uri when available and also the user whose content changed.
+ *
+ * @param selfChange True if this is a self-change notification.
+ * @param uri The Uri of the changed content, or null if unknown.
+ * @param userId The user whose content changed. Can be either a specific
+ * user or {@link UserHandle#USER_ALL}.
+ *
+ * @hide
+ */
+ public void onChange(boolean selfChange, Uri uri, int userId) {
+ onChange(selfChange, uri);
+ }
+
+ /**
* Dispatches a change notification to the observer.
* <p>
* If a {@link Handler} was supplied to the {@link ContentObserver} constructor,
@@ -159,25 +175,45 @@ public abstract class ContentObserver {
* @param uri The Uri of the changed content, or null if unknown.
*/
public final void dispatchChange(boolean selfChange, Uri uri) {
+ dispatchChange(selfChange, uri, UserHandle.getCallingUserId());
+ }
+
+ /**
+ * Dispatches a change notification to the observer. Includes the changed
+ * content Uri when available and also the user whose content changed.
+ * <p>
+ * If a {@link Handler} was supplied to the {@link ContentObserver} constructor,
+ * then a call to the {@link #onChange} method is posted to the handler's message queue.
+ * Otherwise, the {@link #onChange} method is invoked immediately on this thread.
+ * </p>
+ *
+ * @param selfChange True if this is a self-change notification.
+ * @param uri The Uri of the changed content, or null if unknown.
+ * @param userId The user whose content changed.
+ */
+ private void dispatchChange(boolean selfChange, Uri uri, int userId) {
if (mHandler == null) {
- onChange(selfChange, uri);
+ onChange(selfChange, uri, userId);
} else {
- mHandler.post(new NotificationRunnable(selfChange, uri));
+ mHandler.post(new NotificationRunnable(selfChange, uri, userId));
}
}
+
private final class NotificationRunnable implements Runnable {
private final boolean mSelfChange;
private final Uri mUri;
+ private final int mUserId;
- public NotificationRunnable(boolean selfChange, Uri uri) {
+ public NotificationRunnable(boolean selfChange, Uri uri, int userId) {
mSelfChange = selfChange;
mUri = uri;
+ mUserId = userId;
}
@Override
public void run() {
- ContentObserver.this.onChange(mSelfChange, mUri);
+ ContentObserver.this.onChange(mSelfChange, mUri, mUserId);
}
}
@@ -189,10 +225,10 @@ public abstract class ContentObserver {
}
@Override
- public void onChange(boolean selfChange, Uri uri) {
+ public void onChange(boolean selfChange, Uri uri, int userId) {
ContentObserver contentObserver = mContentObserver;
if (contentObserver != null) {
- contentObserver.dispatchChange(selfChange, uri);
+ contentObserver.dispatchChange(selfChange, uri, userId);
}
}
diff --git a/core/java/android/database/CursorToBulkCursorAdaptor.java b/core/java/android/database/CursorToBulkCursorAdaptor.java
index 7dcfae2..02eddf2 100644
--- a/core/java/android/database/CursorToBulkCursorAdaptor.java
+++ b/core/java/android/database/CursorToBulkCursorAdaptor.java
@@ -17,9 +17,7 @@
package android.database;
import android.net.Uri;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
+import android.os.*;
/**
@@ -33,7 +31,7 @@ import android.os.RemoteException;
*
* {@hide}
*/
-public final class CursorToBulkCursorAdaptor extends BulkCursorNative
+public final class CursorToBulkCursorAdaptor extends BulkCursorNative
implements IBinder.DeathRecipient {
private static final String TAG = "Cursor";
@@ -66,7 +64,7 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative
// Do nothing, the far side is dead
}
}
-
+
public boolean unlinkToDeath(DeathRecipient recipient) {
return mRemote.asBinder().unlinkToDeath(recipient, 0);
}
@@ -80,7 +78,7 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative
@Override
public void onChange(boolean selfChange, Uri uri) {
try {
- mRemote.onChange(selfChange, uri);
+ mRemote.onChange(selfChange, uri, android.os.Process.myUid());
} catch (RemoteException ex) {
// Do nothing, the far side is dead
}
diff --git a/core/java/android/database/IContentObserver.aidl b/core/java/android/database/IContentObserver.aidl
index 13aff05..22dc9fe 100644
--- a/core/java/android/database/IContentObserver.aidl
+++ b/core/java/android/database/IContentObserver.aidl
@@ -2,16 +2,16 @@
**
** Copyright 2007, The Android Open Source Project
**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License
+** You may obtain a copy of the License at
**
-** http://www.apache.org/licenses/LICENSE-2.0
+** http://www.apache.org/licenses/LICENSE-2.0
**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
** limitations under the License.
*/
@@ -29,5 +29,5 @@ interface IContentObserver
* observed. selfUpdate is true if the update was caused by a call to
* commit on the cursor that is being observed.
*/
- oneway void onChange(boolean selfUpdate, in Uri uri);
+ oneway void onChange(boolean selfUpdate, in Uri uri, int userId);
}
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 64d3dc5..165148b 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -255,7 +255,7 @@ public final class ContentService extends IContentService.Stub {
for (int i=0; i<numCalls; i++) {
ObserverCall oc = calls.get(i);
try {
- oc.mObserver.onChange(oc.mSelfChange, uri);
+ oc.mObserver.onChange(oc.mSelfChange, uri, userHandle);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Notified " + oc.mObserver + " of " + "update at " + uri);
}
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index 6a56de0..ce91f3d 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -17,14 +17,14 @@
package com.android.server.print;
import android.Manifest;
+import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
@@ -81,10 +81,13 @@ public final class PrintManagerService extends SystemService {
}
@Override
- public void onBootPhase(int phase) {
- if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
- mPrintManagerImpl.systemRunning();
- }
+ public void onStartUser(int userHandle) {
+ mPrintManagerImpl.handleUserStarted(userHandle);
+ }
+
+ @Override
+ public void onStopUser(int userHandle) {
+ mPrintManagerImpl.handleUserStopped(userHandle);
}
class PrintManagerImpl extends IPrintManager.Stub {
@@ -101,9 +104,7 @@ public final class PrintManagerService extends SystemService {
private final UserManager mUserManager;
- private final SparseArray<UserState> mUserStates = new SparseArray<UserState>();
-
- private int mCurrentUserId = UserHandle.USER_OWNER;
+ private final SparseArray<UserState> mUserStates = new SparseArray<>();
PrintManagerImpl(Context context) {
mContext = context;
@@ -112,22 +113,6 @@ public final class PrintManagerService extends SystemService {
registerBroadcastReceivers();
}
- public void systemRunning() {
- BackgroundThread.getHandler().post(new Runnable() {
- @Override
- public void run() {
- final UserState userState;
- synchronized (mLock) {
- userState = getCurrentUserStateLocked();
- }
- // This is the first time we switch to this user after boot, so
- // now is the time to remove obsolete print jobs since they
- // are from the last boot and no application would query them.
- userState.removeObsoletePrintJobs();
- }
- });
- }
-
@Override
public Bundle print(String printJobName, IPrintDocumentAdapter adapter,
PrintAttributes attributes, String packageName, int appId, int userId) {
@@ -137,7 +122,7 @@ public final class PrintManagerService extends SystemService {
final String resolvedPackageName;
synchronized (mLock) {
// Only the current group members can start new print jobs.
- if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return null;
}
resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
@@ -160,7 +145,7 @@ public final class PrintManagerService extends SystemService {
final UserState userState;
synchronized (mLock) {
// Only the current group members can query for state of print jobs.
- if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return null;
}
resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
@@ -181,7 +166,7 @@ public final class PrintManagerService extends SystemService {
final UserState userState;
synchronized (mLock) {
// Only the current group members can query for state of a print job.
- if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return null;
}
resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
@@ -202,7 +187,7 @@ public final class PrintManagerService extends SystemService {
final UserState userState;
synchronized (mLock) {
// Only the current group members can cancel a print job.
- if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
@@ -223,7 +208,7 @@ public final class PrintManagerService extends SystemService {
final UserState userState;
synchronized (mLock) {
// Only the current group members can restart a print job.
- if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
@@ -243,7 +228,7 @@ public final class PrintManagerService extends SystemService {
final UserState userState;
synchronized (mLock) {
// Only the current group members can get enabled services.
- if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return null;
}
userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -262,7 +247,7 @@ public final class PrintManagerService extends SystemService {
final UserState userState;
synchronized (mLock) {
// Only the current group members can get installed services.
- if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return null;
}
userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -282,7 +267,7 @@ public final class PrintManagerService extends SystemService {
final UserState userState;
synchronized (mLock) {
// Only the current group members can create a discovery session.
- if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -302,7 +287,7 @@ public final class PrintManagerService extends SystemService {
final UserState userState;
synchronized (mLock) {
// Only the current group members can destroy a discovery session.
- if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -322,7 +307,7 @@ public final class PrintManagerService extends SystemService {
final UserState userState;
synchronized (mLock) {
// Only the current group members can start discovery.
- if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -341,7 +326,7 @@ public final class PrintManagerService extends SystemService {
final UserState userState;
synchronized (mLock) {
// Only the current group members can stop discovery.
- if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -360,7 +345,7 @@ public final class PrintManagerService extends SystemService {
final UserState userState;
synchronized (mLock) {
// Only the current group members can validate printers.
- if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -379,7 +364,7 @@ public final class PrintManagerService extends SystemService {
final UserState userState;
synchronized (mLock) {
// Only the current group members can start printer tracking.
- if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -398,7 +383,7 @@ public final class PrintManagerService extends SystemService {
final UserState userState;
synchronized (mLock) {
// Only the current group members can stop printer tracking.
- if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -419,7 +404,7 @@ public final class PrintManagerService extends SystemService {
final UserState userState;
synchronized (mLock) {
// Only the current group members can add a print job listener.
- if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
@@ -440,7 +425,7 @@ public final class PrintManagerService extends SystemService {
final UserState userState;
synchronized (mLock) {
// Only the current group members can remove a print job listener.
- if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) {
return;
}
userState = getOrCreateUserStateLocked(resolvedUserId);
@@ -484,11 +469,19 @@ public final class PrintManagerService extends SystemService {
Settings.Secure.ENABLED_PRINT_SERVICES);
ContentObserver observer = new ContentObserver(BackgroundThread.getHandler()) {
@Override
- public void onChange(boolean selfChange, Uri uri) {
+ public void onChange(boolean selfChange, Uri uri, int userId) {
if (enabledPrintServicesUri.equals(uri)) {
synchronized (mLock) {
- UserState userState = getCurrentUserStateLocked();
- userState.updateIfNeededLocked();
+ 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();
+ }
+ }
}
}
}
@@ -622,27 +615,6 @@ public final class PrintManagerService extends SystemService {
// package changes
monitor.register(mContext, BackgroundThread.getHandler().getLooper(),
UserHandle.ALL, true);
-
- // user changes
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
- intentFilter.addAction(Intent.ACTION_USER_REMOVED);
-
- mContext.registerReceiverAsUser(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (Intent.ACTION_USER_SWITCHED.equals(action)) {
- switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
- } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
- removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
- }
- }
- }, UserHandle.ALL, intentFilter, null, BackgroundThread.getHandler());
- }
-
- private UserState getCurrentUserStateLocked() {
- return getOrCreateUserStateLocked(mCurrentUserId);
}
private UserState getOrCreateUserStateLocked(int userId) {
@@ -654,20 +626,11 @@ public final class PrintManagerService extends SystemService {
return userState;
}
- private void switchUser(int newUserId) {
+ private void handleUserStarted(int userId) {
UserState userState;
synchronized (mLock) {
- if (newUserId == mCurrentUserId) {
- return;
- }
- mCurrentUserId = newUserId;
- userState = mUserStates.get(mCurrentUserId);
- if (userState == null) {
- userState = getCurrentUserStateLocked();
- userState.updateIfNeededLocked();
- } else {
- userState.updateIfNeededLocked();
- }
+ userState = getOrCreateUserStateLocked(userId);
+ userState.updateIfNeededLocked();
}
// This is the first time we switch to this user after boot, so
// now is the time to remove obsolete print jobs since they
@@ -675,18 +638,18 @@ public final class PrintManagerService extends SystemService {
userState.removeObsoletePrintJobs();
}
- private void removeUser(int removedUserId) {
+ private void handleUserStopped(int userId) {
synchronized (mLock) {
- UserState userState = mUserStates.get(removedUserId);
+ UserState userState = mUserStates.get(userId);
if (userState != null) {
userState.destroyLocked();
- mUserStates.remove(removedUserId);
+ mUserStates.remove(userId);
}
}
}
private int resolveCallingProfileParentLocked(int userId) {
- if (userId != mCurrentUserId) {
+ if (userId != getCurrentUserId()) {
final long identity = Binder.clearCallingIdentity();
try {
UserInfo parent = mUserManager.getProfileParent(userId);
@@ -723,28 +686,11 @@ public final class PrintManagerService extends SystemService {
}
private int resolveCallingUserEnforcingPermissions(int userId) {
- final int callingUid = Binder.getCallingUid();
- if (callingUid == 0 || callingUid == Process.SYSTEM_UID
- || callingUid == Process.SHELL_UID) {
- return userId;
- }
- final int callingUserId = UserHandle.getUserId(callingUid);
- if (callingUserId == userId) {
- return userId;
- }
- if (mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)
- != PackageManager.PERMISSION_GRANTED
- && mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS)
- != PackageManager.PERMISSION_GRANTED) {
- if (userId == UserHandle.USER_CURRENT_OR_SELF) {
- return callingUserId;
- }
- throw new SecurityException("Call from user " + callingUserId + " as user "
- + userId + " without permission INTERACT_ACROSS_USERS or "
- + "INTERACT_ACROSS_USERS_FULL not allowed.");
- }
- if (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) {
- return mCurrentUserId;
+ try {
+ return ActivityManagerNative.getDefault().handleIncomingUser(Binder.getCallingPid(),
+ Binder.getCallingUid(), userId, true, true, "", null);
+ } catch (RemoteException re) {
+ // Shouldn't happen, local.
}
return userId;
}
@@ -764,6 +710,15 @@ public final class PrintManagerService extends SystemService {
return null;
}
+ private int getCurrentUserId () {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return ActivityManager.getCurrentUser();
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
private void showEnableInstalledPrintServiceNotification(ComponentName component,
String label, int userId) {
UserHandle userHandle = new UserHandle(userId);