Migrating Incremental* APIs to PackageManager APIs.
Step 2, merging Data Loader params.
Test: builds and flashes
Bug: b/136132412
Change-Id: I2102554316dadcdcb49790c133ece110c43c29b3
diff --git a/core/java/android/content/pm/DataLoaderParams.java b/core/java/android/content/pm/DataLoaderParams.java
index af4b99a..60d7bb3 100644
--- a/core/java/android/content/pm/DataLoaderParams.java
+++ b/core/java/android/content/pm/DataLoaderParams.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.content.ComponentName;
import android.os.ParcelFileDescriptor;
import java.util.Arrays;
@@ -26,7 +27,7 @@
import java.util.stream.Collectors;
/**
- * This class represents the parameters used to configure an Incremental Data Loader.
+ * This class represents the parameters used to configure a Data Loader.
*
* WARNING: This is a system API to aid internal development.
* Use at your own risk. It will change or be removed without warning.
@@ -34,13 +35,41 @@
*/
@SystemApi
public class DataLoaderParams {
- @NonNull private final DataLoaderParamsParcel mData;
+ @NonNull
+ private final DataLoaderParamsParcel mData;
- public DataLoaderParams(@NonNull String url, @NonNull String packageName,
+ /**
+ * Creates and populates set of Data Loader parameters for Streaming installation.
+ *
+ * @param componentName Data Loader component supporting Streaming installation.
+ * @param arguments free form installation arguments
+ */
+ public static final @NonNull DataLoaderParams forStreaming(@NonNull ComponentName componentName,
+ @NonNull String arguments) {
+ return new DataLoaderParams(DataLoaderType.STREAMING, componentName, arguments, null);
+ }
+
+ /**
+ * Creates and populates set of Data Loader parameters for Incremental installation.
+ *
+ * @param componentName Data Loader component supporting Incremental installation.
+ * @param arguments free form installation arguments
+ * @param namedFds TODO(b/146080380) remove
+ */
+ public static final @NonNull DataLoaderParams forIncremental(
+ @NonNull ComponentName componentName, @NonNull String arguments,
@Nullable Map<String, ParcelFileDescriptor> namedFds) {
+ return new DataLoaderParams(DataLoaderType.INCREMENTAL, componentName, arguments, namedFds);
+ }
+
+ /** @hide */
+ public DataLoaderParams(@NonNull @DataLoaderType int type, @NonNull ComponentName componentName,
+ @NonNull String arguments, @Nullable Map<String, ParcelFileDescriptor> namedFds) {
DataLoaderParamsParcel data = new DataLoaderParamsParcel();
- data.staticArgs = url;
- data.packageName = packageName;
+ data.type = type;
+ data.packageName = componentName.getPackageName();
+ data.className = componentName.getClassName();
+ data.arguments = arguments;
if (namedFds == null || namedFds.isEmpty()) {
data.dynamicArgs = new NamedParcelFileDescriptor[0];
} else {
@@ -56,39 +85,42 @@
mData = data;
}
- /**
- * @hide
- */
- public DataLoaderParams(@NonNull DataLoaderParamsParcel data) {
+ /** @hide */
+ DataLoaderParams(@NonNull DataLoaderParamsParcel data) {
mData = data;
}
- /**
- * @return static server's URL
- */
- public final @NonNull String getStaticArgs() {
- return mData.staticArgs;
- }
-
- /**
- * @return data loader's package name
- */
- public final @NonNull String getPackageName() {
- return mData.packageName;
- }
-
- /**
- * @hide
- */
+ /** @hide */
public final @NonNull DataLoaderParamsParcel getData() {
return mData;
}
/**
- * @return data loader's dynamic arguments such as file descriptors
+ * @return data loader type
+ */
+ public final @NonNull @DataLoaderType int getType() {
+ return mData.type;
+ }
+
+ /**
+ * @return data loader's component name
+ */
+ public final @NonNull ComponentName getComponentName() {
+ return new ComponentName(mData.packageName, mData.className);
+ }
+
+ /**
+ * @return data loader's arguments
+ */
+ public final @NonNull String getArguments() {
+ return mData.arguments;
+ }
+
+ /**
+ * @return data loader's dynamic arguments such as file descriptors TODO: remove
*/
public final @NonNull Map<String, ParcelFileDescriptor> getDynamicArgs() {
return Arrays.stream(mData.dynamicArgs).collect(
- Collectors.toMap(p->p.name, p->p.fd));
+ Collectors.toMap(p -> p.name, p -> p.fd));
}
}
diff --git a/core/java/android/content/pm/DataLoaderParamsParcel.aidl b/core/java/android/content/pm/DataLoaderParamsParcel.aidl
index 3316398..e05843b 100644
--- a/core/java/android/content/pm/DataLoaderParamsParcel.aidl
+++ b/core/java/android/content/pm/DataLoaderParamsParcel.aidl
@@ -16,6 +16,7 @@
package android.content.pm;
+import android.content.pm.DataLoaderType;
import android.content.pm.NamedParcelFileDescriptor;
/**
@@ -23,7 +24,9 @@
* @hide
*/
parcelable DataLoaderParamsParcel {
+ DataLoaderType type;
@utf8InCpp String packageName;
- @utf8InCpp String staticArgs;
+ @utf8InCpp String className;
+ @utf8InCpp String arguments;
NamedParcelFileDescriptor[] dynamicArgs;
}
diff --git a/core/java/android/content/pm/DataLoaderType.aidl b/core/java/android/content/pm/DataLoaderType.aidl
new file mode 100644
index 0000000..7d726f5
--- /dev/null
+++ b/core/java/android/content/pm/DataLoaderType.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+/**
+ * Types of Data Loader for an installation session.
+ * @hide
+ */
+@Backing(type="int")
+enum DataLoaderType {
+ /**
+ * Default value, legacy installation.
+ */
+ NONE = 0,
+ /**
+ * Streaming installation using data loader.
+ */
+ STREAMING = 1,
+ /**
+ * Streaming installation using Incremental FileSystem.
+ */
+ INCREMENTAL = 2,
+}
diff --git a/core/java/android/content/pm/IDataLoader.aidl b/core/java/android/content/pm/IDataLoader.aidl
index c65bd6a..b5baa93 100644
--- a/core/java/android/content/pm/IDataLoader.aidl
+++ b/core/java/android/content/pm/IDataLoader.aidl
@@ -27,7 +27,9 @@
*/
oneway interface IDataLoader {
void create(int id, in Bundle params, IDataLoaderStatusListener listener);
- void start(in List<InstallationFile> fileInfos);
+ void start();
void stop();
void destroy();
+
+ void prepareImage(in List<InstallationFile> addedFiles, in List<String> removedFiles);
}
diff --git a/core/java/android/content/pm/IDataLoaderStatusListener.aidl b/core/java/android/content/pm/IDataLoaderStatusListener.aidl
index a60d6ee..5011faa 100644
--- a/core/java/android/content/pm/IDataLoaderStatusListener.aidl
+++ b/core/java/android/content/pm/IDataLoaderStatusListener.aidl
@@ -22,13 +22,18 @@
*/
oneway interface IDataLoaderStatusListener {
/** Data loader status */
- const int DATA_LOADER_READY = 0;
- const int DATA_LOADER_NOT_READY = 1;
- const int DATA_LOADER_RUNNING = 2;
+ const int DATA_LOADER_CREATED = 0;
+ const int DATA_LOADER_DESTROYED = 1;
+
+ const int DATA_LOADER_STARTED = 2;
const int DATA_LOADER_STOPPED = 3;
- const int DATA_LOADER_SLOW_CONNECTION = 4;
- const int DATA_LOADER_NO_CONNECTION = 5;
- const int DATA_LOADER_CONNECTION_OK = 6;
+
+ const int DATA_LOADER_IMAGE_READY = 4;
+ const int DATA_LOADER_IMAGE_NOT_READY = 5;
+
+ const int DATA_LOADER_SLOW_CONNECTION = 6;
+ const int DATA_LOADER_NO_CONNECTION = 7;
+ const int DATA_LOADER_CONNECTION_OK = 8;
/** Data loader status callback */
void onStatusChanged(in int dataLoaderId, in int status);
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 3d6d849..e4a0bc0 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1461,10 +1461,7 @@
/** {@hide} */
public long requiredInstalledVersionCode = PackageManager.VERSION_CODE_HIGHEST;
/** {@hide} */
- public DataLoaderParams incrementalParams;
- /** TODO(b/146080380): add a class name to make it fully compatible with ComponentName.
- * {@hide} */
- public String dataLoaderPackageName;
+ public DataLoaderParams dataLoaderParams;
/** {@hide} */
public int rollbackDataPolicy = PackageManager.RollbackDataPolicy.RESTORE;
@@ -1503,10 +1500,8 @@
DataLoaderParamsParcel dataLoaderParamsParcel = source.readParcelable(
DataLoaderParamsParcel.class.getClassLoader());
if (dataLoaderParamsParcel != null) {
- incrementalParams = new DataLoaderParams(
- dataLoaderParamsParcel);
+ dataLoaderParams = new DataLoaderParams(dataLoaderParamsParcel);
}
- dataLoaderPackageName = source.readString();
rollbackDataPolicy = source.readInt();
}
@@ -1531,8 +1526,7 @@
ret.isMultiPackage = isMultiPackage;
ret.isStaged = isStaged;
ret.requiredInstalledVersionCode = requiredInstalledVersionCode;
- ret.incrementalParams = incrementalParams;
- ret.dataLoaderPackageName = dataLoaderPackageName;
+ ret.dataLoaderParams = dataLoaderParams;
ret.rollbackDataPolicy = rollbackDataPolicy;
return ret;
}
@@ -1893,29 +1887,18 @@
}
/**
- * Set Incremental data loader params.
+ * Set the data loader params for the session.
+ * This also switches installation into data provider mode and disallow direct writes into
+ * staging folder.
+ *
* WARNING: This is a system API to aid internal development.
* Use at your own risk. It will change or be removed without warning.
* {@hide}
*/
@SystemApi
@RequiresPermission(Manifest.permission.INSTALL_PACKAGES)
- public void setIncrementalParams(@NonNull DataLoaderParams incrementalParams) {
- this.incrementalParams = incrementalParams;
- }
-
- /**
- * Set the data provider params for the session.
- * This also switches installation into callback mode and disallow direct writes into
- * staging folder.
- * TODO(b/146080380): unify dataprovider params with Incremental.
- *
- * @param dataLoaderPackageName name of the dataLoader package
- * {@hide}
- */
- @RequiresPermission(Manifest.permission.INSTALL_PACKAGES)
- public void setDataLoaderPackageName(String dataLoaderPackageName) {
- this.dataLoaderPackageName = dataLoaderPackageName;
+ public void setDataLoaderParams(@NonNull DataLoaderParams dataLoaderParams) {
+ this.dataLoaderParams = dataLoaderParams;
}
/** {@hide} */
@@ -1938,7 +1921,7 @@
pw.printPair("isMultiPackage", isMultiPackage);
pw.printPair("isStaged", isStaged);
pw.printPair("requiredInstalledVersionCode", requiredInstalledVersionCode);
- pw.printPair("dataLoaderPackageName", dataLoaderPackageName);
+ pw.printPair("dataLoaderParams", dataLoaderParams);
pw.printPair("rollbackDataPolicy", rollbackDataPolicy);
pw.println();
}
@@ -1969,12 +1952,11 @@
dest.writeBoolean(isMultiPackage);
dest.writeBoolean(isStaged);
dest.writeLong(requiredInstalledVersionCode);
- if (incrementalParams != null) {
- dest.writeParcelable(incrementalParams.getData(), flags);
+ if (dataLoaderParams != null) {
+ dest.writeParcelable(dataLoaderParams.getData(), flags);
} else {
dest.writeParcelable(null, flags);
}
- dest.writeString(dataLoaderPackageName);
dest.writeInt(rollbackDataPolicy);
}
diff --git a/core/java/android/os/incremental/IncrementalFileStorages.java b/core/java/android/os/incremental/IncrementalFileStorages.java
index fb94fc9..2138d553 100644
--- a/core/java/android/os/incremental/IncrementalFileStorages.java
+++ b/core/java/android/os/incremental/IncrementalFileStorages.java
@@ -87,8 +87,8 @@
mPackageName = packageName;
mStageDir = stageDir;
mIncrementalManager = incrementalManager;
- if (dataLoaderParams.getPackageName().equals("local")) {
- final String incrementalPath = dataLoaderParams.getStaticArgs();
+ if (dataLoaderParams.getComponentName().getPackageName().equals("local")) {
+ final String incrementalPath = dataLoaderParams.getArguments();
mDefaultStorage = mIncrementalManager.openStorage(incrementalPath);
mDefaultDir = incrementalPath;
return;
diff --git a/core/java/android/service/dataloader/DataLoaderService.java b/core/java/android/service/dataloader/DataLoaderService.java
index 54a4fa6..75f252e 100644
--- a/core/java/android/service/dataloader/DataLoaderService.java
+++ b/core/java/android/service/dataloader/DataLoaderService.java
@@ -16,7 +16,6 @@
package android.service.dataloader;
-import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -27,19 +26,16 @@
import android.content.pm.FileSystemControlParcel;
import android.content.pm.IDataLoader;
import android.content.pm.IDataLoaderStatusListener;
-import android.content.pm.IPackageInstallerSessionFileSystemConnector;
import android.content.pm.InstallationFile;
import android.content.pm.NamedParcelFileDescriptor;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
import android.util.ExceptionUtils;
import android.util.Slog;
import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
+import java.util.Collection;
import java.util.List;
/**
@@ -55,88 +51,35 @@
*/
@SystemApi
public abstract class DataLoaderService extends Service {
- private static final String TAG = "IncrementalDataLoaderService";
+ private static final String TAG = "DataLoaderService";
private final DataLoaderBinderService mBinder = new DataLoaderBinderService();
- /** @hide */
- public static final int DATA_LOADER_READY =
- IDataLoaderStatusListener.DATA_LOADER_READY;
- /** @hide */
- public static final int DATA_LOADER_NOT_READY =
- IDataLoaderStatusListener.DATA_LOADER_NOT_READY;
- /** @hide */
- public static final int DATA_LOADER_RUNNING =
- IDataLoaderStatusListener.DATA_LOADER_RUNNING;
- /** @hide */
- public static final int DATA_LOADER_STOPPED =
- IDataLoaderStatusListener.DATA_LOADER_STOPPED;
- /** @hide */
- public static final int DATA_LOADER_SLOW_CONNECTION =
- IDataLoaderStatusListener.DATA_LOADER_SLOW_CONNECTION;
- /** @hide */
- public static final int DATA_LOADER_NO_CONNECTION =
- IDataLoaderStatusListener.DATA_LOADER_NO_CONNECTION;
- /** @hide */
- public static final int DATA_LOADER_CONNECTION_OK =
- IDataLoaderStatusListener.DATA_LOADER_CONNECTION_OK;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"DATA_LOADER_"}, value = {
- DATA_LOADER_READY,
- DATA_LOADER_NOT_READY,
- DATA_LOADER_RUNNING,
- DATA_LOADER_STOPPED,
- DATA_LOADER_SLOW_CONNECTION,
- DATA_LOADER_NO_CONNECTION,
- DATA_LOADER_CONNECTION_OK
- })
- public @interface DataLoaderStatus {
- }
-
/**
- * Managed DataLoader interface. Each instance corresponds to a single Incremental File System
- * instance.
+ * Managed DataLoader interface. Each instance corresponds to a single installation session.
* @hide
*/
- public abstract static class DataLoader {
+ public interface DataLoader {
/**
- * A virtual constructor used to do simple initialization. Not ready to serve any data yet.
- * All heavy-lifting has to be done in onStart.
+ * A virtual constructor.
*
- * @param params Data loader configuration parameters.
- * @param connector IncFS API wrapper.
- * @param listener Used for reporting internal state to IncrementalService.
+ * @param dataLoaderParams parameters set in the installation session
+ * @param connector FS API wrapper
* @return True if initialization of a Data Loader was successful. False will be reported to
- * IncrementalService and can cause an unmount of an IFS instance.
+ * PackageManager and fail the installation
*/
- public abstract boolean onCreate(@NonNull DataLoaderParams params,
- @NonNull FileSystemConnector connector,
- @NonNull StatusListener listener);
+ boolean onCreate(@NonNull DataLoaderParams dataLoaderParams,
+ @NonNull FileSystemConnector connector);
/**
- * Start the data loader. After this method returns data loader is considered to be ready to
- * receive callbacks from IFS, supply data via connector and send status updates via
- * callbacks.
+ * Prepare installation image. After this method succeeds installer will validate the files
+ * and continue installation.
*
- * @return True if Data Loader was able to start. False will be reported to
- * IncrementalService and can cause an unmount of an IFS instance.
+ * @param addedFiles list of files created in this installation session.
+ * @param removedFiles list of files removed in this installation session.
+ * @return false if unable to create and populate all addedFiles.
*/
- public abstract boolean onStart();
-
- /**
- * Stop the data loader. Use to stop any additional threads and free up resources. Data
- * loader is not longer responsible for supplying data. Start/Stop pair can be called
- * multiple times e.g. if IFS detects corruption and data needs to be re-loaded.
- */
- public abstract void onStop();
-
- /**
- * Virtual destructor. Use to cleanup all internal state. After this method returns, the
- * data loader can no longer use connector or callbacks. For any additional operations with
- * this instance of IFS a new DataLoader will be created using createDataLoader method.
- */
- public abstract void onDestroy();
+ boolean onPrepareImage(Collection<InstallationFile> addedFiles,
+ Collection<String> removedFiles);
}
/**
@@ -145,7 +88,9 @@
* @return An instance of a DataLoader.
* @hide
*/
- public abstract @Nullable DataLoader onCreateDataLoader();
+ public @Nullable DataLoader onCreateDataLoader() {
+ return null;
+ }
/**
* @hide
@@ -160,148 +105,125 @@
@Override
public void create(int id, @NonNull Bundle options,
@NonNull IDataLoaderStatusListener listener)
- throws IllegalArgumentException, RuntimeException {
+ throws IllegalArgumentException, RuntimeException {
mId = id;
- final DataLoaderParamsParcel params = options.getParcelable("params");
+ final DataLoaderParamsParcel params = options.getParcelable("params");
if (params == null) {
- throw new IllegalArgumentException("Must specify Incremental data loader params");
+ throw new IllegalArgumentException("Must specify data loader params");
}
- final FileSystemControlParcel control =
- options.getParcelable("control");
+ final FileSystemControlParcel control = options.getParcelable("control");
if (control == null) {
- throw new IllegalArgumentException("Must specify Incremental control parcel");
+ throw new IllegalArgumentException("Must specify control parcel");
}
- mStatusListener = listener;
try {
if (!nativeCreateDataLoader(id, control, params, listener)) {
Slog.e(TAG, "Failed to create native loader for " + mId);
}
} catch (Exception ex) {
+ Slog.e(TAG, "Failed to create native loader for " + mId, ex);
destroy();
throw new RuntimeException(ex);
} finally {
// Closing FDs.
- if (control.incremental.cmd != null) {
- try {
- control.incremental.cmd.close();
- } catch (IOException e) {
- Slog.e(TAG, "Failed to close IncFs CMD file descriptor " + e);
+ if (control.incremental != null) {
+ if (control.incremental.cmd != null) {
+ try {
+ control.incremental.cmd.close();
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to close IncFs CMD file descriptor " + e);
+ }
+ }
+ if (control.incremental.log != null) {
+ try {
+ control.incremental.log.close();
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to close IncFs LOG file descriptor " + e);
+ }
}
}
- if (control.incremental.log != null) {
- try {
- control.incremental.log.close();
- } catch (IOException e) {
- Slog.e(TAG, "Failed to close IncFs LOG file descriptor " + e);
- }
- }
- NamedParcelFileDescriptor[] fds = params.dynamicArgs;
- for (NamedParcelFileDescriptor nfd : fds) {
- try {
- nfd.fd.close();
- } catch (IOException e) {
- Slog.e(TAG,
- "Failed to close DynamicArgs parcel file descriptor " + e);
+ if (params.dynamicArgs != null) {
+ NamedParcelFileDescriptor[] fds = params.dynamicArgs;
+ for (NamedParcelFileDescriptor nfd : fds) {
+ try {
+ nfd.fd.close();
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to close DynamicArgs parcel file descriptor " + e);
+ }
}
}
}
}
@Override
- public void start(List<InstallationFile> fileInfos) {
+ public void start() {
if (!nativeStartDataLoader(mId)) {
- Slog.e(TAG, "Failed to start loader: loader not found for " + mId);
+ Slog.e(TAG, "Failed to start loader: " + mId);
}
}
@Override
public void stop() {
if (!nativeStopDataLoader(mId)) {
- Slog.w(TAG, "Failed to stop loader: loader not found for " + mId);
+ Slog.w(TAG, "Failed to stop loader: " + mId);
}
}
@Override
public void destroy() {
if (!nativeDestroyDataLoader(mId)) {
- Slog.w(TAG, "Failed to destroy loader: loader not found for " + mId);
+ Slog.w(TAG, "Failed to destroy loader: " + mId);
+ }
+ }
+
+ @Override
+ public void prepareImage(List<InstallationFile> addedFiles, List<String> removedFiles) {
+ if (!nativePrepareImage(mId, addedFiles, removedFiles)) {
+ Slog.w(TAG, "Failed to destroy loader: " + mId);
}
}
}
/**
- *
* Used by the DataLoaderService implementations.
*
* @hide
*/
public static final class FileSystemConnector {
/**
- * Creates a wrapper for an installation session connector.
+ * Create a wrapper for a native instance.
+ *
* @hide
*/
- FileSystemConnector(IPackageInstallerSessionFileSystemConnector connector) {
- mConnector = connector;
+ FileSystemConnector(long nativeInstance) {
+ mNativeInstance = nativeInstance;
}
/**
* Write data to an installation file from an arbitrary FD.
*
- * @param name name of file previously added to the installation session.
- * @param offsetBytes offset into the file to begin writing at, or 0 to
- * start at the beginning of the file.
- * @param lengthBytes total size of the file being written, used to
- * preallocate the underlying disk space, or -1 if unknown.
- * The system may clear various caches as needed to allocate
- * this space.
- * @param incomingFd FD to read bytes from.
- * @throws IOException if trouble opening the file for writing, such as
- * lack of disk space or unavailable media.
+ * @param name name of file previously added to the installation session.
+ * @param offsetBytes offset into the file to begin writing at, or 0 to start at the
+ * beginning of the file.
+ * @param lengthBytes total size of the file being written, used to preallocate the
+ * underlying disk space, or -1 if unknown. The system may clear various
+ * caches as needed to allocate this space.
+ * @param incomingFd FD to read bytes from.
+ * @throws IOException if trouble opening the file for writing, such as lack of disk space
+ * or unavailable media.
*/
public void writeData(String name, long offsetBytes, long lengthBytes,
ParcelFileDescriptor incomingFd) throws IOException {
try {
- mConnector.writeData(name, offsetBytes, lengthBytes, incomingFd);
+ nativeWriteData(mNativeInstance, name, offsetBytes, lengthBytes, incomingFd);
} catch (RuntimeException e) {
ExceptionUtils.maybeUnwrapIOException(e);
throw e;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
}
}
- private final IPackageInstallerSessionFileSystemConnector mConnector;
- }
-
- /**
- * Wrapper for native reporting DataLoader statuses.
- * @hide
- */
- public static final class StatusListener {
- /**
- * Creates a wrapper for a native instance.
- * @hide
- */
- StatusListener(long nativeInstance) {
- mNativeInstance = nativeInstance;
- }
-
- /**
- * Report the status of DataLoader. Used for system-wide notifications e.g., disabling
- * applications which rely on this data loader to function properly.
- *
- * @param status status to report.
- * @return True if status was reported successfully.
- */
- public boolean onStatusChanged(@DataLoaderStatus int status) {
- return nativeReportStatus(mNativeInstance, status);
- }
-
private final long mNativeInstance;
}
- private IDataLoaderStatusListener mStatusListener = null;
-
/* Native methods */
private native boolean nativeCreateDataLoader(int storageId,
@NonNull FileSystemControlParcel control,
@@ -314,5 +236,10 @@
private native boolean nativeDestroyDataLoader(int storageId);
- private static native boolean nativeReportStatus(long nativeInstance, int status);
+ private native boolean nativePrepareImage(int storageId,
+ Collection<InstallationFile> addedFiles, Collection<String> removedFiles);
+
+ private static native void nativeWriteData(long nativeInstance, String name, long offsetBytes,
+ long lengthBytes, ParcelFileDescriptor incomingFd);
+
}
diff --git a/core/jni/android_service_DataLoaderService.cpp b/core/jni/android_service_DataLoaderService.cpp
index 381b386..a62d127 100644
--- a/core/jni/android_service_DataLoaderService.cpp
+++ b/core/jni/android_service_DataLoaderService.cpp
@@ -51,13 +51,19 @@
}
-static jboolean nativeReportStatus(JNIEnv* env,
- jobject clazz,
- jlong self,
- jint status) {
- auto listener = (DataLoaderStatusListenerPtr)self;
- return DataLoader_StatusListener_reportStatus(listener,
- (DataLoaderStatus)status);
+static jboolean nativePrepareImage(JNIEnv* env, jobject thiz, jint storageId, jobject addedFiles, jobject removedFiles) {
+ return DataLoaderService_OnPrepareImage(storageId, addedFiles, removedFiles);
+}
+
+static void nativeWriteData(JNIEnv* env,
+ jobject clazz,
+ jlong self,
+ jstring name,
+ jlong offsetBytes,
+ jlong lengthBytes,
+ jobject incomingFd) {
+ auto connector = (DataLoaderFilesystemConnectorPtr)self;
+ return DataLoader_FilesystemConnector_writeData(connector, name, offsetBytes, lengthBytes, incomingFd);
}
static const JNINativeMethod dlc_method_table[] = {
@@ -69,7 +75,8 @@
{"nativeStartDataLoader", "(I)Z", (void*)nativeStartDataLoader},
{"nativeStopDataLoader", "(I)Z", (void*)nativeStopDataLoader},
{"nativeDestroyDataLoader", "(I)Z", (void*)nativeDestroyDataLoader},
- {"nativeReportStatus", "(JI)Z", (void*)nativeReportStatus},
+ {"nativePrepareImage", "(ILjava/util/Collection;Ljava/util/Collection;)Z", (void*)nativePrepareImage},
+ {"nativeWriteData", "(JLjava/lang/String;JJLandroid/os/ParcelFileDescriptor;)V", (void*)nativeWriteData},
};
} // namespace
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 1165d2d..44a902c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4113,7 +4113,7 @@
<permission android:name="android.permission.INTENT_FILTER_VERIFICATION_AGENT"
android:protectionLevel="signature|privileged" />
- <!-- Must be required by intent filter verifier receiver, to ensure that only the
+ <!-- Must be required by intent filter verifier rintent-filtereceiver, to ensure that only the
system can interact with it.
@hide
-->
@@ -5143,6 +5143,12 @@
android:permission="android.permission.BIND_JOB_SERVICE" >
</service>
-</application>
+ <service android:name="com.android.server.pm.PackageManagerShellCommandDataLoader">
+ <intent-filter>
+ <action android:name="android.intent.action.LOAD_DATA" />
+ </intent-filter>
+ </service>
+
+ </application>
</manifest>