Enforce permission for print system APIs

The permission is preinstalled as we want to leave the PrintSpooler
unpriviledged.

Test: Checked that Settings, PrintSpooler and BuiltInPrintService still
      behave as expected.
Fixes: 62350107
Change-Id: Id33896f2899533f2d05cafa926df29cf1c6bfa77
diff --git a/api/system-current.txt b/api/system-current.txt
index 268d8ec..52ffcf6 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -190,6 +190,8 @@
     field public static final java.lang.String READ_OEM_UNLOCK_STATE = "android.permission.READ_OEM_UNLOCK_STATE";
     field public static final java.lang.String READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS";
     field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
+    field public static final java.lang.String READ_PRINT_SERVICES = "android.permission.READ_PRINT_SERVICES";
+    field public static final java.lang.String READ_PRINT_SERVICE_RECOMMENDATIONS = "android.permission.READ_PRINT_SERVICE_RECOMMENDATIONS";
     field public static final java.lang.String READ_PRIVILEGED_PHONE_STATE = "android.permission.READ_PRIVILEGED_PHONE_STATE";
     field public static final java.lang.String READ_SEARCH_INDEXABLES = "android.permission.READ_SEARCH_INDEXABLES";
     field public static final java.lang.String READ_SMS = "android.permission.READ_SMS";
diff --git a/api/test-current.txt b/api/test-current.txt
index c2a1231..f05ef09 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -32732,9 +32732,7 @@
 
   public final class PrintManager {
     method public java.util.List<android.print.PrintJob> getPrintJobs();
-    method public java.util.List<android.printservice.PrintServiceInfo> getPrintServices(int);
     method public android.print.PrintJob print(java.lang.String, android.print.PrintDocumentAdapter, android.print.PrintAttributes);
-    field public static final int ALL_SERVICES = 3; // 0x3
   }
 
   public final class PrinterCapabilitiesInfo implements android.os.Parcelable {
@@ -32864,13 +32862,6 @@
     field public static final java.lang.String SERVICE_META_DATA = "android.printservice";
   }
 
