14b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov/* 24b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Copyright (C) 2013 The Android Open Source Project 34b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * 44b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License"); 54b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * you may not use this file except in compliance with the License. 64b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * You may obtain a copy of the License at 74b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * 84b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * http://www.apache.org/licenses/LICENSE-2.0 94b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * 104b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * Unless required by applicable law or agreed to in writing, software 114b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS, 124b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * See the License for the specific language governing permissions and 144b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov * limitations under the License. 154b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov */ 164b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 174b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovpackage com.android.server.print; 184b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 194b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.Manifest; 2086b1df234397802895771fe14cd8f2813fa43415Svetoslavimport android.app.ActivityManager; 2186b1df234397802895771fe14cd8f2813fa43415Svetoslavimport android.app.ActivityManagerNative; 22d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslavimport android.app.Notification; 23d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslavimport android.app.NotificationManager; 24d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslavimport android.app.PendingIntent; 254b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.content.ComponentName; 264b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.content.Context; 274b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.content.Intent; 284b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.content.pm.PackageManager; 2907ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guyimport android.content.pm.PackageManager.NameNotFoundException; 30d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslavimport android.content.pm.ResolveInfo; 31d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslavimport android.content.pm.ServiceInfo; 3204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslavimport android.content.pm.UserInfo; 334b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.database.ContentObserver; 344b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.net.Uri; 354b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.Binder; 367bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslavimport android.os.Bundle; 374b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.Process; 38704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganovimport android.os.RemoteException; 394b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.os.UserHandle; 4004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslavimport android.os.UserManager; 41a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.print.IPrintDocumentAdapter; 42704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganovimport android.print.IPrintJobStateChangeListener; 434b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.print.IPrintManager; 4444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.print.IPrinterDiscoveryObserver; 454b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.print.PrintAttributes; 462fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslavimport android.print.PrintJobId; 474b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.print.PrintJobInfo; 4844720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganovimport android.print.PrinterId; 49860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganovimport android.printservice.PrintServiceInfo; 504b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport android.provider.Settings; 517bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslavimport android.text.TextUtils; 52a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport android.util.SparseArray; 534b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 54d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslavimport com.android.internal.R; 554b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport com.android.internal.content.PackageMonitor; 56a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganovimport com.android.internal.os.BackgroundThread; 57817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasaniimport com.android.server.SystemService; 584b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 59b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganovimport java.io.FileDescriptor; 60b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganovimport java.io.PrintWriter; 614b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.util.Iterator; 624b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.util.List; 634b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganovimport java.util.Set; 644b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 65817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani/** 66817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani * SystemService wrapper for the PrintManager implementation. Publishes 67817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani * Context.PRINT_SERVICE. 68817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani * PrintManager implementation is contained within. 69817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani */ 704b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 71817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasanipublic final class PrintManagerService extends SystemService { 72b880d880c6cd989eacc28c365fc9a41d31900da1Jeff Brown private final PrintManagerImpl mPrintManagerImpl; 734b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 74b880d880c6cd989eacc28c365fc9a41d31900da1Jeff Brown public PrintManagerService(Context context) { 75b880d880c6cd989eacc28c365fc9a41d31900da1Jeff Brown super(context); 76817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani mPrintManagerImpl = new PrintManagerImpl(context); 774b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 78b880d880c6cd989eacc28c365fc9a41d31900da1Jeff Brown 794b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 80817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public void onStart() { 81817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani publishBinderService(Context.PRINT_SERVICE, mPrintManagerImpl); 824b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 834b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 844b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov @Override 8586b1df234397802895771fe14cd8f2813fa43415Svetoslav public void onStartUser(int userHandle) { 8686b1df234397802895771fe14cd8f2813fa43415Svetoslav mPrintManagerImpl.handleUserStarted(userHandle); 8786b1df234397802895771fe14cd8f2813fa43415Svetoslav } 8886b1df234397802895771fe14cd8f2813fa43415Svetoslav 8986b1df234397802895771fe14cd8f2813fa43415Svetoslav @Override 9086b1df234397802895771fe14cd8f2813fa43415Svetoslav public void onStopUser(int userHandle) { 9186b1df234397802895771fe14cd8f2813fa43415Svetoslav mPrintManagerImpl.handleUserStopped(userHandle); 924b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 934b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 94817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani class PrintManagerImpl extends IPrintManager.Stub { 95817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani private static final char COMPONENT_NAME_SEPARATOR = ':'; 968c43376ea83a67414bd6823a472b76d41160239eSvetoslav Ganov 97817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani private static final String EXTRA_PRINT_SERVICE_COMPONENT_NAME = 98817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani "EXTRA_PRINT_SERVICE_COMPONENT_NAME"; 994b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 10004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav private static final int BACKGROUND_USER_ID = -10; 10104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav 102817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani private final Object mLock = new Object(); 103860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov 104817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani private final Context mContext; 105d8dbc13b47bec3248a86a505a30af9d0474240dcSvetoslav 10604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav private final UserManager mUserManager; 10704533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav 10886b1df234397802895771fe14cd8f2813fa43415Svetoslav private final SparseArray<UserState> mUserStates = new SparseArray<>(); 109817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani 110817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani PrintManagerImpl(Context context) { 111817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani mContext = context; 11204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 113817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani registerContentObservers(); 11404533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav registerBroadcastReceivers(); 11544720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 11644720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 117817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 118817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public Bundle print(String printJobName, IPrintDocumentAdapter adapter, 119817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani PrintAttributes attributes, String packageName, int appId, int userId) { 120817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 12104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav final int resolvedAppId; 122817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final UserState userState; 12304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav final String resolvedPackageName; 124817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 12504533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // Only the current group members can start new print jobs. 12686b1df234397802895771fe14cd8f2813fa43415Svetoslav if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 12704533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return null; 12804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 12904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav resolvedAppId = resolveCallingAppEnforcingPermissions(appId); 13004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav resolvedPackageName = resolveCallingPackageNameEnforcingSecurity(packageName); 131817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = getOrCreateUserStateLocked(resolvedUserId); 132817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 133817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final long identity = Binder.clearCallingIdentity(); 134817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani try { 135817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani return userState.print(printJobName, adapter, attributes, 136817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani resolvedPackageName, resolvedAppId); 137817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } finally { 138817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.restoreCallingIdentity(identity); 139817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 14044720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 141817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani 142817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 143817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public List<PrintJobInfo> getPrintJobInfos(int appId, int userId) { 144817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 14504533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav final int resolvedAppId; 146817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final UserState userState; 147817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 14804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // Only the current group members can query for state of print jobs. 14986b1df234397802895771fe14cd8f2813fa43415Svetoslav if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 15004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return null; 15104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 15204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav resolvedAppId = resolveCallingAppEnforcingPermissions(appId); 153817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = getOrCreateUserStateLocked(resolvedUserId); 154817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 155817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final long identity = Binder.clearCallingIdentity(); 156817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani try { 157817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani return userState.getPrintJobInfos(resolvedAppId); 158817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } finally { 159817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.restoreCallingIdentity(identity); 160817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 16144720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 16244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 163817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 164817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId, int userId) { 165817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 16604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav final int resolvedAppId; 167817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final UserState userState; 168817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 16904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // Only the current group members can query for state of a print job. 17086b1df234397802895771fe14cd8f2813fa43415Svetoslav if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 17104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return null; 17204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 17304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav resolvedAppId = resolveCallingAppEnforcingPermissions(appId); 174817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = getOrCreateUserStateLocked(resolvedUserId); 175817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 176817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final long identity = Binder.clearCallingIdentity(); 177817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani try { 178817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani return userState.getPrintJobInfo(printJobId, resolvedAppId); 179817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } finally { 180817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.restoreCallingIdentity(identity); 181817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 18244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 183817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani 184817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 185817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public void cancelPrintJob(PrintJobId printJobId, int appId, int userId) { 186817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 18704533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav final int resolvedAppId; 188817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final UserState userState; 189817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 19004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // Only the current group members can cancel a print job. 19186b1df234397802895771fe14cd8f2813fa43415Svetoslav if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 19204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return; 19304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 19404533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav resolvedAppId = resolveCallingAppEnforcingPermissions(appId); 195817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = getOrCreateUserStateLocked(resolvedUserId); 196817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 197817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final long identity = Binder.clearCallingIdentity(); 198817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani try { 199817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState.cancelPrintJob(printJobId, resolvedAppId); 200817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } finally { 201817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.restoreCallingIdentity(identity); 202817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 20344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 20444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 205817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 206817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public void restartPrintJob(PrintJobId printJobId, int appId, int userId) { 207817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 20804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav final int resolvedAppId; 209817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final UserState userState; 210817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 21104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // Only the current group members can restart a print job. 21286b1df234397802895771fe14cd8f2813fa43415Svetoslav if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 21304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return; 21404533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 21504533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav resolvedAppId = resolveCallingAppEnforcingPermissions(appId); 216817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = getOrCreateUserStateLocked(resolvedUserId); 217817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 218817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final long identity = Binder.clearCallingIdentity(); 219817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani try { 220817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState.restartPrintJob(printJobId, resolvedAppId); 221817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } finally { 222817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.restoreCallingIdentity(identity); 223817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 22444720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 225817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani 226817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 227817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public List<PrintServiceInfo> getEnabledPrintServices(int userId) { 228817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 229817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final UserState userState; 230817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 23104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // Only the current group members can get enabled services. 23286b1df234397802895771fe14cd8f2813fa43415Svetoslav if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 23304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return null; 23404533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 235817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = getOrCreateUserStateLocked(resolvedUserId); 236817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 237817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final long identity = Binder.clearCallingIdentity(); 238817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani try { 239817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani return userState.getEnabledPrintServices(); 240817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } finally { 241817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.restoreCallingIdentity(identity); 242817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 243d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 244d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 245817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 246817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public List<PrintServiceInfo> getInstalledPrintServices(int userId) { 247817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 248817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final UserState userState; 249817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 25004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // Only the current group members can get installed services. 25186b1df234397802895771fe14cd8f2813fa43415Svetoslav if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 25204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return null; 25304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 254817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = getOrCreateUserStateLocked(resolvedUserId); 255817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 256817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final long identity = Binder.clearCallingIdentity(); 257817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani try { 258817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani return userState.getInstalledPrintServices(); 259817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } finally { 260817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.restoreCallingIdentity(identity); 261817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 262d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 263817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani 264817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 265817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer, 266817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani int userId) { 267817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 268817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final UserState userState; 269817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 27004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // Only the current group members can create a discovery session. 27186b1df234397802895771fe14cd8f2813fa43415Svetoslav if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 27204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return; 27304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 274817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = getOrCreateUserStateLocked(resolvedUserId); 275817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 276817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final long identity = Binder.clearCallingIdentity(); 277817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani try { 278817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState.createPrinterDiscoverySession(observer); 279817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } finally { 280817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.restoreCallingIdentity(identity); 281817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 282d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 283d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov 284817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 285817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public void destroyPrinterDiscoverySession(IPrinterDiscoveryObserver observer, 286817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani int userId) { 287817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 288817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final UserState userState; 289817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 29004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // Only the current group members can destroy a discovery session. 29186b1df234397802895771fe14cd8f2813fa43415Svetoslav if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 29204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return; 29304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 294817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = getOrCreateUserStateLocked(resolvedUserId); 295817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 296817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final long identity = Binder.clearCallingIdentity(); 297817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani try { 298817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState.destroyPrinterDiscoverySession(observer); 299817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } finally { 300817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.restoreCallingIdentity(identity); 301817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 302d26d4898fcc9b78f4b66118895c375384098205eSvetoslav Ganov } 303817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani 304817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 305817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public void startPrinterDiscovery(IPrinterDiscoveryObserver observer, 306817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani List<PrinterId> priorityList, int userId) { 307817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 308817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final UserState userState; 309817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 31004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // Only the current group members can start discovery. 31186b1df234397802895771fe14cd8f2813fa43415Svetoslav if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 31204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return; 31304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 314817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = getOrCreateUserStateLocked(resolvedUserId); 315817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 316817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final long identity = Binder.clearCallingIdentity(); 317817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani try { 318817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState.startPrinterDiscovery(observer, priorityList); 319817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } finally { 320817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.restoreCallingIdentity(identity); 321817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 32244720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov } 32344720af55a8fdf991929983dad5d53c02851dd1eSvetoslav Ganov 324817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 325817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public void stopPrinterDiscovery(IPrinterDiscoveryObserver observer, int userId) { 326817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 327817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final UserState userState; 328817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 32904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // Only the current group members can stop discovery. 33086b1df234397802895771fe14cd8f2813fa43415Svetoslav if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 33104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return; 33204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 333817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = getOrCreateUserStateLocked(resolvedUserId); 334817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 335817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final long identity = Binder.clearCallingIdentity(); 336817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani try { 337817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState.stopPrinterDiscovery(observer); 338817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } finally { 339817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.restoreCallingIdentity(identity); 340817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 341704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 342817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani 343817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 344817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public void validatePrinters(List<PrinterId> printerIds, int userId) { 345817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 346817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final UserState userState; 347817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 34804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // Only the current group members can validate printers. 34986b1df234397802895771fe14cd8f2813fa43415Svetoslav if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 35004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return; 35104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 352817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = getOrCreateUserStateLocked(resolvedUserId); 353817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 354817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final long identity = Binder.clearCallingIdentity(); 355817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani try { 356817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState.validatePrinters(printerIds); 357817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } finally { 358817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.restoreCallingIdentity(identity); 359817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 360704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 361704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 362817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 363817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public void startPrinterStateTracking(PrinterId printerId, int userId) { 364817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 365817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final UserState userState; 366817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 36704533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // Only the current group members can start printer tracking. 36886b1df234397802895771fe14cd8f2813fa43415Svetoslav if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 36904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return; 37004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 371817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = getOrCreateUserStateLocked(resolvedUserId); 372817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 373817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final long identity = Binder.clearCallingIdentity(); 374817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani try { 375817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState.startPrinterStateTracking(printerId); 376817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } finally { 377817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.restoreCallingIdentity(identity); 378817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 379704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 380817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani 381817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 382817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public void stopPrinterStateTracking(PrinterId printerId, int userId) { 383817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 384817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final UserState userState; 385817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 38604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // Only the current group members can stop printer tracking. 38786b1df234397802895771fe14cd8f2813fa43415Svetoslav if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 38804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return; 38904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 390817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = getOrCreateUserStateLocked(resolvedUserId); 391817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 392817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final long identity = Binder.clearCallingIdentity(); 393817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani try { 394817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState.stopPrinterStateTracking(printerId); 395817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } finally { 396817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.restoreCallingIdentity(identity); 397817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 398704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov } 399704697b6197262678e930daa831a1916ddee4dcfSvetoslav Ganov 400817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 401817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public void addPrintJobStateChangeListener(IPrintJobStateChangeListener listener, 402817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani int appId, int userId) throws RemoteException { 403817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 40404533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav final int resolvedAppId; 405817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final UserState userState; 406817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 40704533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // Only the current group members can add a print job listener. 40886b1df234397802895771fe14cd8f2813fa43415Svetoslav if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 40904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return; 41004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 41104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav resolvedAppId = resolveCallingAppEnforcingPermissions(appId); 412817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = getOrCreateUserStateLocked(resolvedUserId); 413817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 414817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final long identity = Binder.clearCallingIdentity(); 415817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani try { 416817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState.addPrintJobStateChangeListener(listener, resolvedAppId); 417817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } finally { 418817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.restoreCallingIdentity(identity); 419817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 420b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 421b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 422817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 423817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public void removePrintJobStateChangeListener(IPrintJobStateChangeListener listener, 424817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani int userId) { 425817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 426817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final UserState userState; 427817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 42804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // Only the current group members can remove a print job listener. 42986b1df234397802895771fe14cd8f2813fa43415Svetoslav if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 43004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return; 43104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 432817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = getOrCreateUserStateLocked(resolvedUserId); 433817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 4345fe07aa7a81c840eaf52bf95d4d5bacd914a8106Svetoslav final long identity = Binder.clearCallingIdentity(); 4355fe07aa7a81c840eaf52bf95d4d5bacd914a8106Svetoslav try { 436817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState.removePrintJobStateChangeListener(listener); 4375fe07aa7a81c840eaf52bf95d4d5bacd914a8106Svetoslav } finally { 4385fe07aa7a81c840eaf52bf95d4d5bacd914a8106Svetoslav Binder.restoreCallingIdentity(identity); 439b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 440b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov } 441b669917825a49421ee79be4819ead765f5de8aaeSvetoslav Ganov 442817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 443817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 444817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP) 445817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani != PackageManager.PERMISSION_GRANTED) { 446817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani pw.println("Permission Denial: can't dump PrintManager from from pid=" 447817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani + Binder.getCallingPid() 448817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani + ", uid=" + Binder.getCallingUid()); 449817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani return; 450817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 4514b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 452817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 453817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final long identity = Binder.clearCallingIdentity(); 454817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani try { 455817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani pw.println("PRINT MANAGER STATE (dumpsys print)"); 456817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int userStateCount = mUserStates.size(); 457817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani for (int i = 0; i < userStateCount; i++) { 458817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani UserState userState = mUserStates.valueAt(i); 459817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState.dump(fd, pw, ""); 460817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani pw.println(); 4614b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 462817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } finally { 463817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.restoreCallingIdentity(identity); 4644b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 4654b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 466817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 4674b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 468817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani private void registerContentObservers() { 469817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final Uri enabledPrintServicesUri = Settings.Secure.getUriFor( 470817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Settings.Secure.ENABLED_PRINT_SERVICES); 471817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani ContentObserver observer = new ContentObserver(BackgroundThread.getHandler()) { 472817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 47386b1df234397802895771fe14cd8f2813fa43415Svetoslav public void onChange(boolean selfChange, Uri uri, int userId) { 474817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani if (enabledPrintServicesUri.equals(uri)) { 475817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 47686b1df234397802895771fe14cd8f2813fa43415Svetoslav if (userId != UserHandle.USER_ALL) { 47786b1df234397802895771fe14cd8f2813fa43415Svetoslav UserState userState = getOrCreateUserStateLocked(userId); 47886b1df234397802895771fe14cd8f2813fa43415Svetoslav userState.updateIfNeededLocked(); 47986b1df234397802895771fe14cd8f2813fa43415Svetoslav } else { 48086b1df234397802895771fe14cd8f2813fa43415Svetoslav final int userCount = mUserStates.size(); 48186b1df234397802895771fe14cd8f2813fa43415Svetoslav for (int i = 0; i < userCount; i++) { 48286b1df234397802895771fe14cd8f2813fa43415Svetoslav UserState userState = mUserStates.valueAt(i); 48386b1df234397802895771fe14cd8f2813fa43415Svetoslav userState.updateIfNeededLocked(); 48486b1df234397802895771fe14cd8f2813fa43415Svetoslav } 48586b1df234397802895771fe14cd8f2813fa43415Svetoslav } 486a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 4874b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 4884b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 489817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani }; 4904b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 491817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani mContext.getContentResolver().registerContentObserver(enabledPrintServicesUri, 492817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani false, observer, UserHandle.USER_ALL); 493817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 494817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani 49504533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav private void registerBroadcastReceivers() { 496817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani PackageMonitor monitor = new PackageMonitor() { 497817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 498e58a49e411327e26b6ad9939833f53c7fa5aef20Amith Yamasani public void onPackageModified(String packageName) { 499817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 50004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // A background user/profile's print jobs are running but there is 50104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // no UI shown. Hence, if the packages of such a user change we need 50204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // to handle it as the change may affect ongoing print jobs. 503e58a49e411327e26b6ad9939833f53c7fa5aef20Amith Yamasani boolean servicesChanged = false; 504817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani UserState userState = getOrCreateUserStateLocked(getChangingUserId()); 505e58a49e411327e26b6ad9939833f53c7fa5aef20Amith Yamasani Iterator<ComponentName> iterator = userState.getEnabledServices().iterator(); 506817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani while (iterator.hasNext()) { 507817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani ComponentName componentName = iterator.next(); 508817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani if (packageName.equals(componentName.getPackageName())) { 509e58a49e411327e26b6ad9939833f53c7fa5aef20Amith Yamasani servicesChanged = true; 510817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 5114b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 512e58a49e411327e26b6ad9939833f53c7fa5aef20Amith Yamasani if (servicesChanged) { 513e58a49e411327e26b6ad9939833f53c7fa5aef20Amith Yamasani userState.updateIfNeededLocked(); 5144b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 5154b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 5164b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 5174b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 518817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 519817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public void onPackageRemoved(String packageName, int uid) { 520817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 52104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // A background user/profile's print jobs are running but there is 52204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // no UI shown. Hence, if the packages of such a user change we need 52304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // to handle it as the change may affect ongoing print jobs. 524e58a49e411327e26b6ad9939833f53c7fa5aef20Amith Yamasani boolean servicesRemoved = false; 525817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani UserState userState = getOrCreateUserStateLocked(getChangingUserId()); 526e58a49e411327e26b6ad9939833f53c7fa5aef20Amith Yamasani Iterator<ComponentName> iterator = userState.getEnabledServices().iterator(); 527817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani while (iterator.hasNext()) { 528817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani ComponentName componentName = iterator.next(); 529817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani if (packageName.equals(componentName.getPackageName())) { 530817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani iterator.remove(); 531e58a49e411327e26b6ad9939833f53c7fa5aef20Amith Yamasani servicesRemoved = true; 5324b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 5334b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 534e58a49e411327e26b6ad9939833f53c7fa5aef20Amith Yamasani if (servicesRemoved) { 535e58a49e411327e26b6ad9939833f53c7fa5aef20Amith Yamasani persistComponentNamesToSettingLocked( 536e58a49e411327e26b6ad9939833f53c7fa5aef20Amith Yamasani Settings.Secure.ENABLED_PRINT_SERVICES, 537e58a49e411327e26b6ad9939833f53c7fa5aef20Amith Yamasani userState.getEnabledServices(), getChangingUserId()); 538e58a49e411327e26b6ad9939833f53c7fa5aef20Amith Yamasani userState.updateIfNeededLocked(); 539e58a49e411327e26b6ad9939833f53c7fa5aef20Amith Yamasani } 540dbcc95d4d889c4de2490870cfeb97cc8f6deb30eSvetoslav } 5414b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 5424b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 543817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 544817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public boolean onHandleForceStop(Intent intent, String[] stoppedPackages, 545817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani int uid, boolean doit) { 546817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani synchronized (mLock) { 54704533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // A background user/profile's print jobs are running but there is 54804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // no UI shown. Hence, if the packages of such a user change we need 54904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // to handle it as the change may affect ongoing print jobs. 550817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani UserState userState = getOrCreateUserStateLocked(getChangingUserId()); 551817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani boolean stoppedSomePackages = false; 552817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Iterator<ComponentName> iterator = userState.getEnabledServices() 553817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani .iterator(); 554817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani while (iterator.hasNext()) { 555817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani ComponentName componentName = iterator.next(); 556817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani String componentPackage = componentName.getPackageName(); 557817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani for (String stoppedPackage : stoppedPackages) { 558817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani if (componentPackage.equals(stoppedPackage)) { 559817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani if (!doit) { 560817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani return true; 561817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 562817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani stoppedSomePackages = true; 563817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani break; 5644b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 5654b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 5664b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 567817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani if (stoppedSomePackages) { 568817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState.updateIfNeededLocked(); 569817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 570817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani return false; 5714b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 5724b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 5734b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 574817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani @Override 575817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani public void onPackageAdded(String packageName, int uid) { 57604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // A background user/profile's print jobs are running but there is 57704533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // no UI shown. Hence, if the packages of such a user change we need 57804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav // to handle it as the change may affect ongoing print jobs. 579817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Intent intent = new Intent(android.printservice.PrintService.SERVICE_INTERFACE); 580817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani intent.setPackage(packageName); 581d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslav 582817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani List<ResolveInfo> installedServices = mContext.getPackageManager() 583817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani .queryIntentServicesAsUser(intent, PackageManager.GET_SERVICES, 584817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani getChangingUserId()); 585d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslav 586817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani if (installedServices == null) { 587817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani return; 588817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 589cb247866acf10b039e02b600f8471b4a508f0ce8Svetoslav Ganov 590817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int installedServiceCount = installedServices.size(); 591817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani for (int i = 0; i < installedServiceCount; i++) { 592817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani ServiceInfo serviceInfo = installedServices.get(i).serviceInfo; 593817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani ComponentName component = new ComponentName(serviceInfo.packageName, 594817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani serviceInfo.name); 595817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani String label = serviceInfo.loadLabel(mContext.getPackageManager()) 596817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani .toString(); 597817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani showEnableInstalledPrintServiceNotification(component, label, 598817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani getChangingUserId()); 599817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 600d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslav } 601d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslav 602817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani private void persistComponentNamesToSettingLocked(String settingName, 603817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Set<ComponentName> componentNames, int userId) { 604817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani StringBuilder builder = new StringBuilder(); 605817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani for (ComponentName componentName : componentNames) { 606817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani if (builder.length() > 0) { 607817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani builder.append(COMPONENT_NAME_SEPARATOR); 608817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 609817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani builder.append(componentName.flattenToShortString()); 610a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 611817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Settings.Secure.putStringForUser(mContext.getContentResolver(), 612817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani settingName, builder.toString(), userId); 613a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 614817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani }; 615817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani 616817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani // package changes 617817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani monitor.register(mContext, BackgroundThread.getHandler().getLooper(), 618817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani UserHandle.ALL, true); 6194b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 6204b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 621817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani private UserState getOrCreateUserStateLocked(int userId) { 622817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani UserState userState = mUserStates.get(userId); 6232fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav if (userState == null) { 624817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userState = new UserState(mContext, userId, mLock); 625817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani mUserStates.put(userId, userState); 6262fbd2a7f070f246ddafd9de94efa9a98861e9136Svetoslav } 627817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani return userState; 6284b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 6294b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 630c82768ff4b045b5b4edc08405964d504438a681fSvetoslav private void handleUserStarted(final int userId) { 631c82768ff4b045b5b4edc08405964d504438a681fSvetoslav // This code will touch the remote print spooler which 632c82768ff4b045b5b4edc08405964d504438a681fSvetoslav // must be called off the main thread, so post the work. 633c82768ff4b045b5b4edc08405964d504438a681fSvetoslav BackgroundThread.getHandler().post(new Runnable() { 634c82768ff4b045b5b4edc08405964d504438a681fSvetoslav @Override 635c82768ff4b045b5b4edc08405964d504438a681fSvetoslav public void run() { 636c82768ff4b045b5b4edc08405964d504438a681fSvetoslav UserState userState; 637c82768ff4b045b5b4edc08405964d504438a681fSvetoslav synchronized (mLock) { 638c82768ff4b045b5b4edc08405964d504438a681fSvetoslav userState = getOrCreateUserStateLocked(userId); 639c82768ff4b045b5b4edc08405964d504438a681fSvetoslav userState.updateIfNeededLocked(); 640c82768ff4b045b5b4edc08405964d504438a681fSvetoslav } 641c82768ff4b045b5b4edc08405964d504438a681fSvetoslav // This is the first time we switch to this user after boot, so 642c82768ff4b045b5b4edc08405964d504438a681fSvetoslav // now is the time to remove obsolete print jobs since they 643c82768ff4b045b5b4edc08405964d504438a681fSvetoslav // are from the last boot and no application would query them. 644c82768ff4b045b5b4edc08405964d504438a681fSvetoslav userState.removeObsoletePrintJobs(); 645c82768ff4b045b5b4edc08405964d504438a681fSvetoslav } 646c82768ff4b045b5b4edc08405964d504438a681fSvetoslav }); 647817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 648817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani 649c82768ff4b045b5b4edc08405964d504438a681fSvetoslav private void handleUserStopped(final int userId) { 650c82768ff4b045b5b4edc08405964d504438a681fSvetoslav // This code will touch the remote print spooler which 651c82768ff4b045b5b4edc08405964d504438a681fSvetoslav // must be called off the main thread, so post the work. 652c82768ff4b045b5b4edc08405964d504438a681fSvetoslav BackgroundThread.getHandler().post(new Runnable() { 653c82768ff4b045b5b4edc08405964d504438a681fSvetoslav @Override 654c82768ff4b045b5b4edc08405964d504438a681fSvetoslav public void run() { 655c82768ff4b045b5b4edc08405964d504438a681fSvetoslav synchronized (mLock) { 656c82768ff4b045b5b4edc08405964d504438a681fSvetoslav UserState userState = mUserStates.get(userId); 657c82768ff4b045b5b4edc08405964d504438a681fSvetoslav if (userState != null) { 658c82768ff4b045b5b4edc08405964d504438a681fSvetoslav userState.destroyLocked(); 659c82768ff4b045b5b4edc08405964d504438a681fSvetoslav mUserStates.remove(userId); 660c82768ff4b045b5b4edc08405964d504438a681fSvetoslav } 661c82768ff4b045b5b4edc08405964d504438a681fSvetoslav } 662817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 663c82768ff4b045b5b4edc08405964d504438a681fSvetoslav }); 6644b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 665a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov 66604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav private int resolveCallingProfileParentLocked(int userId) { 66786b1df234397802895771fe14cd8f2813fa43415Svetoslav if (userId != getCurrentUserId()) { 66804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav final long identity = Binder.clearCallingIdentity(); 66904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav try { 67004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav UserInfo parent = mUserManager.getProfileParent(userId); 67104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav if (parent != null) { 67204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return parent.getUserHandle().getIdentifier(); 67304533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } else { 67404533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return BACKGROUND_USER_ID; 67504533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 67604533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } finally { 67704533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav Binder.restoreCallingIdentity(identity); 67804533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 67904533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 68004533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav return userId; 68104533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav } 68204533dd3ba4e916f5a639d0cfbc331c32515cc84Svetoslav 683817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani private int resolveCallingAppEnforcingPermissions(int appId) { 684817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int callingUid = Binder.getCallingUid(); 685817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani if (callingUid == 0 || callingUid == Process.SYSTEM_UID 686817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani || callingUid == Process.SHELL_UID) { 687817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani return appId; 688817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 689817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int callingAppId = UserHandle.getAppId(callingUid); 690817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani if (appId == callingAppId) { 691817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani return appId; 692817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 693817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani if (mContext.checkCallingPermission( 694817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani "com.android.printspooler.permission.ACCESS_ALL_PRINT_JOBS") 695817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani != PackageManager.PERMISSION_GRANTED) { 696817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani throw new SecurityException("Call from app " + callingAppId + " as app " 697817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani + appId + " without com.android.printspooler.permission" 698817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani + ".ACCESS_ALL_PRINT_JOBS"); 699817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 700a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov return appId; 701a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov } 7024b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov 703817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani private int resolveCallingUserEnforcingPermissions(int userId) { 70486b1df234397802895771fe14cd8f2813fa43415Svetoslav try { 70586b1df234397802895771fe14cd8f2813fa43415Svetoslav return ActivityManagerNative.getDefault().handleIncomingUser(Binder.getCallingPid(), 70686b1df234397802895771fe14cd8f2813fa43415Svetoslav Binder.getCallingUid(), userId, true, true, "", null); 70786b1df234397802895771fe14cd8f2813fa43415Svetoslav } catch (RemoteException re) { 70886b1df234397802895771fe14cd8f2813fa43415Svetoslav // Shouldn't happen, local. 709817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 710194db6ad91c4aee995930ea8f04ea877730234fdSvet Ganov return userId; 7114b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov } 712d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslav 713817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani private String resolveCallingPackageNameEnforcingSecurity(String packageName) { 714817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani if (TextUtils.isEmpty(packageName)) { 715817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani return null; 716817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 717817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani String[] packages = mContext.getPackageManager().getPackagesForUid( 718817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Binder.getCallingUid()); 719817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani final int packageCount = packages.length; 720817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani for (int i = 0; i < packageCount; i++) { 721817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani if (packageName.equals(packages[i])) { 722817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani return packageName; 723817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 7247bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 725817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani return null; 7267bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav } 7277bfbbcb04bf4ba8f3069b2df136f708c9849bacfSvetoslav 72886b1df234397802895771fe14cd8f2813fa43415Svetoslav private int getCurrentUserId () { 72986b1df234397802895771fe14cd8f2813fa43415Svetoslav final long identity = Binder.clearCallingIdentity(); 73086b1df234397802895771fe14cd8f2813fa43415Svetoslav try { 73186b1df234397802895771fe14cd8f2813fa43415Svetoslav return ActivityManager.getCurrentUser(); 73286b1df234397802895771fe14cd8f2813fa43415Svetoslav } finally { 73386b1df234397802895771fe14cd8f2813fa43415Svetoslav Binder.restoreCallingIdentity(identity); 73486b1df234397802895771fe14cd8f2813fa43415Svetoslav } 73586b1df234397802895771fe14cd8f2813fa43415Svetoslav } 73686b1df234397802895771fe14cd8f2813fa43415Svetoslav 737817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani private void showEnableInstalledPrintServiceNotification(ComponentName component, 738817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani String label, int userId) { 739817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani UserHandle userHandle = new UserHandle(userId); 7404a82b455f9832430207e3ecfddfad4b67b071407Svetoslav Ganov 741817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani Intent intent = new Intent(Settings.ACTION_PRINT_SETTINGS); 742817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani intent.putExtra(EXTRA_PRINT_SERVICE_COMPONENT_NAME, component.flattenToString()); 743d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslav 744817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani PendingIntent pendingIntent = PendingIntent.getActivityAsUser(mContext, 0, intent, 745817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT, null, 746817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userHandle); 747d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslav 74807ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy Context builderContext = mContext; 74907ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy try { 75007ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy builderContext = mContext.createPackageContextAsUser(mContext.getPackageName(), 0, 75107ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy userHandle); 75207ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy } catch (NameNotFoundException e) { 75307ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy // Ignore can't find the package the system is running as. 75407ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy } 75507ad8dc2087aa02da48353acc19ba82e62d99f82Kenny Guy Notification.Builder builder = new Notification.Builder(builderContext) 756817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani .setSmallIcon(R.drawable.ic_print) 757817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani .setContentTitle(mContext.getString(R.string.print_service_installed_title, 758817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani label)) 759817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani .setContentText(mContext.getString(R.string.print_service_installed_message)) 760817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani .setContentIntent(pendingIntent) 761817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani .setWhen(System.currentTimeMillis()) 762817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani .setAutoCancel(true) 763255dd04271088590fedc46c8e22b2fd4ab142d39Selim Cinek .setShowWhen(true) 7644a357cd2e55293402d7172766f7f9419815fc1e8Alan Viverette .setColor(mContext.getColor( 765255dd04271088590fedc46c8e22b2fd4ab142d39Selim Cinek com.android.internal.R.color.system_notification_accent_color)); 766d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslav 767817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani NotificationManager notificationManager = (NotificationManager) mContext 768817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani .getSystemService(Context.NOTIFICATION_SERVICE); 769d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslav 770817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani String notificationTag = getClass().getName() + ":" + component.flattenToString(); 771817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani notificationManager.notifyAsUser(notificationTag, 0, builder.build(), 772817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani userHandle); 773817ec49e7991d4cac50b2308cd7cf5f8641e1e29Amith Yamasani } 774d8f391b4e0e8d876ec7216d34f86a9b3e8bab7e5Svetoslav } 7754b9a4d16872bbb50712e007b419ac0b35ff1582dSvetoslav Ganov} 776