Added keep-uninstalled-packages DO policy

This policy allows DO to specify a list of apps to cache even without being
installed on any user.

Bug: 23938464
Change-Id: I2eeab7f148409739fc23a5c44e955ad12b63fd04
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index faed7a0..58f4c63 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3591,6 +3591,48 @@
     }
 
     /**
+     * Called by a device owner to get the list of apps to keep around as APKs even if no user has
+     * currently installed it.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     *
+     * @return List of package names to keep cached.
+     * @hide
+     */
+    public List<String> getKeepUninstalledPackages(@NonNull ComponentName admin) {
+        if (mService != null) {
+            try {
+                return mService.getKeepUninstalledPackages(admin);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Called by a device owner to set a list of apps to keep around as APKs even if no user has
+     * currently installed it.
+     *
+     * <p>Please note that setting this policy does not imply that specified apps will be
+     * automatically pre-cached.</p>
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageNames List of package names to keep cached.
+     * @hide
+     */
+    public void setKeepUninstalledPackages(@NonNull ComponentName admin,
+            @NonNull List<String> packageNames) {
+        if (mService != null) {
+            try {
+                mService.setKeepUninstalledPackages(admin, packageNames);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
      * Called by a device owner to create a user with the specified name. The UserHandle returned
      * by this method should not be persisted as user handles are recycled as users are removed and
      * created. If you need to persist an identifier for this user, use
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 7601cf2..283bf14 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -231,4 +231,6 @@
             String permission, int grantState);
     int getPermissionGrantState(in ComponentName admin, String packageName, String permission);
     boolean isProvisioningAllowed(String action);
+    void setKeepUninstalledPackages(in ComponentName admin,in List<String> packageList);
+    List<String> getKeepUninstalledPackages(in ComponentName admin);
 }
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index bf70d6c..905ac5e 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -16,7 +16,7 @@
 
 package android.content.pm;
 
-import android.annotation.NonNull;
+import java.util.List;
 
 /**
  * Package manager local system service interface.
@@ -115,4 +115,11 @@
      */
     public abstract void grantDefaultPermissionsToDefaultSimCallManager(String packageName,
             int userId);
+
+    /**
+     * Sets a list of apps to keep in PM's internal data structures and as APKs even if no user has
+     * currently installed it. The apps are not preloaded.
+     * @param packageList List of package names to keep cached.
+     */
+    public abstract void setKeepUninstalledPackages(List<String> packageList);
 }