summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSvetoslav <svetoslavganov@google.com>2014-05-08 12:48:23 -0700
committerSvetoslav Ganov <svetoslavganov@google.com>2014-05-13 21:21:36 +0000
commit04533dd3ba4e916f5a639d0cfbc331c32515cc84 (patch)
treeb5bcc6d2cb60ccc11a6a430ca243b2e05c57e76e
parentb09506dad997c3a652ae8b74a008451664ea7b54 (diff)
downloadframeworks_base-04533dd3ba4e916f5a639d0cfbc331c32515cc84.zip
frameworks_base-04533dd3ba4e916f5a639d0cfbc331c32515cc84.tar.gz
frameworks_base-04533dd3ba4e916f5a639d0cfbc331c32515cc84.tar.bz2
Teach print manager services about user profiles.
For user profiles the printing layer will have a separate state and set a set of print plugins. The rationale behind this is that if a user uses different profiles for different domains he would expect that each domain is separate as domains may have different security and privacy requirements. bug:14567366 Change-Id: I461ae4636294fa8968785295afb952aeb14a13b5
-rw-r--r--services/print/java/com/android/server/print/PrintManagerService.java125
1 files changed, 116 insertions, 9 deletions
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index f7bec6e..39f228f 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -28,6 +28,7 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Binder;
@@ -35,6 +36,7 @@ import android.os.Bundle;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.os.UserManager;
import android.print.IPrintDocumentAdapter;
import android.print.IPrintJobStateChangeListener;
import android.print.IPrintManager;
@@ -91,18 +93,23 @@ public final class PrintManagerService extends SystemService {
private static final String EXTRA_PRINT_SERVICE_COMPONENT_NAME =
"EXTRA_PRINT_SERVICE_COMPONENT_NAME";
+ private static final int BACKGROUND_USER_ID = -10;
+
private final Object mLock = new Object();
private final Context mContext;
+ private final UserManager mUserManager;
+
private final SparseArray<UserState> mUserStates = new SparseArray<UserState>();
private int mCurrentUserId = UserHandle.USER_OWNER;
PrintManagerImpl(Context context) {
mContext = context;
+ mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
registerContentObservers();
- registerBoradcastReceivers();
+ registerBroadcastReceivers();
}
public void systemRunning() {
@@ -125,11 +132,17 @@ public final class PrintManagerService extends SystemService {
@Override
public Bundle print(String printJobName, IPrintDocumentAdapter adapter,
PrintAttributes attributes, String packageName, int appId, int userId) {
- final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- String resolvedPackageName = resolveCallingPackageNameEnforcingSecurity(packageName);
+ final int resolvedAppId;
final UserState userState;
+ final String resolvedPackageName;
synchronized (mLock) {
+ // Only the current group members can start new print jobs.
+ if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ return null;
+ }
+ resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
+ resolvedPackageName = resolveCallingPackageNameEnforcingSecurity(packageName);
userState = getOrCreateUserStateLocked(resolvedUserId);
}
final long identity = Binder.clearCallingIdentity();
@@ -143,10 +156,15 @@ public final class PrintManagerService extends SystemService {
@Override
public List<PrintJobInfo> getPrintJobInfos(int appId, int userId) {
- final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final int resolvedAppId;
final UserState userState;
synchronized (mLock) {
+ // Only the current group members can query for state of print jobs.
+ if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ return null;
+ }
+ resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
userState = getOrCreateUserStateLocked(resolvedUserId);
}
final long identity = Binder.clearCallingIdentity();
@@ -159,10 +177,15 @@ public final class PrintManagerService extends SystemService {
@Override
public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId, int userId) {
- final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final int resolvedAppId;
final UserState userState;
synchronized (mLock) {
+ // Only the current group members can query for state of a print job.
+ if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ return null;
+ }
+ resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
userState = getOrCreateUserStateLocked(resolvedUserId);
}
final long identity = Binder.clearCallingIdentity();
@@ -175,10 +198,15 @@ public final class PrintManagerService extends SystemService {
@Override
public void cancelPrintJob(PrintJobId printJobId, int appId, int userId) {
- final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final int resolvedAppId;
final UserState userState;
synchronized (mLock) {
+ // Only the current group members can cancel a print job.
+ if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ return;
+ }
+ resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
userState = getOrCreateUserStateLocked(resolvedUserId);
}
final long identity = Binder.clearCallingIdentity();
@@ -191,10 +219,15 @@ public final class PrintManagerService extends SystemService {
@Override
public void restartPrintJob(PrintJobId printJobId, int appId, int userId) {
- final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+ final int resolvedAppId;
final UserState userState;
synchronized (mLock) {
+ // Only the current group members can restart a print job.
+ if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ return;
+ }
+ resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
userState = getOrCreateUserStateLocked(resolvedUserId);
}
final long identity = Binder.clearCallingIdentity();
@@ -210,6 +243,10 @@ public final class PrintManagerService extends SystemService {
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
final UserState userState;
synchronized (mLock) {
+ // Only the current group members can get enabled services.
+ if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ return null;
+ }
userState = getOrCreateUserStateLocked(resolvedUserId);
}
final long identity = Binder.clearCallingIdentity();
@@ -225,6 +262,10 @@ public final class PrintManagerService extends SystemService {
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
final UserState userState;
synchronized (mLock) {
+ // Only the current group members can get installed services.
+ if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ return null;
+ }
userState = getOrCreateUserStateLocked(resolvedUserId);
}
final long identity = Binder.clearCallingIdentity();
@@ -241,6 +282,10 @@ public final class PrintManagerService extends SystemService {
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
final UserState userState;
synchronized (mLock) {
+ // Only the current group members can create a discovery session.
+ if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ return;
+ }
userState = getOrCreateUserStateLocked(resolvedUserId);
}
final long identity = Binder.clearCallingIdentity();
@@ -257,6 +302,10 @@ public final class PrintManagerService extends SystemService {
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
final UserState userState;
synchronized (mLock) {
+ // Only the current group members can destroy a discovery session.
+ if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ return;
+ }
userState = getOrCreateUserStateLocked(resolvedUserId);
}
final long identity = Binder.clearCallingIdentity();
@@ -273,6 +322,10 @@ public final class PrintManagerService extends SystemService {
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
final UserState userState;
synchronized (mLock) {
+ // Only the current group members can start discovery.
+ if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ return;
+ }
userState = getOrCreateUserStateLocked(resolvedUserId);
}
final long identity = Binder.clearCallingIdentity();
@@ -288,6 +341,10 @@ public final class PrintManagerService extends SystemService {
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
final UserState userState;
synchronized (mLock) {
+ // Only the current group members can stop discovery.
+ if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ return;
+ }
userState = getOrCreateUserStateLocked(resolvedUserId);
}
final long identity = Binder.clearCallingIdentity();
@@ -303,6 +360,10 @@ public final class PrintManagerService extends SystemService {
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
final UserState userState;
synchronized (mLock) {
+ // Only the current group members can validate printers.
+ if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ return;
+ }
userState = getOrCreateUserStateLocked(resolvedUserId);
}
final long identity = Binder.clearCallingIdentity();
@@ -318,6 +379,10 @@ public final class PrintManagerService extends SystemService {
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
final UserState userState;
synchronized (mLock) {
+ // Only the current group members can start printer tracking.
+ if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ return;
+ }
userState = getOrCreateUserStateLocked(resolvedUserId);
}
final long identity = Binder.clearCallingIdentity();
@@ -333,6 +398,10 @@ public final class PrintManagerService extends SystemService {
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
final UserState userState;
synchronized (mLock) {
+ // Only the current group members can stop printer tracking.
+ if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ return;
+ }
userState = getOrCreateUserStateLocked(resolvedUserId);
}
final long identity = Binder.clearCallingIdentity();
@@ -347,9 +416,14 @@ public final class PrintManagerService extends SystemService {
public void addPrintJobStateChangeListener(IPrintJobStateChangeListener listener,
int appId, int userId) throws RemoteException {
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
- final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
+ final int resolvedAppId;
final UserState userState;
synchronized (mLock) {
+ // Only the current group members can add a print job listener.
+ if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ return;
+ }
+ resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
userState = getOrCreateUserStateLocked(resolvedUserId);
}
final long identity = Binder.clearCallingIdentity();
@@ -366,6 +440,10 @@ public final class PrintManagerService extends SystemService {
final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
final UserState userState;
synchronized (mLock) {
+ // Only the current group members can remove a print job listener.
+ if (resolveCallingProfileParentLocked(resolvedUserId) != mCurrentUserId) {
+ return;
+ }
userState = getOrCreateUserStateLocked(resolvedUserId);
}
final long identity = Binder.clearCallingIdentity();
@@ -421,11 +499,14 @@ public final class PrintManagerService extends SystemService {
false, observer, UserHandle.USER_ALL);
}
- private void registerBoradcastReceivers() {
+ private void registerBroadcastReceivers() {
PackageMonitor monitor = new PackageMonitor() {
@Override
public void onPackageModified(String packageName) {
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
+ // to handle it as the change may affect ongoing print jobs.
boolean servicesChanged = false;
UserState userState = getOrCreateUserStateLocked(getChangingUserId());
Iterator<ComponentName> iterator = userState.getEnabledServices().iterator();
@@ -444,6 +525,9 @@ public final class PrintManagerService extends SystemService {
@Override
public void onPackageRemoved(String packageName, int uid) {
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
+ // to handle it as the change may affect ongoing print jobs.
boolean servicesRemoved = false;
UserState userState = getOrCreateUserStateLocked(getChangingUserId());
Iterator<ComponentName> iterator = userState.getEnabledServices().iterator();
@@ -467,6 +551,9 @@ public final class PrintManagerService extends SystemService {
public boolean onHandleForceStop(Intent intent, String[] stoppedPackages,
int uid, boolean doit) {
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
+ // to handle it as the change may affect ongoing print jobs.
UserState userState = getOrCreateUserStateLocked(getChangingUserId());
boolean stoppedSomePackages = false;
Iterator<ComponentName> iterator = userState.getEnabledServices()
@@ -493,6 +580,9 @@ public final class PrintManagerService extends SystemService {
@Override
public void onPackageAdded(String packageName, int uid) {
+ // 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.
Intent intent = new Intent(android.printservice.PrintService.SERVICE_INTERFACE);
intent.setPackage(packageName);
@@ -596,6 +686,23 @@ public final class PrintManagerService extends SystemService {
}
}
+ private int resolveCallingProfileParentLocked(int userId) {
+ if (userId != mCurrentUserId) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ UserInfo parent = mUserManager.getProfileParent(userId);
+ if (parent != null) {
+ return parent.getUserHandle().getIdentifier();
+ } else {
+ return BACKGROUND_USER_ID;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ return userId;
+ }
+
private int resolveCallingAppEnforcingPermissions(int appId) {
final int callingUid = Binder.getCallingUid();
if (callingUid == 0 || callingUid == Process.SYSTEM_UID