1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.print; 18 19 import android.Manifest; 20 import android.app.ActivityManager; 21 import android.app.ActivityManagerNative; 22 import android.app.Notification; 23 import android.app.NotificationManager; 24 import android.app.PendingIntent; 25 import android.content.ComponentName; 26 import android.content.Context; 27 import android.content.Intent; 28 import android.content.pm.PackageManager; 29 import android.content.pm.PackageManager.NameNotFoundException; 30 import android.content.pm.ResolveInfo; 31 import android.content.pm.ServiceInfo; 32 import android.content.pm.UserInfo; 33 import android.database.ContentObserver; 34 import android.net.Uri; 35 import android.os.Binder; 36 import android.os.Bundle; 37 import android.os.Process; 38 import android.os.RemoteException; 39 import android.os.UserHandle; 40 import android.os.UserManager; 41 import android.print.IPrintDocumentAdapter; 42 import android.print.IPrintJobStateChangeListener; 43 import android.print.IPrintManager; 44 import android.print.IPrinterDiscoveryObserver; 45 import android.print.PrintAttributes; 46 import android.print.PrintJobId; 47 import android.print.PrintJobInfo; 48 import android.print.PrinterId; 49 import android.printservice.PrintServiceInfo; 50 import android.provider.Settings; 51 import android.text.TextUtils; 52 import android.util.SparseArray; 53 54 import com.android.internal.R; 55 import com.android.internal.content.PackageMonitor; 56 import com.android.internal.os.BackgroundThread; 57 import com.android.server.SystemService; 58 59 import java.io.FileDescriptor; 60 import java.io.PrintWriter; 61 import java.util.Iterator; 62 import java.util.List; 63 import java.util.Set; 64 65 /** 66 * SystemService wrapper for the PrintManager implementation. Publishes 67 * Context.PRINT_SERVICE. 68 * PrintManager implementation is contained within. 69 */ 70 71 public final class PrintManagerService extends SystemService { 72 private final PrintManagerImpl mPrintManagerImpl; 73 74 public PrintManagerService(Context context) { 75 super(context); 76 mPrintManagerImpl = new PrintManagerImpl(context); 77 } 78 79 @Override 80 public void onStart() { 81 publishBinderService(Context.PRINT_SERVICE, mPrintManagerImpl); 82 } 83 84 @Override 85 public void onStartUser(int userHandle) { 86 mPrintManagerImpl.handleUserStarted(userHandle); 87 } 88 89 @Override 90 public void onStopUser(int userHandle) { 91 mPrintManagerImpl.handleUserStopped(userHandle); 92 } 93 94 class PrintManagerImpl extends IPrintManager.Stub { 95 private static final char COMPONENT_NAME_SEPARATOR = ':'; 96 97 private static final String EXTRA_PRINT_SERVICE_COMPONENT_NAME = 98 "EXTRA_PRINT_SERVICE_COMPONENT_NAME"; 99 100 private static final int BACKGROUND_USER_ID = -10; 101 102 private final Object mLock = new Object(); 103 104 private final Context mContext; 105 106 private final UserManager mUserManager; 107 108 private final SparseArray<UserState> mUserStates = new SparseArray<>(); 109 110 PrintManagerImpl(Context context) { 111 mContext = context; 112 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 113 registerContentObservers(); 114 registerBroadcastReceivers(); 115 } 116 117 @Override 118 public Bundle print(String printJobName, IPrintDocumentAdapter adapter, 119 PrintAttributes attributes, String packageName, int appId, int userId) { 120 final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 121 final int resolvedAppId; 122 final UserState userState; 123 final String resolvedPackageName; 124 synchronized (mLock) { 125 // Only the current group members can start new print jobs. 126 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 127 return null; 128 } 129 resolvedAppId = resolveCallingAppEnforcingPermissions(appId); 130 resolvedPackageName = resolveCallingPackageNameEnforcingSecurity(packageName); 131 userState = getOrCreateUserStateLocked(resolvedUserId); 132 } 133 final long identity = Binder.clearCallingIdentity(); 134 try { 135 return userState.print(printJobName, adapter, attributes, 136 resolvedPackageName, resolvedAppId); 137 } finally { 138 Binder.restoreCallingIdentity(identity); 139 } 140 } 141 142 @Override 143 public List<PrintJobInfo> getPrintJobInfos(int appId, int userId) { 144 final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 145 final int resolvedAppId; 146 final UserState userState; 147 synchronized (mLock) { 148 // Only the current group members can query for state of print jobs. 149 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 150 return null; 151 } 152 resolvedAppId = resolveCallingAppEnforcingPermissions(appId); 153 userState = getOrCreateUserStateLocked(resolvedUserId); 154 } 155 final long identity = Binder.clearCallingIdentity(); 156 try { 157 return userState.getPrintJobInfos(resolvedAppId); 158 } finally { 159 Binder.restoreCallingIdentity(identity); 160 } 161 } 162 163 @Override 164 public PrintJobInfo getPrintJobInfo(PrintJobId printJobId, int appId, int userId) { 165 final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 166 final int resolvedAppId; 167 final UserState userState; 168 synchronized (mLock) { 169 // Only the current group members can query for state of a print job. 170 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 171 return null; 172 } 173 resolvedAppId = resolveCallingAppEnforcingPermissions(appId); 174 userState = getOrCreateUserStateLocked(resolvedUserId); 175 } 176 final long identity = Binder.clearCallingIdentity(); 177 try { 178 return userState.getPrintJobInfo(printJobId, resolvedAppId); 179 } finally { 180 Binder.restoreCallingIdentity(identity); 181 } 182 } 183 184 @Override 185 public void cancelPrintJob(PrintJobId printJobId, int appId, int userId) { 186 final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 187 final int resolvedAppId; 188 final UserState userState; 189 synchronized (mLock) { 190 // Only the current group members can cancel a print job. 191 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 192 return; 193 } 194 resolvedAppId = resolveCallingAppEnforcingPermissions(appId); 195 userState = getOrCreateUserStateLocked(resolvedUserId); 196 } 197 final long identity = Binder.clearCallingIdentity(); 198 try { 199 userState.cancelPrintJob(printJobId, resolvedAppId); 200 } finally { 201 Binder.restoreCallingIdentity(identity); 202 } 203 } 204 205 @Override 206 public void restartPrintJob(PrintJobId printJobId, int appId, int userId) { 207 final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 208 final int resolvedAppId; 209 final UserState userState; 210 synchronized (mLock) { 211 // Only the current group members can restart a print job. 212 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 213 return; 214 } 215 resolvedAppId = resolveCallingAppEnforcingPermissions(appId); 216 userState = getOrCreateUserStateLocked(resolvedUserId); 217 } 218 final long identity = Binder.clearCallingIdentity(); 219 try { 220 userState.restartPrintJob(printJobId, resolvedAppId); 221 } finally { 222 Binder.restoreCallingIdentity(identity); 223 } 224 } 225 226 @Override 227 public List<PrintServiceInfo> getEnabledPrintServices(int userId) { 228 final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 229 final UserState userState; 230 synchronized (mLock) { 231 // Only the current group members can get enabled services. 232 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 233 return null; 234 } 235 userState = getOrCreateUserStateLocked(resolvedUserId); 236 } 237 final long identity = Binder.clearCallingIdentity(); 238 try { 239 return userState.getEnabledPrintServices(); 240 } finally { 241 Binder.restoreCallingIdentity(identity); 242 } 243 } 244 245 @Override 246 public List<PrintServiceInfo> getInstalledPrintServices(int userId) { 247 final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 248 final UserState userState; 249 synchronized (mLock) { 250 // Only the current group members can get installed services. 251 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 252 return null; 253 } 254 userState = getOrCreateUserStateLocked(resolvedUserId); 255 } 256 final long identity = Binder.clearCallingIdentity(); 257 try { 258 return userState.getInstalledPrintServices(); 259 } finally { 260 Binder.restoreCallingIdentity(identity); 261 } 262 } 263 264 @Override 265 public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer, 266 int userId) { 267 final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 268 final UserState userState; 269 synchronized (mLock) { 270 // Only the current group members can create a discovery session. 271 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 272 return; 273 } 274 userState = getOrCreateUserStateLocked(resolvedUserId); 275 } 276 final long identity = Binder.clearCallingIdentity(); 277 try { 278 userState.createPrinterDiscoverySession(observer); 279 } finally { 280 Binder.restoreCallingIdentity(identity); 281 } 282 } 283 284 @Override 285 public void destroyPrinterDiscoverySession(IPrinterDiscoveryObserver observer, 286 int userId) { 287 final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 288 final UserState userState; 289 synchronized (mLock) { 290 // Only the current group members can destroy a discovery session. 291 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 292 return; 293 } 294 userState = getOrCreateUserStateLocked(resolvedUserId); 295 } 296 final long identity = Binder.clearCallingIdentity(); 297 try { 298 userState.destroyPrinterDiscoverySession(observer); 299 } finally { 300 Binder.restoreCallingIdentity(identity); 301 } 302 } 303 304 @Override 305 public void startPrinterDiscovery(IPrinterDiscoveryObserver observer, 306 List<PrinterId> priorityList, int userId) { 307 final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 308 final UserState userState; 309 synchronized (mLock) { 310 // Only the current group members can start discovery. 311 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 312 return; 313 } 314 userState = getOrCreateUserStateLocked(resolvedUserId); 315 } 316 final long identity = Binder.clearCallingIdentity(); 317 try { 318 userState.startPrinterDiscovery(observer, priorityList); 319 } finally { 320 Binder.restoreCallingIdentity(identity); 321 } 322 } 323 324 @Override 325 public void stopPrinterDiscovery(IPrinterDiscoveryObserver observer, int userId) { 326 final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 327 final UserState userState; 328 synchronized (mLock) { 329 // Only the current group members can stop discovery. 330 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 331 return; 332 } 333 userState = getOrCreateUserStateLocked(resolvedUserId); 334 } 335 final long identity = Binder.clearCallingIdentity(); 336 try { 337 userState.stopPrinterDiscovery(observer); 338 } finally { 339 Binder.restoreCallingIdentity(identity); 340 } 341 } 342 343 @Override 344 public void validatePrinters(List<PrinterId> printerIds, int userId) { 345 final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 346 final UserState userState; 347 synchronized (mLock) { 348 // Only the current group members can validate printers. 349 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 350 return; 351 } 352 userState = getOrCreateUserStateLocked(resolvedUserId); 353 } 354 final long identity = Binder.clearCallingIdentity(); 355 try { 356 userState.validatePrinters(printerIds); 357 } finally { 358 Binder.restoreCallingIdentity(identity); 359 } 360 } 361 362 @Override 363 public void startPrinterStateTracking(PrinterId printerId, int userId) { 364 final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 365 final UserState userState; 366 synchronized (mLock) { 367 // Only the current group members can start printer tracking. 368 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 369 return; 370 } 371 userState = getOrCreateUserStateLocked(resolvedUserId); 372 } 373 final long identity = Binder.clearCallingIdentity(); 374 try { 375 userState.startPrinterStateTracking(printerId); 376 } finally { 377 Binder.restoreCallingIdentity(identity); 378 } 379 } 380 381 @Override 382 public void stopPrinterStateTracking(PrinterId printerId, int userId) { 383 final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 384 final UserState userState; 385 synchronized (mLock) { 386 // Only the current group members can stop printer tracking. 387 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 388 return; 389 } 390 userState = getOrCreateUserStateLocked(resolvedUserId); 391 } 392 final long identity = Binder.clearCallingIdentity(); 393 try { 394 userState.stopPrinterStateTracking(printerId); 395 } finally { 396 Binder.restoreCallingIdentity(identity); 397 } 398 } 399 400 @Override 401 public void addPrintJobStateChangeListener(IPrintJobStateChangeListener listener, 402 int appId, int userId) throws RemoteException { 403 final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 404 final int resolvedAppId; 405 final UserState userState; 406 synchronized (mLock) { 407 // Only the current group members can add a print job listener. 408 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 409 return; 410 } 411 resolvedAppId = resolveCallingAppEnforcingPermissions(appId); 412 userState = getOrCreateUserStateLocked(resolvedUserId); 413 } 414 final long identity = Binder.clearCallingIdentity(); 415 try { 416 userState.addPrintJobStateChangeListener(listener, resolvedAppId); 417 } finally { 418 Binder.restoreCallingIdentity(identity); 419 } 420 } 421 422 @Override 423 public void removePrintJobStateChangeListener(IPrintJobStateChangeListener listener, 424 int userId) { 425 final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); 426 final UserState userState; 427 synchronized (mLock) { 428 // Only the current group members can remove a print job listener. 429 if (resolveCallingProfileParentLocked(resolvedUserId) != getCurrentUserId()) { 430 return; 431 } 432 userState = getOrCreateUserStateLocked(resolvedUserId); 433 } 434 final long identity = Binder.clearCallingIdentity(); 435 try { 436 userState.removePrintJobStateChangeListener(listener); 437 } finally { 438 Binder.restoreCallingIdentity(identity); 439 } 440 } 441 442 @Override 443 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 444 if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP) 445 != PackageManager.PERMISSION_GRANTED) { 446 pw.println("Permission Denial: can't dump PrintManager from from pid=" 447 + Binder.getCallingPid() 448 + ", uid=" + Binder.getCallingUid()); 449 return; 450 } 451 452 synchronized (mLock) { 453 final long identity = Binder.clearCallingIdentity(); 454 try { 455 pw.println("PRINT MANAGER STATE (dumpsys print)"); 456 final int userStateCount = mUserStates.size(); 457 for (int i = 0; i < userStateCount; i++) { 458 UserState userState = mUserStates.valueAt(i); 459 userState.dump(fd, pw, ""); 460 pw.println(); 461 } 462 } finally { 463 Binder.restoreCallingIdentity(identity); 464 } 465 } 466 } 467 468 private void registerContentObservers() { 469 final Uri enabledPrintServicesUri = Settings.Secure.getUriFor( 470 Settings.Secure.ENABLED_PRINT_SERVICES); 471 ContentObserver observer = new ContentObserver(BackgroundThread.getHandler()) { 472 @Override 473 public void onChange(boolean selfChange, Uri uri, int userId) { 474 if (enabledPrintServicesUri.equals(uri)) { 475 synchronized (mLock) { 476 if (userId != UserHandle.USER_ALL) { 477 UserState userState = getOrCreateUserStateLocked(userId); 478 userState.updateIfNeededLocked(); 479 } else { 480 final int userCount = mUserStates.size(); 481 for (int i = 0; i < userCount; i++) { 482 UserState userState = mUserStates.valueAt(i); 483 userState.updateIfNeededLocked(); 484 } 485 } 486 } 487 } 488 } 489 }; 490 491 mContext.getContentResolver().registerContentObserver(enabledPrintServicesUri, 492 false, observer, UserHandle.USER_ALL); 493 } 494 495 private void registerBroadcastReceivers() { 496 PackageMonitor monitor = new PackageMonitor() { 497 @Override 498 public void onPackageModified(String packageName) { 499 synchronized (mLock) { 500 // A background user/profile's print jobs are running but there is 501 // no UI shown. Hence, if the packages of such a user change we need 502 // to handle it as the change may affect ongoing print jobs. 503 boolean servicesChanged = false; 504 UserState userState = getOrCreateUserStateLocked(getChangingUserId()); 505 Iterator<ComponentName> iterator = userState.getEnabledServices().iterator(); 506 while (iterator.hasNext()) { 507 ComponentName componentName = iterator.next(); 508 if (packageName.equals(componentName.getPackageName())) { 509 servicesChanged = true; 510 } 511 } 512 if (servicesChanged) { 513 userState.updateIfNeededLocked(); 514 } 515 } 516 } 517 518 @Override 519 public void onPackageRemoved(String packageName, int uid) { 520 synchronized (mLock) { 521 // A background user/profile's print jobs are running but there is 522 // no UI shown. Hence, if the packages of such a user change we need 523 // to handle it as the change may affect ongoing print jobs. 524 boolean servicesRemoved = false; 525 UserState userState = getOrCreateUserStateLocked(getChangingUserId()); 526 Iterator<ComponentName> iterator = userState.getEnabledServices().iterator(); 527 while (iterator.hasNext()) { 528 ComponentName componentName = iterator.next(); 529 if (packageName.equals(componentName.getPackageName())) { 530 iterator.remove(); 531 servicesRemoved = true; 532 } 533 } 534 if (servicesRemoved) { 535 persistComponentNamesToSettingLocked( 536 Settings.Secure.ENABLED_PRINT_SERVICES, 537 userState.getEnabledServices(), getChangingUserId()); 538 userState.updateIfNeededLocked(); 539 } 540 } 541 } 542 543 @Override 544 public boolean onHandleForceStop(Intent intent, String[] stoppedPackages, 545 int uid, boolean doit) { 546 synchronized (mLock) { 547 // A background user/profile's print jobs are running but there is 548 // no UI shown. Hence, if the packages of such a user change we need 549 // to handle it as the change may affect ongoing print jobs. 550 UserState userState = getOrCreateUserStateLocked(getChangingUserId()); 551 boolean stoppedSomePackages = false; 552 Iterator<ComponentName> iterator = userState.getEnabledServices() 553 .iterator(); 554 while (iterator.hasNext()) { 555 ComponentName componentName = iterator.next(); 556 String componentPackage = componentName.getPackageName(); 557 for (String stoppedPackage : stoppedPackages) { 558 if (componentPackage.equals(stoppedPackage)) { 559 if (!doit) { 560 return true; 561 } 562 stoppedSomePackages = true; 563 break; 564 } 565 } 566 } 567 if (stoppedSomePackages) { 568 userState.updateIfNeededLocked(); 569 } 570 return false; 571 } 572 } 573 574 @Override 575 public void onPackageAdded(String packageName, int uid) { 576 // A background user/profile's print jobs are running but there is 577 // no UI shown. Hence, if the packages of such a user change we need 578 // to handle it as the change may affect ongoing print jobs. 579 Intent intent = new Intent(android.printservice.PrintService.SERVICE_INTERFACE); 580 intent.setPackage(packageName); 581 582 List<ResolveInfo> installedServices = mContext.getPackageManager() 583 .queryIntentServicesAsUser(intent, PackageManager.GET_SERVICES, 584 getChangingUserId()); 585 586 if (installedServices == null) { 587 return; 588 } 589 590 final int installedServiceCount = installedServices.size(); 591 for (int i = 0; i < installedServiceCount; i++) { 592 ServiceInfo serviceInfo = installedServices.get(i).serviceInfo; 593 ComponentName component = new ComponentName(serviceInfo.packageName, 594 serviceInfo.name); 595 String label = serviceInfo.loadLabel(mContext.getPackageManager()) 596 .toString(); 597 showEnableInstalledPrintServiceNotification(component, label, 598 getChangingUserId()); 599 } 600 } 601 602 private void persistComponentNamesToSettingLocked(String settingName, 603 Set<ComponentName> componentNames, int userId) { 604 StringBuilder builder = new StringBuilder(); 605 for (ComponentName componentName : componentNames) { 606 if (builder.length() > 0) { 607 builder.append(COMPONENT_NAME_SEPARATOR); 608 } 609 builder.append(componentName.flattenToShortString()); 610 } 611 Settings.Secure.putStringForUser(mContext.getContentResolver(), 612 settingName, builder.toString(), userId); 613 } 614 }; 615 616 // package changes 617 monitor.register(mContext, BackgroundThread.getHandler().getLooper(), 618 UserHandle.ALL, true); 619 } 620 621 private UserState getOrCreateUserStateLocked(int userId) { 622 UserState userState = mUserStates.get(userId); 623 if (userState == null) { 624 userState = new UserState(mContext, userId, mLock); 625 mUserStates.put(userId, userState); 626 } 627 return userState; 628 } 629 630 private void handleUserStarted(final int userId) { 631 // This code will touch the remote print spooler which 632 // must be called off the main thread, so post the work. 633 BackgroundThread.getHandler().post(new Runnable() { 634 @Override 635 public void run() { 636 UserState userState; 637 synchronized (mLock) { 638 userState = getOrCreateUserStateLocked(userId); 639 userState.updateIfNeededLocked(); 640 } 641 // This is the first time we switch to this user after boot, so 642 // now is the time to remove obsolete print jobs since they 643 // are from the last boot and no application would query them. 644 userState.removeObsoletePrintJobs(); 645 } 646 }); 647 } 648 649 private void handleUserStopped(final int userId) { 650 // This code will touch the remote print spooler which 651 // must be called off the main thread, so post the work. 652 BackgroundThread.getHandler().post(new Runnable() { 653 @Override 654 public void run() { 655 synchronized (mLock) { 656 UserState userState = mUserStates.get(userId); 657 if (userState != null) { 658 userState.destroyLocked(); 659 mUserStates.remove(userId); 660 } 661 } 662 } 663 }); 664 } 665 666 private int resolveCallingProfileParentLocked(int userId) { 667 if (userId != getCurrentUserId()) { 668 final long identity = Binder.clearCallingIdentity(); 669 try { 670 UserInfo parent = mUserManager.getProfileParent(userId); 671 if (parent != null) { 672 return parent.getUserHandle().getIdentifier(); 673 } else { 674 return BACKGROUND_USER_ID; 675 } 676 } finally { 677 Binder.restoreCallingIdentity(identity); 678 } 679 } 680 return userId; 681 } 682 683 private int resolveCallingAppEnforcingPermissions(int appId) { 684 final int callingUid = Binder.getCallingUid(); 685 if (callingUid == 0 || callingUid == Process.SYSTEM_UID 686 || callingUid == Process.SHELL_UID) { 687 return appId; 688 } 689 final int callingAppId = UserHandle.getAppId(callingUid); 690 if (appId == callingAppId) { 691 return appId; 692 } 693 if (mContext.checkCallingPermission( 694 "com.android.printspooler.permission.ACCESS_ALL_PRINT_JOBS") 695 != PackageManager.PERMISSION_GRANTED) { 696 throw new SecurityException("Call from app " + callingAppId + " as app " 697 + appId + " without com.android.printspooler.permission" 698 + ".ACCESS_ALL_PRINT_JOBS"); 699 } 700 return appId; 701 } 702 703 private int resolveCallingUserEnforcingPermissions(int userId) { 704 try { 705 return ActivityManagerNative.getDefault().handleIncomingUser(Binder.getCallingPid(), 706 Binder.getCallingUid(), userId, true, true, "", null); 707 } catch (RemoteException re) { 708 // Shouldn't happen, local. 709 } 710 return userId; 711 } 712 713 private String resolveCallingPackageNameEnforcingSecurity(String packageName) { 714 if (TextUtils.isEmpty(packageName)) { 715 return null; 716 } 717 String[] packages = mContext.getPackageManager().getPackagesForUid( 718 Binder.getCallingUid()); 719 final int packageCount = packages.length; 720 for (int i = 0; i < packageCount; i++) { 721 if (packageName.equals(packages[i])) { 722 return packageName; 723 } 724 } 725 return null; 726 } 727 728 private int getCurrentUserId () { 729 final long identity = Binder.clearCallingIdentity(); 730 try { 731 return ActivityManager.getCurrentUser(); 732 } finally { 733 Binder.restoreCallingIdentity(identity); 734 } 735 } 736 737 private void showEnableInstalledPrintServiceNotification(ComponentName component, 738 String label, int userId) { 739 UserHandle userHandle = new UserHandle(userId); 740 741 Intent intent = new Intent(Settings.ACTION_PRINT_SETTINGS); 742 intent.putExtra(EXTRA_PRINT_SERVICE_COMPONENT_NAME, component.flattenToString()); 743 744 PendingIntent pendingIntent = PendingIntent.getActivityAsUser(mContext, 0, intent, 745 PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT, null, 746 userHandle); 747 748 Context builderContext = mContext; 749 try { 750 builderContext = mContext.createPackageContextAsUser(mContext.getPackageName(), 0, 751 userHandle); 752 } catch (NameNotFoundException e) { 753 // Ignore can't find the package the system is running as. 754 } 755 Notification.Builder builder = new Notification.Builder(builderContext) 756 .setSmallIcon(R.drawable.ic_print) 757 .setContentTitle(mContext.getString(R.string.print_service_installed_title, 758 label)) 759 .setContentText(mContext.getString(R.string.print_service_installed_message)) 760 .setContentIntent(pendingIntent) 761 .setWhen(System.currentTimeMillis()) 762 .setAutoCancel(true) 763 .setShowWhen(true) 764 .setColor(mContext.getResources().getColor( 765 com.android.internal.R.color.system_notification_accent_color)); 766 767 NotificationManager notificationManager = (NotificationManager) mContext 768 .getSystemService(Context.NOTIFICATION_SERVICE); 769 770 String notificationTag = getClass().getName() + ":" + component.flattenToString(); 771 notificationManager.notifyAsUser(notificationTag, 0, builder.build(), 772 userHandle); 773 } 774 } 775 } 776