-  public final class PrintServiceInfo implements android.os.Parcelable {
-    method public int describeContents();
-    method public android.content.ComponentName getComponentName();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.printservice.PrintServiceInfo> CREATOR;
-  }
-
   public abstract class PrinterDiscoverySession {
     ctor public PrinterDiscoverySession();
     method public final void addPrinters(java.util.List<android.print.PrinterInfo>);
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
index 52dccb4..51b7798 100644
--- a/core/java/android/print/PrintManager.java
+++ b/core/java/android/print/PrintManager.java
@@ -18,9 +18,9 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
-import android.annotation.TestApi;
 import android.app.Activity;
 import android.app.Application.ActivityLifecycleCallbacks;
 import android.content.ComponentName;
@@ -142,7 +142,6 @@
      * @see #getPrintServices
      * @hide
      */
-    @TestApi
     public static final int ALL_SERVICES = ENABLED_SERVICES | DISABLED_SERVICES;
 
     /**
@@ -554,6 +553,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRINT_SERVICES)
     public void addPrintServicesChangeListener(@NonNull PrintServicesChangeListener listener,
             @Nullable Handler handler) {
         Preconditions.checkNotNull(listener);
@@ -589,6 +589,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRINT_SERVICES)
     public void removePrintServicesChangeListener(@NonNull PrintServicesChangeListener listener) {
         Preconditions.checkNotNull(listener);
 
@@ -629,8 +630,8 @@
      *
      * @hide
      */
-    @TestApi
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRINT_SERVICES)
     public @NonNull List<PrintServiceInfo> getPrintServices(int selectionFlags) {
         Preconditions.checkFlagsArgument(selectionFlags, ALL_SERVICES);
 
@@ -656,6 +657,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRINT_SERVICE_RECOMMENDATIONS)
     public void addPrintServiceRecommendationsChangeListener(
             @NonNull PrintServiceRecommendationsChangeListener listener,
             @Nullable Handler handler) {
@@ -692,6 +694,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRINT_SERVICE_RECOMMENDATIONS)
     public void removePrintServiceRecommendationsChangeListener(
             @NonNull PrintServiceRecommendationsChangeListener listener) {
         Preconditions.checkNotNull(listener);
@@ -731,6 +734,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRINT_SERVICE_RECOMMENDATIONS)
     public @NonNull List<RecommendationInfo> getPrintServiceRecommendations() {
         try {
             List<RecommendationInfo> recommendations =
diff --git a/core/java/android/printservice/PrintServiceInfo.java b/core/java/android/printservice/PrintServiceInfo.java
index 5ef9319..57f1229 100644
--- a/core/java/android/printservice/PrintServiceInfo.java
+++ b/core/java/android/printservice/PrintServiceInfo.java
@@ -18,7 +18,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
-import android.annotation.TestApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -49,7 +48,6 @@
  *
  * @hide
  */
-@TestApi
 @SystemApi
 public final class PrintServiceInfo implements Parcelable {
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 222ecbc..56d5d28 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2534,6 +2534,23 @@
     <permission android:name="android.permission.BIND_PRINT_RECOMMENDATION_SERVICE"
             android:protectionLevel="signature" />
 
+    <!-- Allows applications to get the installed and enabled print services.
+         @hide
+         @SystemApi
+         @TestApi
+         <p>Protection level: signature|preinstalled
+    -->
+    <permission android:name="android.permission.READ_PRINT_SERVICES"
+        android:protectionLevel="signature|preinstalled" />
+
+    <!-- Allows applications to get the currently recommended print services for printers.
+         @hide
+         @SystemApi
+         <p>Protection level: signature|preinstalled
+    -->
+    <permission android:name="android.permission.READ_PRINT_SERVICE_RECOMMENDATIONS"
+        android:protectionLevel="signature|preinstalled" />
+
     <!-- Must be required by a {@link android.nfc.cardemulation.HostApduService}
          or {@link android.nfc.cardemulation.OffHostApduService} to ensure that only
          the system can bind to it.
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index 4b9415e..91e23dd 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -36,6 +36,8 @@
     <uses-permission android:name="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"/>
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
+    <uses-permission android:name="android.permission.READ_PRINT_SERVICES" />
+    <uses-permission android:name="android.permission.READ_PRINT_SERVICE_RECOMMENDATIONS" />
 
     <application
         android:allowClearUserData="true"
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index 3ec8380..6c417a9 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -263,6 +263,8 @@
             Preconditions.checkFlagsArgument(selectionFlags,
                     PrintManager.DISABLED_SERVICES | PrintManager.ENABLED_SERVICES);
 
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.READ_PRINT_SERVICES, null);
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final UserState userState;
             synchronized (mLock) {
@@ -316,6 +318,8 @@
 
         @Override
         public List<RecommendationInfo> getPrintServiceRecommendations(int userId) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.READ_PRINT_SERVICE_RECOMMENDATIONS, null);
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final UserState userState;
             synchronized (mLock) {
@@ -538,6 +542,8 @@
                 int userId) throws RemoteException {
             listener = Preconditions.checkNotNull(listener);
 
+            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRINT_SERVICES,
+                    null);
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final UserState userState;
             synchronized (mLock) {
@@ -560,6 +566,8 @@
                 int userId) {
             listener = Preconditions.checkNotNull(listener);
 
+            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRINT_SERVICES,
+                    null);
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final UserState userState;
             synchronized (mLock) {
@@ -583,6 +591,8 @@
                 throws RemoteException {
             listener = Preconditions.checkNotNull(listener);
 
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.READ_PRINT_SERVICE_RECOMMENDATIONS, null);
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final UserState userState;
             synchronized (mLock) {
@@ -605,6 +615,8 @@
                 IRecommendationsChangeListener listener, int userId) {
             listener = Preconditions.checkNotNull(listener);
 
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.READ_PRINT_SERVICE_RECOMMENDATIONS, null);
             final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
             final UserState userState;
             synchronized (mLock) {
@@ -888,12 +900,12 @@
 
         private int resolveCallingAppEnforcingPermissions(int appId) {
             final int callingUid = Binder.getCallingUid();
-            if (callingUid == 0 || callingUid == Process.SYSTEM_UID
-                    || callingUid == Process.SHELL_UID) {
+            if (callingUid == 0) {
                 return appId;
             }
             final int callingAppId = UserHandle.getAppId(callingUid);
-            if (appId == callingAppId) {
+            if (appId == callingAppId || callingAppId == Process.SHELL_UID
+                    || callingAppId == Process.SYSTEM_UID) {
                 return appId;
             }
             if (mContext.checkCallingPermission(