Loading core/java/android/os/incremental/IIncrementalService.aidl +19 −10 Original line number Diff line number Diff line Loading @@ -38,12 +38,18 @@ interface IIncrementalService { * Opens or creates a storage given a target path and data loader params. Returns the storage ID. */ int openStorage(in @utf8InCpp String path); int createStorage(in @utf8InCpp String path, in DataLoaderParamsParcel params, int createMode, int createStorage(in @utf8InCpp String path, in DataLoaderParamsParcel params, int createMode); int createLinkedStorage(in @utf8InCpp String path, int otherStorageId, int createMode); /** * Loops DataLoader through bind/create/start with params. */ boolean startLoading(int storageId, in DataLoaderParamsParcel params, in IDataLoaderStatusListener statusListener, in StorageHealthCheckParams healthCheckParams, in IStorageHealthListener healthListener, in PerUidReadTimeouts[] perUidReadTimeouts); int createLinkedStorage(in @utf8InCpp String path, int otherStorageId, int createMode); /** * Bind-mounts a path under a storage to a full path. Can be permanent or temporary. Loading Loading @@ -100,6 +106,14 @@ interface IIncrementalService { */ int isFileFullyLoaded(int storageId, in @utf8InCpp String path); /** * Checks if all files in the storage are fully loaded. * 0 - fully loaded * >0 - certain pages missing * <0 - -errcode */ int isFullyLoaded(int storageId); /** * Returns overall loading progress of all the files on a storage, progress value between [0,1]. * Returns a negative value on error. Loading @@ -112,11 +126,6 @@ interface IIncrementalService { byte[] getMetadataByPath(int storageId, in @utf8InCpp String path); byte[] getMetadataById(int storageId, in byte[] fileId); /** * Starts loading data for a storage. */ boolean startLoading(int storageId); /** * Deletes a storage given its ID. Deletes its bind mounts and unmount it. Stop its data loader. */ Loading core/java/android/os/incremental/IncrementalFileStorages.java +58 −33 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ import android.content.Context; import android.content.pm.DataLoaderParams; import android.content.pm.IDataLoaderStatusListener; import android.content.pm.InstallationFileParcel; import android.text.TextUtils; import java.io.File; import java.io.IOException; Loading @@ -53,6 +52,7 @@ public final class IncrementalFileStorages { private @NonNull final IncrementalManager mIncrementalManager; private @NonNull final File mStageDir; private @Nullable IncrementalStorage mInheritedStorage; private @Nullable IncrementalStorage mDefaultStorage; /** Loading @@ -65,6 +65,7 @@ public final class IncrementalFileStorages { */ public static IncrementalFileStorages initialize(Context context, @NonNull File stageDir, @Nullable File inheritedDir, @NonNull DataLoaderParams dataLoaderParams, @Nullable IDataLoaderStatusListener statusListener, @Nullable StorageHealthCheckParams healthCheckParams, Loading @@ -79,9 +80,8 @@ public final class IncrementalFileStorages { throw new IOException("Failed to obtain incrementalManager."); } final IncrementalFileStorages result = new IncrementalFileStorages(stageDir, incrementalManager, dataLoaderParams, statusListener, healthCheckParams, healthListener, perUidReadTimeouts); final IncrementalFileStorages result = new IncrementalFileStorages(stageDir, inheritedDir, incrementalManager, dataLoaderParams); for (InstallationFileParcel file : addedFiles) { if (file.location == LOCATION_DATA_APP) { try { Loading @@ -95,43 +95,46 @@ public final class IncrementalFileStorages { throw new IOException("Unknown file location: " + file.location); } } result.startLoading(); result.startLoading(dataLoaderParams, statusListener, healthCheckParams, healthListener, perUidReadTimeouts); return result; } private IncrementalFileStorages(@NonNull File stageDir, @Nullable File inheritedDir, @NonNull IncrementalManager incrementalManager, @NonNull DataLoaderParams dataLoaderParams, @Nullable IDataLoaderStatusListener statusListener, @Nullable StorageHealthCheckParams healthCheckParams, @Nullable IStorageHealthListener healthListener, @NonNull PerUidReadTimeouts[] perUidReadTimeouts) throws IOException { @NonNull DataLoaderParams dataLoaderParams) throws IOException { try { mStageDir = stageDir; mIncrementalManager = incrementalManager; if (dataLoaderParams.getComponentName().getPackageName().equals("local")) { final String incrementalPath = dataLoaderParams.getArguments(); if (TextUtils.isEmpty(incrementalPath)) { throw new IOException("Failed to create storage: incrementalPath is empty"); if (inheritedDir != null && IncrementalManager.isIncrementalPath( inheritedDir.getAbsolutePath())) { mInheritedStorage = mIncrementalManager.openStorage( inheritedDir.getAbsolutePath()); if (mInheritedStorage != null) { if (!mInheritedStorage.isFullyLoaded()) { throw new IOException("Inherited storage has missing pages."); } mDefaultStorage = mIncrementalManager.openStorage(incrementalPath); mDefaultStorage = mIncrementalManager.createStorage(stageDir.getAbsolutePath(), mInheritedStorage, IncrementalManager.CREATE_MODE_CREATE | IncrementalManager.CREATE_MODE_TEMPORARY_BIND); if (mDefaultStorage == null) { throw new IOException( "Couldn't open incremental storage at " + incrementalPath); "Couldn't create linked incremental storage at " + stageDir); } mDefaultStorage.bind(stageDir.getAbsolutePath()); } else { return; } } mDefaultStorage = mIncrementalManager.createStorage(stageDir.getAbsolutePath(), dataLoaderParams, IncrementalManager.CREATE_MODE_CREATE | IncrementalManager.CREATE_MODE_TEMPORARY_BIND, false, statusListener, healthCheckParams, healthListener, perUidReadTimeouts); | IncrementalManager.CREATE_MODE_TEMPORARY_BIND); if (mDefaultStorage == null) { throw new IOException( "Couldn't create incremental storage at " + stageDir); } } } catch (IOException e) { cleanUp(); throw e; Loading @@ -149,9 +152,16 @@ public final class IncrementalFileStorages { /** * Starts or re-starts loading of data. */ public void startLoading() throws IOException { if (!mDefaultStorage.startLoading()) { throw new IOException("Failed to start loading data for Incremental installation."); void startLoading( @NonNull DataLoaderParams dataLoaderParams, @Nullable IDataLoaderStatusListener statusListener, @Nullable StorageHealthCheckParams healthCheckParams, @Nullable IStorageHealthListener healthListener, @NonNull PerUidReadTimeouts[] perUidReadTimeouts) throws IOException { if (!mDefaultStorage.startLoading(dataLoaderParams, statusListener, healthCheckParams, healthListener, perUidReadTimeouts)) { throw new IOException( "Failed to start or restart loading data for Incremental installation."); } } Loading @@ -162,6 +172,21 @@ public final class IncrementalFileStorages { mDefaultStorage.makeFile(name, content.length, UUID.randomUUID(), null, null, content); } /** * Creates a hardlink from inherited storage to default. */ public boolean makeLink(@NonNull String relativePath, @NonNull String fromBase, @NonNull String toBase) throws IOException { if (mInheritedStorage == null) { return false; } final File sourcePath = new File(fromBase, relativePath); final File destPath = new File(toBase, relativePath); mInheritedStorage.makeLink(sourcePath.getAbsolutePath(), mDefaultStorage, destPath.getAbsolutePath()); return true; } /** * Permanently disables readlogs. */ Loading core/java/android/os/incremental/IncrementalManager.java +8 −18 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import android.annotation.Nullable; import android.annotation.SystemService; import android.content.Context; import android.content.pm.DataLoaderParams; import android.content.pm.IDataLoaderStatusListener; import android.content.pm.IPackageLoadingProgressCallback; import android.os.RemoteCallbackList; import android.os.RemoteException; Loading Loading @@ -95,32 +94,20 @@ public final class IncrementalManager { * @param params IncrementalDataLoaderParams object to configure data loading. * @param createMode Mode for opening an old Incremental File System mount or creating * a new mount. * @param autoStartDataLoader Set true to immediately start data loader after creating storage. * @return IncrementalStorage object corresponding to the mounted directory. */ @Nullable public IncrementalStorage createStorage(@NonNull String path, @NonNull DataLoaderParams params, @CreateMode int createMode, boolean autoStartDataLoader, @Nullable IDataLoaderStatusListener statusListener, @Nullable StorageHealthCheckParams healthCheckParams, @Nullable IStorageHealthListener healthListener, @NonNull PerUidReadTimeouts[] perUidReadTimeouts) { @CreateMode int createMode) { Objects.requireNonNull(path); Objects.requireNonNull(params); Objects.requireNonNull(perUidReadTimeouts); try { final int id = mService.createStorage(path, params.getData(), createMode, statusListener, healthCheckParams, healthListener, perUidReadTimeouts); final int id = mService.createStorage(path, params.getData(), createMode); if (id < 0) { return null; } final IncrementalStorage storage = new IncrementalStorage(mService, id); if (autoStartDataLoader) { storage.startLoading(); } return storage; return new IncrementalStorage(mService, id); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading Loading @@ -281,15 +268,18 @@ public final class IncrementalManager { * Unbinds the target dir and deletes the corresponding storage instance. * Deletes the package name and associated storage id from maps. */ public void onPackageRemoved(@NonNull String codePath) { public void onPackageRemoved(@NonNull File codeFile) { try { final String codePath = codeFile.getAbsolutePath(); final IncrementalStorage storage = openStorage(codePath); if (storage == null) { return; } mLoadingProgressCallbacks.cleanUpCallbacks(storage); unregisterHealthListener(codePath); mService.deleteStorage(storage.getId()); // Parent since we bind-mount a folder one level above. mService.deleteBindMount(storage.getId(), codeFile.getParent()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading core/java/android/os/incremental/IncrementalStorage.java +34 −5 Original line number Diff line number Diff line Loading @@ -18,11 +18,14 @@ package android.os.incremental; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.pm.DataLoaderParams; import android.content.pm.IDataLoaderStatusListener; import android.os.RemoteException; import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; import java.util.Objects; import java.util.UUID; /** Loading Loading @@ -323,6 +326,24 @@ public final class IncrementalStorage { } } /** * Checks if all files in the storage are fully loaded. */ public boolean isFullyLoaded() throws IOException { try { final int res = mService.isFullyLoaded(mId); if (res < 0) { throw new IOException( "isFullyLoaded() failed at querying loading progress, errno " + -res); } return res == 0; } catch (RemoteException e) { e.rethrowFromSystemServer(); return false; } } /** * Returns the loading progress of a storage * Loading Loading @@ -376,13 +397,21 @@ public final class IncrementalStorage { } /** * Informs the data loader service associated with the current storage to start data loader * * @return True if data loader is successfully started. * Iinitializes and starts the DataLoader. * This makes sure all install-time parameters are applied. * Does not affect persistent DataLoader params. * @return True if start request was successfully queued. */ public boolean startLoading() { public boolean startLoading( @NonNull DataLoaderParams dataLoaderParams, @Nullable IDataLoaderStatusListener statusListener, @Nullable StorageHealthCheckParams healthCheckParams, @Nullable IStorageHealthListener healthListener, @NonNull PerUidReadTimeouts[] perUidReadTimeouts) { Objects.requireNonNull(perUidReadTimeouts); try { return mService.startLoading(mId); return mService.startLoading(mId, dataLoaderParams.getData(), statusListener, healthCheckParams, healthListener, perUidReadTimeouts); } catch (RemoteException e) { e.rethrowFromSystemServer(); return false; Loading services/core/java/com/android/server/pm/PackageInstallerSession.java +26 −15 Original line number Diff line number Diff line Loading @@ -3299,17 +3299,28 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } private void linkFile(String relativePath, String fromBase, String toBase) throws IOException { try { // Try if (mIncrementalFileStorages != null && mIncrementalFileStorages.makeLink(relativePath, fromBase, toBase)) { return; } mPm.mInstaller.linkFile(relativePath, fromBase, toBase); } catch (InstallerException | IOException e) { throw new IOException("failed linkOrCreateDir(" + relativePath + ", " + fromBase + ", " + toBase + ")", e); } } private void linkFiles(List<File> fromFiles, File toDir, File fromDir) throws IOException { for (File fromFile : fromFiles) { final String relativePath = getRelativePath(fromFile, fromDir); try { mPm.mInstaller.linkFile(relativePath, fromDir.getAbsolutePath(), toDir.getAbsolutePath()); } catch (InstallerException e) { throw new IOException("failed linkOrCreateDir(" + relativePath + ", " + fromDir + ", " + toDir + ")", e); } final String fromBase = fromDir.getAbsolutePath(); final String toBase = toDir.getAbsolutePath(); linkFile(relativePath, fromBase, toBase); } Slog.d(TAG, "Linked " + fromFiles.size() + " files into " + toDir); Loading Loading @@ -3577,12 +3588,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // Retrying commit. if (mIncrementalFileStorages != null) { try { mIncrementalFileStorages.startLoading(); } catch (IOException e) { throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE, e.getMessage(), e.getCause()); } return false; } Loading Loading @@ -3757,9 +3762,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { }; try { final PackageInfo pkgInfo = mPm.getPackageInfo(this.params.appPackageName, 0, userId); final File inheritedDir = (pkgInfo != null && pkgInfo.applicationInfo != null) ? new File( pkgInfo.applicationInfo.getCodePath()).getParentFile() : null; mIncrementalFileStorages = IncrementalFileStorages.initialize(mContext, stageDir, params, statusListener, healthCheckParams, healthListener, addedFiles, perUidReadTimeouts); inheritedDir, params, statusListener, healthCheckParams, healthListener, addedFiles, perUidReadTimeouts); return false; } catch (IOException e) { throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE, e.getMessage(), Loading Loading
core/java/android/os/incremental/IIncrementalService.aidl +19 −10 Original line number Diff line number Diff line Loading @@ -38,12 +38,18 @@ interface IIncrementalService { * Opens or creates a storage given a target path and data loader params. Returns the storage ID. */ int openStorage(in @utf8InCpp String path); int createStorage(in @utf8InCpp String path, in DataLoaderParamsParcel params, int createMode, int createStorage(in @utf8InCpp String path, in DataLoaderParamsParcel params, int createMode); int createLinkedStorage(in @utf8InCpp String path, int otherStorageId, int createMode); /** * Loops DataLoader through bind/create/start with params. */ boolean startLoading(int storageId, in DataLoaderParamsParcel params, in IDataLoaderStatusListener statusListener, in StorageHealthCheckParams healthCheckParams, in IStorageHealthListener healthListener, in PerUidReadTimeouts[] perUidReadTimeouts); int createLinkedStorage(in @utf8InCpp String path, int otherStorageId, int createMode); /** * Bind-mounts a path under a storage to a full path. Can be permanent or temporary. Loading Loading @@ -100,6 +106,14 @@ interface IIncrementalService { */ int isFileFullyLoaded(int storageId, in @utf8InCpp String path); /** * Checks if all files in the storage are fully loaded. * 0 - fully loaded * >0 - certain pages missing * <0 - -errcode */ int isFullyLoaded(int storageId); /** * Returns overall loading progress of all the files on a storage, progress value between [0,1]. * Returns a negative value on error. Loading @@ -112,11 +126,6 @@ interface IIncrementalService { byte[] getMetadataByPath(int storageId, in @utf8InCpp String path); byte[] getMetadataById(int storageId, in byte[] fileId); /** * Starts loading data for a storage. */ boolean startLoading(int storageId); /** * Deletes a storage given its ID. Deletes its bind mounts and unmount it. Stop its data loader. */ Loading
core/java/android/os/incremental/IncrementalFileStorages.java +58 −33 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ import android.content.Context; import android.content.pm.DataLoaderParams; import android.content.pm.IDataLoaderStatusListener; import android.content.pm.InstallationFileParcel; import android.text.TextUtils; import java.io.File; import java.io.IOException; Loading @@ -53,6 +52,7 @@ public final class IncrementalFileStorages { private @NonNull final IncrementalManager mIncrementalManager; private @NonNull final File mStageDir; private @Nullable IncrementalStorage mInheritedStorage; private @Nullable IncrementalStorage mDefaultStorage; /** Loading @@ -65,6 +65,7 @@ public final class IncrementalFileStorages { */ public static IncrementalFileStorages initialize(Context context, @NonNull File stageDir, @Nullable File inheritedDir, @NonNull DataLoaderParams dataLoaderParams, @Nullable IDataLoaderStatusListener statusListener, @Nullable StorageHealthCheckParams healthCheckParams, Loading @@ -79,9 +80,8 @@ public final class IncrementalFileStorages { throw new IOException("Failed to obtain incrementalManager."); } final IncrementalFileStorages result = new IncrementalFileStorages(stageDir, incrementalManager, dataLoaderParams, statusListener, healthCheckParams, healthListener, perUidReadTimeouts); final IncrementalFileStorages result = new IncrementalFileStorages(stageDir, inheritedDir, incrementalManager, dataLoaderParams); for (InstallationFileParcel file : addedFiles) { if (file.location == LOCATION_DATA_APP) { try { Loading @@ -95,43 +95,46 @@ public final class IncrementalFileStorages { throw new IOException("Unknown file location: " + file.location); } } result.startLoading(); result.startLoading(dataLoaderParams, statusListener, healthCheckParams, healthListener, perUidReadTimeouts); return result; } private IncrementalFileStorages(@NonNull File stageDir, @Nullable File inheritedDir, @NonNull IncrementalManager incrementalManager, @NonNull DataLoaderParams dataLoaderParams, @Nullable IDataLoaderStatusListener statusListener, @Nullable StorageHealthCheckParams healthCheckParams, @Nullable IStorageHealthListener healthListener, @NonNull PerUidReadTimeouts[] perUidReadTimeouts) throws IOException { @NonNull DataLoaderParams dataLoaderParams) throws IOException { try { mStageDir = stageDir; mIncrementalManager = incrementalManager; if (dataLoaderParams.getComponentName().getPackageName().equals("local")) { final String incrementalPath = dataLoaderParams.getArguments(); if (TextUtils.isEmpty(incrementalPath)) { throw new IOException("Failed to create storage: incrementalPath is empty"); if (inheritedDir != null && IncrementalManager.isIncrementalPath( inheritedDir.getAbsolutePath())) { mInheritedStorage = mIncrementalManager.openStorage( inheritedDir.getAbsolutePath()); if (mInheritedStorage != null) { if (!mInheritedStorage.isFullyLoaded()) { throw new IOException("Inherited storage has missing pages."); } mDefaultStorage = mIncrementalManager.openStorage(incrementalPath); mDefaultStorage = mIncrementalManager.createStorage(stageDir.getAbsolutePath(), mInheritedStorage, IncrementalManager.CREATE_MODE_CREATE | IncrementalManager.CREATE_MODE_TEMPORARY_BIND); if (mDefaultStorage == null) { throw new IOException( "Couldn't open incremental storage at " + incrementalPath); "Couldn't create linked incremental storage at " + stageDir); } mDefaultStorage.bind(stageDir.getAbsolutePath()); } else { return; } } mDefaultStorage = mIncrementalManager.createStorage(stageDir.getAbsolutePath(), dataLoaderParams, IncrementalManager.CREATE_MODE_CREATE | IncrementalManager.CREATE_MODE_TEMPORARY_BIND, false, statusListener, healthCheckParams, healthListener, perUidReadTimeouts); | IncrementalManager.CREATE_MODE_TEMPORARY_BIND); if (mDefaultStorage == null) { throw new IOException( "Couldn't create incremental storage at " + stageDir); } } } catch (IOException e) { cleanUp(); throw e; Loading @@ -149,9 +152,16 @@ public final class IncrementalFileStorages { /** * Starts or re-starts loading of data. */ public void startLoading() throws IOException { if (!mDefaultStorage.startLoading()) { throw new IOException("Failed to start loading data for Incremental installation."); void startLoading( @NonNull DataLoaderParams dataLoaderParams, @Nullable IDataLoaderStatusListener statusListener, @Nullable StorageHealthCheckParams healthCheckParams, @Nullable IStorageHealthListener healthListener, @NonNull PerUidReadTimeouts[] perUidReadTimeouts) throws IOException { if (!mDefaultStorage.startLoading(dataLoaderParams, statusListener, healthCheckParams, healthListener, perUidReadTimeouts)) { throw new IOException( "Failed to start or restart loading data for Incremental installation."); } } Loading @@ -162,6 +172,21 @@ public final class IncrementalFileStorages { mDefaultStorage.makeFile(name, content.length, UUID.randomUUID(), null, null, content); } /** * Creates a hardlink from inherited storage to default. */ public boolean makeLink(@NonNull String relativePath, @NonNull String fromBase, @NonNull String toBase) throws IOException { if (mInheritedStorage == null) { return false; } final File sourcePath = new File(fromBase, relativePath); final File destPath = new File(toBase, relativePath); mInheritedStorage.makeLink(sourcePath.getAbsolutePath(), mDefaultStorage, destPath.getAbsolutePath()); return true; } /** * Permanently disables readlogs. */ Loading
core/java/android/os/incremental/IncrementalManager.java +8 −18 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import android.annotation.Nullable; import android.annotation.SystemService; import android.content.Context; import android.content.pm.DataLoaderParams; import android.content.pm.IDataLoaderStatusListener; import android.content.pm.IPackageLoadingProgressCallback; import android.os.RemoteCallbackList; import android.os.RemoteException; Loading Loading @@ -95,32 +94,20 @@ public final class IncrementalManager { * @param params IncrementalDataLoaderParams object to configure data loading. * @param createMode Mode for opening an old Incremental File System mount or creating * a new mount. * @param autoStartDataLoader Set true to immediately start data loader after creating storage. * @return IncrementalStorage object corresponding to the mounted directory. */ @Nullable public IncrementalStorage createStorage(@NonNull String path, @NonNull DataLoaderParams params, @CreateMode int createMode, boolean autoStartDataLoader, @Nullable IDataLoaderStatusListener statusListener, @Nullable StorageHealthCheckParams healthCheckParams, @Nullable IStorageHealthListener healthListener, @NonNull PerUidReadTimeouts[] perUidReadTimeouts) { @CreateMode int createMode) { Objects.requireNonNull(path); Objects.requireNonNull(params); Objects.requireNonNull(perUidReadTimeouts); try { final int id = mService.createStorage(path, params.getData(), createMode, statusListener, healthCheckParams, healthListener, perUidReadTimeouts); final int id = mService.createStorage(path, params.getData(), createMode); if (id < 0) { return null; } final IncrementalStorage storage = new IncrementalStorage(mService, id); if (autoStartDataLoader) { storage.startLoading(); } return storage; return new IncrementalStorage(mService, id); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading Loading @@ -281,15 +268,18 @@ public final class IncrementalManager { * Unbinds the target dir and deletes the corresponding storage instance. * Deletes the package name and associated storage id from maps. */ public void onPackageRemoved(@NonNull String codePath) { public void onPackageRemoved(@NonNull File codeFile) { try { final String codePath = codeFile.getAbsolutePath(); final IncrementalStorage storage = openStorage(codePath); if (storage == null) { return; } mLoadingProgressCallbacks.cleanUpCallbacks(storage); unregisterHealthListener(codePath); mService.deleteStorage(storage.getId()); // Parent since we bind-mount a folder one level above. mService.deleteBindMount(storage.getId(), codeFile.getParent()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading
core/java/android/os/incremental/IncrementalStorage.java +34 −5 Original line number Diff line number Diff line Loading @@ -18,11 +18,14 @@ package android.os.incremental; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.pm.DataLoaderParams; import android.content.pm.IDataLoaderStatusListener; import android.os.RemoteException; import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; import java.util.Objects; import java.util.UUID; /** Loading Loading @@ -323,6 +326,24 @@ public final class IncrementalStorage { } } /** * Checks if all files in the storage are fully loaded. */ public boolean isFullyLoaded() throws IOException { try { final int res = mService.isFullyLoaded(mId); if (res < 0) { throw new IOException( "isFullyLoaded() failed at querying loading progress, errno " + -res); } return res == 0; } catch (RemoteException e) { e.rethrowFromSystemServer(); return false; } } /** * Returns the loading progress of a storage * Loading Loading @@ -376,13 +397,21 @@ public final class IncrementalStorage { } /** * Informs the data loader service associated with the current storage to start data loader * * @return True if data loader is successfully started. * Iinitializes and starts the DataLoader. * This makes sure all install-time parameters are applied. * Does not affect persistent DataLoader params. * @return True if start request was successfully queued. */ public boolean startLoading() { public boolean startLoading( @NonNull DataLoaderParams dataLoaderParams, @Nullable IDataLoaderStatusListener statusListener, @Nullable StorageHealthCheckParams healthCheckParams, @Nullable IStorageHealthListener healthListener, @NonNull PerUidReadTimeouts[] perUidReadTimeouts) { Objects.requireNonNull(perUidReadTimeouts); try { return mService.startLoading(mId); return mService.startLoading(mId, dataLoaderParams.getData(), statusListener, healthCheckParams, healthListener, perUidReadTimeouts); } catch (RemoteException e) { e.rethrowFromSystemServer(); return false; Loading
services/core/java/com/android/server/pm/PackageInstallerSession.java +26 −15 Original line number Diff line number Diff line Loading @@ -3299,17 +3299,28 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } private void linkFile(String relativePath, String fromBase, String toBase) throws IOException { try { // Try if (mIncrementalFileStorages != null && mIncrementalFileStorages.makeLink(relativePath, fromBase, toBase)) { return; } mPm.mInstaller.linkFile(relativePath, fromBase, toBase); } catch (InstallerException | IOException e) { throw new IOException("failed linkOrCreateDir(" + relativePath + ", " + fromBase + ", " + toBase + ")", e); } } private void linkFiles(List<File> fromFiles, File toDir, File fromDir) throws IOException { for (File fromFile : fromFiles) { final String relativePath = getRelativePath(fromFile, fromDir); try { mPm.mInstaller.linkFile(relativePath, fromDir.getAbsolutePath(), toDir.getAbsolutePath()); } catch (InstallerException e) { throw new IOException("failed linkOrCreateDir(" + relativePath + ", " + fromDir + ", " + toDir + ")", e); } final String fromBase = fromDir.getAbsolutePath(); final String toBase = toDir.getAbsolutePath(); linkFile(relativePath, fromBase, toBase); } Slog.d(TAG, "Linked " + fromFiles.size() + " files into " + toDir); Loading Loading @@ -3577,12 +3588,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // Retrying commit. if (mIncrementalFileStorages != null) { try { mIncrementalFileStorages.startLoading(); } catch (IOException e) { throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE, e.getMessage(), e.getCause()); } return false; } Loading Loading @@ -3757,9 +3762,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { }; try { final PackageInfo pkgInfo = mPm.getPackageInfo(this.params.appPackageName, 0, userId); final File inheritedDir = (pkgInfo != null && pkgInfo.applicationInfo != null) ? new File( pkgInfo.applicationInfo.getCodePath()).getParentFile() : null; mIncrementalFileStorages = IncrementalFileStorages.initialize(mContext, stageDir, params, statusListener, healthCheckParams, healthListener, addedFiles, perUidReadTimeouts); inheritedDir, params, statusListener, healthCheckParams, healthListener, addedFiles, perUidReadTimeouts); return false; } catch (IOException e) { throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE, e.getMessage(), Loading