diff --git a/services/api/current.txt b/services/api/current.txt index 45c00595841d9..30a70de007952 100644 --- a/services/api/current.txt +++ b/services/api/current.txt @@ -47,6 +47,9 @@ package com.android.server.am { package com.android.server.pm { public interface PackageManagerLocal { + method public void reconcileSdkData(@Nullable String, @NonNull String, @NonNull java.util.List, int, int, int, @NonNull String, int) throws java.io.IOException; + field public static final int FLAG_STORAGE_CE = 2; // 0x2 + field public static final int FLAG_STORAGE_DE = 1; // 0x1 } } diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java index 76b9830cbde90..5902f487d353a 100644 --- a/services/core/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java @@ -27,6 +27,7 @@ import android.os.CreateAppDataArgs; import android.os.CreateAppDataResult; import android.os.IBinder; import android.os.IInstalld; +import android.os.ReconcileSdkDataArgs; import android.os.RemoteException; import android.os.ServiceManager; import android.os.storage.CrateMetadata; @@ -215,6 +216,21 @@ public class Installer extends SystemService { return result; } + static ReconcileSdkDataArgs buildReconcileSdkDataArgs(String uuid, String packageName, + List subDirNames, int userId, int appId, + String seInfo, int flags) { + final ReconcileSdkDataArgs args = new ReconcileSdkDataArgs(); + args.uuid = uuid; + args.packageName = packageName; + args.subDirNames = subDirNames; + args.userId = userId; + args.appId = appId; + args.previousAppId = 0; + args.seInfo = seInfo; + args.flags = flags; + return args; + } + public @NonNull CreateAppDataResult createAppData(@NonNull CreateAppDataArgs args) throws InstallerException { if (!checkBeforeRemote()) { @@ -247,6 +263,18 @@ public class Installer extends SystemService { } } + void reconcileSdkData(@NonNull ReconcileSdkDataArgs args) + throws InstallerException { + if (!checkBeforeRemote()) { + return; + } + try { + mInstalld.reconcileSdkData(args); + } catch (Exception e) { + throw InstallerException.from(e); + } + } + /** * Class that collects multiple {@code installd} operations together in an * attempt to more efficiently execute them in bulk. diff --git a/services/core/java/com/android/server/pm/PackageManagerLocal.java b/services/core/java/com/android/server/pm/PackageManagerLocal.java index 7b76567fcc6e6..39cc37ea2e7c9 100644 --- a/services/core/java/com/android/server/pm/PackageManagerLocal.java +++ b/services/core/java/com/android/server/pm/PackageManagerLocal.java @@ -16,8 +16,16 @@ package com.android.server.pm; +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; +import java.io.IOException; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.List; + /** * In-process API for server side PackageManager related infrastructure. * @@ -28,4 +36,48 @@ import android.annotation.SystemApi; */ @SystemApi(client = SystemApi.Client.SYSTEM_SERVER) public interface PackageManagerLocal { + + /** + * Indicates if operation should include device encrypted storage. + */ + int FLAG_STORAGE_DE = Installer.FLAG_STORAGE_DE; + /** + * Indicates if operation should include credential encrypted storage. + */ + int FLAG_STORAGE_CE = Installer.FLAG_STORAGE_CE; + + /** + * Constants for use with {@link #reconcileSdkData} to specify which storage areas should be + * included for operation. + * + * @hide + */ + @IntDef(prefix = "FLAG_STORAGE_", value = { + FLAG_STORAGE_DE, + FLAG_STORAGE_CE, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface StorageFlags {} + + /** + * Reconcile sdk data sub-directories for the given {@code packagName}. + * + * Sub directories are created if they do not exist already. If there is an existing per- + * sdk directory that is missing from {@code subDirNames}, then it is removed. + * + * Sdk package path is created if it doesn't exist before creating per-sdk directories. + * + * @param volumeUuid the volume in which the sdk data should be prepared. + * @param packageName package name of the app for which sdk data directory will be prepared. + * @param subDirNames names of sub directories that should be reconciled against. + * @param userId id of the user to whom the package belongs to. + * @param appId id of the package. + * @param previousAppId previous id of the package if package is being updated. + * @param flags flags from StorageManager to indicate which storage areas should be included. + * @param seInfo seInfo tag to be used for selinux policy. + * @throws IOException If any error occurs during the operation. + */ + void reconcileSdkData(@Nullable String volumeUuid, @NonNull String packageName, + @NonNull List subDirNames, int userId, int appId, int previousAppId, + @NonNull String seInfo, @StorageFlags int flags) throws IOException; } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 99c9c689544d4..db3f7cc095b61 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -132,6 +132,7 @@ import android.os.Parcel; import android.os.ParcelableException; import android.os.PersistableBundle; import android.os.Process; +import android.os.ReconcileSdkDataArgs; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; @@ -6012,6 +6013,22 @@ public class PackageManagerService implements PackageSender, TestUtilityService } private class PackageManagerLocalImpl implements PackageManagerLocal { + @Override + public void reconcileSdkData(@Nullable String volumeUuid, @NonNull String packageName, + @NonNull List subDirNames, int userId, int appId, int previousAppId, + @NonNull String seInfo, int flags) throws IOException { + synchronized (mInstallLock) { + ReconcileSdkDataArgs args = mInstaller.buildReconcileSdkDataArgs(volumeUuid, + packageName, subDirNames, userId, appId, seInfo, + flags); + args.previousAppId = previousAppId; + try { + mInstaller.reconcileSdkData(args); + } catch (InstallerException e) { + throw new IOException(e.getMessage()); + } + } + } } private class PackageManagerInternalImpl extends PackageManagerInternalBase {