Migrating Incremental* APIs to PackageManager APIs.

This is the first step, migrating java parts.
CleanSpec.mk added as a workaround for b/146502407

Test: builds and flashes
Bug: b/136132412

Change-Id: Id0a26aa011b555ea457b5aafe7f5789c36d25bcc
diff --git a/Android.bp b/Android.bp
index 77abad6e..e14a352 100644
--- a/Android.bp
+++ b/Android.bp
@@ -807,9 +807,11 @@
 filegroup {
     name: "dataloader_aidl",
     srcs: [
+        "core/java/android/content/pm/DataLoaderParamsParcel.aidl",
+        "core/java/android/content/pm/FileSystemControlParcel.aidl",
         "core/java/android/content/pm/IDataLoaderStatusListener.aidl",
-        "core/java/android/os/incremental/IncrementalDataLoaderParamsParcel.aidl",
-        "core/java/android/os/incremental/NamedParcelFileDescriptor.aidl",
+        "core/java/android/content/pm/IPackageInstallerSessionFileSystemConnector.aidl",
+        "core/java/android/content/pm/NamedParcelFileDescriptor.aidl",
     ],
     path: "core/java",
 }
diff --git a/CleanSpec.mk b/CleanSpec.mk
index f94de29..b84e715 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -257,6 +257,8 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/telephony/java/com/google/android/mms)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/*-service.jar)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/service-statsd.jar)
+$(call add-clean-step, rm -rf $(SOONG_OUT_DIR)/.intermediates/frameworks/base/libincremental_aidl-cpp-source/)
+$(call add-clean-step, rm -rf $(SOONG_OUT_DIR)/.intermediates/frameworks/base/libincremental_manager_aidl-cpp-source/)
 # ******************************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
 # ******************************************************************
diff --git a/core/java/android/os/incremental/IncrementalDataLoaderParams.java b/core/java/android/content/pm/DataLoaderParams.java
similarity index 82%
rename from core/java/android/os/incremental/IncrementalDataLoaderParams.java
rename to core/java/android/content/pm/DataLoaderParams.java
index 701f1cc..b163861 100644
--- a/core/java/android/os/incremental/IncrementalDataLoaderParams.java
+++ b/core/java/android/content/pm/DataLoaderParams.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.os.incremental;
+package android.content.pm;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -29,12 +29,12 @@
  * Hide for now.
  * @hide
  */
-public class IncrementalDataLoaderParams {
-    @NonNull private final IncrementalDataLoaderParamsParcel mData;
+public class DataLoaderParams {
+    @NonNull private final DataLoaderParamsParcel mData;
 
-    public IncrementalDataLoaderParams(@NonNull String url, @NonNull String packageName,
+    public DataLoaderParams(@NonNull String url, @NonNull String packageName,
             @Nullable Map<String, ParcelFileDescriptor> namedFds) {
-        IncrementalDataLoaderParamsParcel data = new IncrementalDataLoaderParamsParcel();
+        DataLoaderParamsParcel data = new DataLoaderParamsParcel();
         data.staticArgs = url;
         data.packageName = packageName;
         if (namedFds == null || namedFds.isEmpty()) {
@@ -52,7 +52,7 @@
         mData = data;
     }
 
-    public IncrementalDataLoaderParams(@NonNull IncrementalDataLoaderParamsParcel data) {
+    public DataLoaderParams(@NonNull DataLoaderParamsParcel data) {
         mData = data;
     }
 
@@ -70,7 +70,7 @@
         return mData.packageName;
     }
 
-    public final @NonNull IncrementalDataLoaderParamsParcel getData() {
+    public final @NonNull DataLoaderParamsParcel getData() {
         return mData;
     }
 
diff --git a/core/java/android/os/incremental/IncrementalDataLoaderParamsParcel.aidl b/core/java/android/content/pm/DataLoaderParamsParcel.aidl
similarity index 85%
rename from core/java/android/os/incremental/IncrementalDataLoaderParamsParcel.aidl
rename to core/java/android/content/pm/DataLoaderParamsParcel.aidl
index cd988dc..3316398 100644
--- a/core/java/android/os/incremental/IncrementalDataLoaderParamsParcel.aidl
+++ b/core/java/android/content/pm/DataLoaderParamsParcel.aidl
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-package android.os.incremental;
+package android.content.pm;
 
-import android.os.incremental.NamedParcelFileDescriptor;
+import android.content.pm.NamedParcelFileDescriptor;
 
 /**
  * Class for holding data loader configuration parameters.
  * @hide
  */
-parcelable IncrementalDataLoaderParamsParcel {
+parcelable DataLoaderParamsParcel {
     @utf8InCpp String packageName;
     @utf8InCpp String staticArgs;
     NamedParcelFileDescriptor[] dynamicArgs;
diff --git a/core/java/android/content/pm/FileSystemControlParcel.aidl b/core/java/android/content/pm/FileSystemControlParcel.aidl
new file mode 100644
index 0000000..f00feae
--- /dev/null
+++ b/core/java/android/content/pm/FileSystemControlParcel.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+import android.content.pm.IPackageInstallerSessionFileSystemConnector;
+import android.os.incremental.IncrementalFileSystemControlParcel;
+
+/**
+ * Wraps info needed for DataLoader to provide data.
+ * @hide
+ */
+parcelable FileSystemControlParcel {
+    // Incremental FS control descriptors.
+    @nullable IncrementalFileSystemControlParcel incremental;
+    // Callback-based installation connector.
+    @nullable IPackageInstallerSessionFileSystemConnector callback;
+}
diff --git a/core/java/android/content/pm/IDataLoader.aidl b/core/java/android/content/pm/IDataLoader.aidl
index 60cc9ba9..c65bd6a 100644
--- a/core/java/android/content/pm/IDataLoader.aidl
+++ b/core/java/android/content/pm/IDataLoader.aidl
@@ -30,5 +30,4 @@
    void start(in List<InstallationFile> fileInfos);
    void stop();
    void destroy();
-   void onFileCreated(long inode, in byte[] metadata);
 }
diff --git a/core/java/android/os/incremental/NamedParcelFileDescriptor.aidl b/core/java/android/content/pm/IPackageInstallerSessionFileSystemConnector.aidl
similarity index 76%
copy from core/java/android/os/incremental/NamedParcelFileDescriptor.aidl
copy to core/java/android/content/pm/IPackageInstallerSessionFileSystemConnector.aidl
index 038ced1..4b2f29e 100644
--- a/core/java/android/os/incremental/NamedParcelFileDescriptor.aidl
+++ b/core/java/android/content/pm/IPackageInstallerSessionFileSystemConnector.aidl
@@ -14,15 +14,11 @@
  * limitations under the License.
  */
 
-package android.os.incremental;
+package android.content.pm;
 
 import android.os.ParcelFileDescriptor;
 
-/**
- * A named ParcelFileDescriptor.
- * @hide
- */
-parcelable NamedParcelFileDescriptor {
-    @utf8InCpp String name;
-    ParcelFileDescriptor fd;
+/** {@hide} */
+interface IPackageInstallerSessionFileSystemConnector {
+    void writeData(String name, long offsetBytes, long lengthBytes, in ParcelFileDescriptor fd);
 }
diff --git a/core/java/android/os/incremental/NamedParcelFileDescriptor.aidl b/core/java/android/content/pm/NamedParcelFileDescriptor.aidl
similarity index 95%
rename from core/java/android/os/incremental/NamedParcelFileDescriptor.aidl
rename to core/java/android/content/pm/NamedParcelFileDescriptor.aidl
index 038ced1..68dd5f5 100644
--- a/core/java/android/os/incremental/NamedParcelFileDescriptor.aidl
+++ b/core/java/android/content/pm/NamedParcelFileDescriptor.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.os.incremental;
+package android.content.pm;
 
 import android.os.ParcelFileDescriptor;
 
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 898631e..218c876 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -50,8 +50,6 @@
 import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.UserHandle;
-import android.os.incremental.IncrementalDataLoaderParams;
-import android.os.incremental.IncrementalDataLoaderParamsParcel;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.util.ArraySet;
@@ -1459,7 +1457,7 @@
         /** {@hide} */
         public long requiredInstalledVersionCode = PackageManager.VERSION_CODE_HIGHEST;
         /** {@hide} */
-        public IncrementalDataLoaderParams incrementalParams;
+        public DataLoaderParams incrementalParams;
         /** TODO(b/146080380): add a class name to make it fully compatible with ComponentName.
          * {@hide} */
         public String dataLoaderPackageName;
@@ -1496,10 +1494,10 @@
             isMultiPackage = source.readBoolean();
             isStaged = source.readBoolean();
             requiredInstalledVersionCode = source.readLong();
-            IncrementalDataLoaderParamsParcel dataLoaderParamsParcel = source.readParcelable(
-                    IncrementalDataLoaderParamsParcel.class.getClassLoader());
+            DataLoaderParamsParcel dataLoaderParamsParcel = source.readParcelable(
+                    DataLoaderParamsParcel.class.getClassLoader());
             if (dataLoaderParamsParcel != null) {
-                incrementalParams = new IncrementalDataLoaderParams(
+                incrementalParams = new DataLoaderParams(
                         dataLoaderParamsParcel);
             }
             dataLoaderPackageName = source.readString();
@@ -1863,7 +1861,7 @@
          * {@hide}
          */
         @RequiresPermission(Manifest.permission.INSTALL_PACKAGES)
-        public void setIncrementalParams(@NonNull IncrementalDataLoaderParams incrementalParams) {
+        public void setIncrementalParams(@NonNull DataLoaderParams incrementalParams) {
             this.incrementalParams = incrementalParams;
         }
 
diff --git a/core/java/android/os/incremental/IIncrementalManager.aidl b/core/java/android/os/incremental/IIncrementalManager.aidl
index f84d7ef..17a310a 100644
--- a/core/java/android/os/incremental/IIncrementalManager.aidl
+++ b/core/java/android/os/incremental/IIncrementalManager.aidl
@@ -16,8 +16,8 @@
 
 package android.os.incremental;
 
-import android.os.incremental.IncrementalFileSystemControlParcel;
-import android.os.incremental.IncrementalDataLoaderParamsParcel;
+import android.content.pm.FileSystemControlParcel;
+import android.content.pm.DataLoaderParamsParcel;
 import android.content.pm.IDataLoaderStatusListener;
 
 /**
@@ -27,8 +27,8 @@
  */
 interface IIncrementalManager {
     boolean prepareDataLoader(int mountId,
-        in IncrementalFileSystemControlParcel control,
-        in IncrementalDataLoaderParamsParcel params,
+        in FileSystemControlParcel control,
+        in DataLoaderParamsParcel params,
         in IDataLoaderStatusListener listener);
     boolean startDataLoader(int mountId);
     void showHealthBlockedUI(int mountId);
diff --git a/core/java/android/os/incremental/IIncrementalManagerNative.aidl b/core/java/android/os/incremental/IIncrementalManagerNative.aidl
index d9c7c6b..14215b1 100644
--- a/core/java/android/os/incremental/IIncrementalManagerNative.aidl
+++ b/core/java/android/os/incremental/IIncrementalManagerNative.aidl
@@ -16,7 +16,7 @@
 
 package android.os.incremental;
 
-import android.os.incremental.IncrementalDataLoaderParamsParcel;
+import android.content.pm.DataLoaderParamsParcel;
 
 /** @hide */
 interface IIncrementalManagerNative {
@@ -32,7 +32,7 @@
      * 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 IncrementalDataLoaderParamsParcel params, int createMode);
+    int createStorage(in @utf8InCpp String path, in DataLoaderParamsParcel params, int createMode);
     int createLinkedStorage(in @utf8InCpp String path, int otherStorageId, int createMode);
 
     /**
diff --git a/core/java/android/os/incremental/IncrementalFileStorages.java b/core/java/android/os/incremental/IncrementalFileStorages.java
index 5bd0748..7987efd 100644
--- a/core/java/android/os/incremental/IncrementalFileStorages.java
+++ b/core/java/android/os/incremental/IncrementalFileStorages.java
@@ -35,6 +35,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.DataLoaderParams;
 import android.content.pm.InstallationFile;
 import android.os.IVold;
 import android.os.RemoteException;
@@ -82,12 +83,12 @@
     public IncrementalFileStorages(@NonNull String packageName,
             @NonNull File stageDir,
             @NonNull IncrementalManager incrementalManager,
-            @NonNull IncrementalDataLoaderParams incrementalDataLoaderParams) {
+            @NonNull DataLoaderParams dataLoaderParams) {
         mPackageName = packageName;
         mStageDir = stageDir;
         mIncrementalManager = incrementalManager;
-        if (incrementalDataLoaderParams.getPackageName().equals("local")) {
-            final String incrementalPath = incrementalDataLoaderParams.getStaticArgs();
+        if (dataLoaderParams.getPackageName().equals("local")) {
+            final String incrementalPath = dataLoaderParams.getStaticArgs();
             mDefaultStorage = mIncrementalManager.openStorage(incrementalPath);
             mDefaultDir = incrementalPath;
             return;
@@ -97,7 +98,7 @@
             return;
         }
         mDefaultStorage = mIncrementalManager.createStorage(mDefaultDir,
-                incrementalDataLoaderParams,
+                dataLoaderParams,
                 IncrementalManager.CREATE_MODE_CREATE
                         | IncrementalManager.CREATE_MODE_TEMPORARY_BIND, false);
     }
diff --git a/core/java/android/os/incremental/IncrementalManager.java b/core/java/android/os/incremental/IncrementalManager.java
index c30f558..c722287 100644
--- a/core/java/android/os/incremental/IncrementalManager.java
+++ b/core/java/android/os/incremental/IncrementalManager.java
@@ -21,6 +21,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemService;
 import android.content.Context;
+import android.content.pm.DataLoaderParams;
 import android.os.RemoteException;
 import android.system.ErrnoException;
 import android.system.Os;
@@ -104,7 +105,7 @@
      */
     @Nullable
     public IncrementalStorage createStorage(@NonNull String path,
-            @NonNull IncrementalDataLoaderParams params, @CreateMode int createMode,
+            @NonNull DataLoaderParams params, @CreateMode int createMode,
             boolean autoStartDataLoader) {
         try {
             final int id = mNativeService.createStorage(path, params.getData(), createMode);
diff --git a/core/java/android/service/dataloader/DataLoaderService.java b/core/java/android/service/dataloader/DataLoaderService.java
new file mode 100644
index 0000000..373e1e5
--- /dev/null
+++ b/core/java/android/service/dataloader/DataLoaderService.java
@@ -0,0 +1,307 @@
+/*
+ * 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.service.dataloader;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.Service;
+import android.content.Intent;
+import android.content.pm.DataLoaderParams;
+import android.content.pm.DataLoaderParamsParcel;
+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.List;
+
+/**
+ * The base class for implementing data loader service to control data loaders. Expecting
+ * Incremental Service to bind to a children class of this.
+ *
+ * @hide
+ *
+ * Hide for now, should be @SystemApi
+ * TODO(b/136132412): update with latest API design
+ */
+public abstract class DataLoaderService extends Service {
+    private static final String TAG = "IncrementalDataLoaderService";
+    private final DataLoaderBinderService mBinder = new DataLoaderBinderService();
+
+    public static final int DATA_LOADER_READY =
+            IDataLoaderStatusListener.DATA_LOADER_READY;
+    public static final int DATA_LOADER_NOT_READY =
+            IDataLoaderStatusListener.DATA_LOADER_NOT_READY;
+    public static final int DATA_LOADER_RUNNING =
+            IDataLoaderStatusListener.DATA_LOADER_RUNNING;
+    public static final int DATA_LOADER_STOPPED =
+            IDataLoaderStatusListener.DATA_LOADER_STOPPED;
+    public static final int DATA_LOADER_SLOW_CONNECTION =
+            IDataLoaderStatusListener.DATA_LOADER_SLOW_CONNECTION;
+    public static final int DATA_LOADER_NO_CONNECTION =
+            IDataLoaderStatusListener.DATA_LOADER_NO_CONNECTION;
+    public static final int DATA_LOADER_CONNECTION_OK =
+            IDataLoaderStatusListener.DATA_LOADER_CONNECTION_OK;
+
+    @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.
+     */
+    public abstract static class 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.
+         *
+         * @param params    Data loader configuration parameters.
+         * @param connector IncFS API wrapper.
+         * @param listener  Used for reporting internal state to IncrementalService.
+         * @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.
+         */
+        public abstract boolean onCreate(@NonNull DataLoaderParams params,
+                @NonNull FileSystemConnector connector,
+                @NonNull StatusListener listener);
+
+        /**
+         * 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.
+         *
+         * @return True if Data Loader was able to start. False will be reported to
+         * IncrementalService and can cause an unmount of an IFS instance.
+         */
+        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();
+    }
+
+    /**
+     * DataLoader factory method.
+     *
+     * @return An instance of a DataLoader.
+     */
+    public abstract @Nullable DataLoader onCreateDataLoader();
+
+    /**
+     * @hide
+     */
+    public final @NonNull IBinder onBind(@NonNull Intent intent) {
+        return (IBinder) mBinder;
+    }
+
+    private class DataLoaderBinderService extends IDataLoader.Stub {
+        private int mId;
+
+        @Override
+        public void create(int id, @NonNull Bundle options,
+                @NonNull IDataLoaderStatusListener listener)
+                    throws IllegalArgumentException, RuntimeException {
+            mId = id;
+            final DataLoaderParamsParcel params =  options.getParcelable("params");
+            if (params == null) {
+                throw new IllegalArgumentException("Must specify Incremental data loader params");
+            }
+            final FileSystemControlParcel control =
+                    options.getParcelable("control");
+            if (control == null) {
+                throw new IllegalArgumentException("Must specify Incremental control parcel");
+            }
+            mStatusListener = listener;
+            try {
+                if (!nativeCreateDataLoader(id, control, params, listener)) {
+                    Slog.e(TAG, "Failed to create native loader for " + mId);
+                }
+            } catch (Exception 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.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);
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void start(List<InstallationFile> fileInfos) {
+            if (!nativeStartDataLoader(mId)) {
+                Slog.e(TAG, "Failed to start loader: loader not found for " + mId);
+            }
+        }
+
+        @Override
+        public void stop() {
+            if (!nativeStopDataLoader(mId)) {
+                Slog.w(TAG, "Failed to stop loader: loader not found for " + mId);
+            }
+        }
+
+        @Override
+        public void destroy() {
+            if (!nativeDestroyDataLoader(mId)) {
+                Slog.w(TAG, "Failed to destroy loader: loader not found for " + mId);
+            }
+        }
+    }
+
+    /**
+     *
+     * Used by the DataLoaderService implementations.
+     *
+     * @hide
+     *
+     * TODO(b/136132412) Should be @SystemApi
+     */
+    public static final class FileSystemConnector {
+        /**
+         * Creates a wrapper for an installation session connector.
+         * @hide
+         */
+        FileSystemConnector(IPackageInstallerSessionFileSystemConnector connector) {
+            mConnector = connector;
+        }
+
+        /**
+         * 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.
+         */
+        public void writeData(String name, long offsetBytes, long lengthBytes,
+                ParcelFileDescriptor incomingFd) throws IOException {
+            try {
+                mConnector.writeData(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
+     * TODO(b/136132412) Should be @SystemApi
+     */
+    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,
+            @NonNull DataLoaderParamsParcel params,
+            IDataLoaderStatusListener listener);
+
+    private native boolean nativeStartDataLoader(int storageId);
+
+    private native boolean nativeStopDataLoader(int storageId);
+
+    private native boolean nativeDestroyDataLoader(int storageId);
+
+    private static native boolean nativeReportStatus(long nativeInstance, int status);
+}
diff --git a/core/java/android/service/incremental/IncrementalDataLoaderService.java b/core/java/android/service/incremental/IncrementalDataLoaderService.java
deleted file mode 100644
index c4a06c8..0000000
--- a/core/java/android/service/incremental/IncrementalDataLoaderService.java
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * 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.service.incremental;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Service;
-import android.content.Intent;
-import android.content.pm.IDataLoader;
-import android.content.pm.IDataLoaderStatusListener;
-import android.content.pm.InstallationFile;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.incremental.IncrementalDataLoaderParams;
-import android.os.incremental.IncrementalDataLoaderParamsParcel;
-import android.os.incremental.IncrementalFileSystemControlParcel;
-import android.os.incremental.NamedParcelFileDescriptor;
-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;
-
-
-/**
- * The base class for implementing data loader service to control data loaders. Expecting
- * Incremental Service to bind to a children class of this.
- *
- * @hide
- *
- * Hide for now, should be @SystemApi
- * TODO(b/136132412): update with latest API design
- */
-public abstract class IncrementalDataLoaderService extends Service {
-    private static final String TAG = "IncrementalDataLoaderService";
-    private final DataLoaderBinderService mBinder = new DataLoaderBinderService();
-
-    public static final int DATA_LOADER_READY =
-            IDataLoaderStatusListener.DATA_LOADER_READY;
-    public static final int DATA_LOADER_NOT_READY =
-            IDataLoaderStatusListener.DATA_LOADER_NOT_READY;
-    public static final int DATA_LOADER_RUNNING =
-            IDataLoaderStatusListener.DATA_LOADER_RUNNING;
-    public static final int DATA_LOADER_STOPPED =
-            IDataLoaderStatusListener.DATA_LOADER_STOPPED;
-    public static final int DATA_LOADER_SLOW_CONNECTION =
-            IDataLoaderStatusListener.DATA_LOADER_SLOW_CONNECTION;
-    public static final int DATA_LOADER_NO_CONNECTION =
-            IDataLoaderStatusListener.DATA_LOADER_NO_CONNECTION;
-    public static final int DATA_LOADER_CONNECTION_OK =
-            IDataLoaderStatusListener.DATA_LOADER_CONNECTION_OK;
-
-    @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 {
-    }
-
-    /**
-     * Incremental FileSystem block size.
-     **/
-    public static final int BLOCK_SIZE = 4096;
-
-    /**
-     * Data compression types
-     */
-    public static final int COMPRESSION_NONE = 0;
-    public static final int COMPRESSION_LZ4 = 1;
-
-    /**
-     * @hide
-     */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({COMPRESSION_NONE, COMPRESSION_LZ4})
-    public @interface CompressionType {
-    }
-
-    /**
-     * Managed DataLoader interface. Each instance corresponds to a single Incremental File System
-     * instance.
-     */
-    public abstract static class 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.
-         *
-         * @param params    Data loader configuration parameters.
-         * @param connector IncFS API wrapper.
-         * @param listener  Used for reporting internal state to IncrementalService.
-         * @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.
-         */
-        public abstract boolean onCreate(@NonNull IncrementalDataLoaderParams params,
-                @NonNull FileSystemConnector connector,
-                @NonNull StatusListener listener);
-
-        /**
-         * 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.
-         *
-         * @return True if Data Loader was able to start. False will be reported to
-         * IncrementalService and can cause an unmount of an IFS instance.
-         */
-        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();
-
-        /**
-         * IFS reports a pending read each time the page needs to be loaded, e.g. missing.
-         *
-         * @param pendingReads array of blocks to load.
-         *
-         * TODO(b/136132412): avoid using collections
-         */
-        public abstract void onPendingReads(
-                @NonNull Collection<FileSystemConnector.PendingReadInfo> pendingReads);
-
-        /**
-         * IFS tracks all reads and reports them using onPageReads.
-         *
-         * @param reads array of blocks.
-         *
-         * TODO(b/136132412): avoid using collections
-         */
-        public abstract void onPageReads(@NonNull Collection<FileSystemConnector.ReadInfo> reads);
-
-        /**
-         * IFS informs data loader that a new file has been created.
-         * <p>
-         * This can be used to prepare the data loader before it starts loading data. For example,
-         * the data loader can keep a list of newly created files, so that it knows what files to
-         * download from the server.
-         *
-         * @param inode    The inode value of the new file.
-         * @param metadata The metadata of the new file.
-         */
-        public abstract void onFileCreated(long inode, byte[] metadata);
-    }
-
-    /**
-     * DataLoader factory method.
-     *
-     * @return An instance of a DataLoader.
-     */
-    public abstract @Nullable DataLoader onCreateDataLoader();
-
-    /**
-     * @hide
-     */
-    public final @NonNull IBinder onBind(@NonNull Intent intent) {
-        return (IBinder) mBinder;
-    }
-
-    private class DataLoaderBinderService extends IDataLoader.Stub {
-        private int mId;
-
-        @Override
-        public void create(int id, @NonNull Bundle options,
-                @NonNull IDataLoaderStatusListener listener)
-                    throws IllegalArgumentException, RuntimeException {
-            mId = id;
-            final IncrementalDataLoaderParamsParcel params =  options.getParcelable("params");
-            if (params == null) {
-                throw new IllegalArgumentException("Must specify Incremental data loader params");
-            }
-            final IncrementalFileSystemControlParcel control =
-                    options.getParcelable("control");
-            if (control == null) {
-                throw new IllegalArgumentException("Must specify Incremental control parcel");
-            }
-            mStatusListener = listener;
-            try {
-                if (!nativeCreateDataLoader(id, control, params, listener)) {
-                    Slog.e(TAG, "Failed to create native loader for " + mId);
-                }
-            } catch (Exception ex) {
-                destroy();
-                throw new RuntimeException(ex);
-            } finally {
-                // Closing FDs.
-                if (control.cmd != null) {
-                    try {
-                        control.cmd.close();
-                    } catch (IOException e) {
-                        Slog.e(TAG, "Failed to close IncFs CMD file descriptor " + e);
-                    }
-                }
-                if (control.log != null) {
-                    try {
-                        control.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);
-                    }
-                }
-            }
-        }
-
-        @Override
-        public void start(List<InstallationFile> fileInfos) {
-            if (!nativeStartDataLoader(mId)) {
-                Slog.e(TAG, "Failed to start loader: loader not found for " + mId);
-            }
-        }
-
-        @Override
-        public void stop() {
-            if (!nativeStopDataLoader(mId)) {
-                Slog.w(TAG, "Failed to stop loader: loader not found for " + mId);
-            }
-        }
-
-        @Override
-        public void destroy() {
-            if (!nativeDestroyDataLoader(mId)) {
-                Slog.w(TAG, "Failed to destroy loader: loader not found for " + mId);
-            }
-        }
-
-        @Override
-        // TODO(b/136132412): remove this
-        public void onFileCreated(long inode, byte[] metadata) {
-            if (!nativeOnFileCreated(mId, inode, metadata)) {
-                Slog.w(TAG, "Failed to handle onFileCreated for storage:" + mId
-                        + " inode:" + inode);
-            }
-        }
-    }
-
-    /**
-     * IncFs API wrapper for writing pages and getting page missing info. Non-hidden methods are
-     * expected to be called by the IncrementalDataLoaderService implemented by developers.
-     *
-     * @hide
-     *
-     * TODO(b/136132412) Should be @SystemApi
-     */
-    public static final class FileSystemConnector {
-        /**
-         * Defines a block address. A block is the unit of data chunk that IncFs operates with.
-         *
-         * @hide
-         */
-        public static class BlockAddress {
-            /**
-             * Linux inode uniquely identifies file within a single IFS instance.
-             */
-            private final long mFileIno;
-            /**
-             * Index of a 4K block within a file.
-             */
-            private final int mBlockIndex;
-
-            public BlockAddress(long fileIno, int blockIndex) {
-                this.mFileIno = fileIno;
-                this.mBlockIndex = blockIndex;
-            }
-
-            public long getFileIno() {
-                return mFileIno;
-            }
-
-            public int getBlockIndex() {
-                return mBlockIndex;
-            }
-        }
-
-        /**
-         * A block is the unit of data chunk that IncFs operates with.
-         *
-         * @hide
-         */
-        public static class Block extends BlockAddress {
-            /**
-             * Data content of the block.
-             */
-            private final @NonNull byte[] mDataBytes;
-
-            public Block(long fileIno, int blockIndex, @NonNull byte[] dataBytes) {
-                super(fileIno, blockIndex);
-                this.mDataBytes = dataBytes;
-            }
-        }
-
-        /**
-         * Defines a page/block inside a file.
-         */
-        public static class DataBlock extends Block {
-            /**
-             * Compression type of the data block.
-             */
-            private final @CompressionType int mCompressionType;
-
-            public DataBlock(long fileIno, int blockIndex, @NonNull byte[] dataBytes,
-                    @CompressionType int compressionType) {
-                super(fileIno, blockIndex, dataBytes);
-                this.mCompressionType = compressionType;
-            }
-        }
-
-        /**
-         * Defines a hash block for a certain file. A hash block index is the index in an array of
-         * hashes which is the 1-d representation of the hash tree. One DataBlock might be
-         * associated with multiple HashBlocks.
-         */
-        public static class HashBlock extends Block {
-            public HashBlock(long fileIno, int blockIndex, @NonNull byte[] dataBytes) {
-                super(fileIno, blockIndex, dataBytes);
-            }
-        }
-
-        /**
-         * Information about a page that is pending to be read.
-         */
-        public static class PendingReadInfo extends BlockAddress {
-            PendingReadInfo(long fileIno, int blockIndex) {
-                super(fileIno, blockIndex);
-            }
-        }
-
-        /**
-         * Information about a page that is read.
-         */
-        public static class ReadInfo extends BlockAddress {
-            /**
-             * A monotonically increasing read timestamp.
-             */
-            private final long mTimePoint;
-            /**
-             * Number of blocks read starting from blockIndex.
-             */
-            private final int mBlockCount;
-
-            ReadInfo(long timePoint, long fileIno, int firstBlockIndex, int blockCount) {
-                super(fileIno, firstBlockIndex);
-                this.mTimePoint = timePoint;
-                this.mBlockCount = blockCount;
-            }
-
-            public long getTimePoint() {
-                return mTimePoint;
-            }
-
-            public int getBlockCount() {
-                return mBlockCount;
-            }
-        }
-
-        /**
-         * Defines the dynamic information about an IncFs file.
-         */
-        public static class FileInfo {
-            /**
-             * BitSet to show if any block is available at each block index.
-             */
-            private final @NonNull
-            byte[] mBlockBitmap;
-
-            /**
-             * @hide
-             */
-            public FileInfo(@NonNull byte[] blockBitmap) {
-                this.mBlockBitmap = blockBitmap;
-            }
-        }
-
-        /**
-         * Creates a wrapper for a native instance.
-         */
-        FileSystemConnector(long nativeInstance) {
-            mNativeInstance = nativeInstance;
-        }
-
-        /**
-         * Checks whether a range in a file if loaded.
-         *
-         * @param node  inode of the file.
-         * @param start The starting offset of the range.
-         * @param end   The ending offset of the range.
-         * @return True if the file is fully loaded.
-         */
-        public boolean isFileRangeLoaded(long node, long start, long end) {
-            return nativeIsFileRangeLoadedNode(mNativeInstance, node, start, end);
-        }
-
-        /**
-         * Gets the metadata of a file.
-         *
-         * @param node inode of the file.
-         * @return The metadata object.
-         */
-        @NonNull
-        public byte[] getFileMetadata(long node) throws IOException {
-            final byte[] metadata = nativeGetFileMetadataNode(mNativeInstance, node);
-            if (metadata == null || metadata.length == 0) {
-                throw new IOException(
-                        "IncrementalFileSystem failed to obtain metadata for node: " + node);
-            }
-            return metadata;
-        }
-
-        /**
-         * Gets the dynamic information of a file, such as page bitmaps. Can be used to get missing
-         * page indices by the FileSystemConnector.
-         *
-         * @param node inode of the file.
-         * @return Dynamic file info.
-         */
-        @NonNull
-        public FileInfo getDynamicFileInfo(long node) throws IOException {
-            final byte[] blockBitmap = nativeGetFileInfoNode(mNativeInstance, node);
-            if (blockBitmap == null || blockBitmap.length == 0) {
-                throw new IOException(
-                        "IncrementalFileSystem failed to obtain dynamic file info for node: "
-                                + node);
-            }
-            return new FileInfo(blockBitmap);
-        }
-
-        /**
-         * Writes a page's data and/or hashes.
-         *
-         * @param dataBlocks the DataBlock objects that contain data block index and data bytes.
-         * @param hashBlocks the HashBlock objects that contain hash indices and hash bytes.
-         *
-         * TODO(b/136132412): change API to avoid dynamic allocation of data block objects
-         */
-        public void writeMissingData(@NonNull DataBlock[] dataBlocks,
-                @Nullable HashBlock[] hashBlocks) throws IOException {
-            if (!nativeWriteMissingData(mNativeInstance, dataBlocks, hashBlocks)) {
-                throw new IOException("IncrementalFileSystem failed to write missing data.");
-            }
-        }
-
-        /**
-         * Writes the signer block of a file. Expecting the connector to call this when it got
-         * signing data from data loader.
-         *
-         * @param node       the file to be written to.
-         * @param signerData the raw signer data byte array.
-         */
-        public void writeSignerData(long node, @NonNull byte[] signerData)
-                throws IOException {
-            if (!nativeWriteSignerDataNode(mNativeInstance, node, signerData)) {
-                throw new IOException(
-                        "IncrementalFileSystem failed to write signer data of node " + node);
-            }
-        }
-
-        private final long mNativeInstance;
-    }
-
-    /**
-     * Wrapper for native reporting DataLoader statuses.
-     *
-     * @hide
-     *
-     * TODO(b/136132412) Should be @SystemApi
-     */
-    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 IncrementalFileSystemControlParcel control,
-            @NonNull IncrementalDataLoaderParamsParcel params,
-            IDataLoaderStatusListener listener);
-
-    private native boolean nativeStartDataLoader(int storageId);
-
-    private native boolean nativeStopDataLoader(int storageId);
-
-    private native boolean nativeDestroyDataLoader(int storageId);
-
-    private static native boolean nativeOnFileCreated(int storageId,
-            long inode, byte[] metadata);
-
-    private static native boolean nativeIsFileRangeLoadedNode(
-            long nativeInstance, long node, long start, long end);
-
-    private static native boolean nativeWriteMissingData(
-            long nativeInstance, FileSystemConnector.DataBlock[] dataBlocks,
-            FileSystemConnector.HashBlock[] hashBlocks);
-
-    private static native boolean nativeWriteSignerDataNode(
-            long nativeInstance, long node, byte[] signerData);
-
-    private static native byte[] nativeGetFileMetadataNode(
-            long nativeInstance, long node);
-
-    private static native byte[] nativeGetFileInfoNode(
-            long nativeInstance, long node);
-
-    private static native boolean nativeReportStatus(long nativeInstance, int status);
-}
diff --git a/core/jni/android_service_DataLoaderService.cpp b/core/jni/android_service_DataLoaderService.cpp
index 4c0f55f..381b386 100644
--- a/core/jni/android_service_DataLoaderService.cpp
+++ b/core/jni/android_service_DataLoaderService.cpp
@@ -16,83 +16,18 @@
 
 #define LOG_TAG "dataloader-jni"
 
-#include <vector>
-
 #include "core_jni_helpers.h"
 #include "dataloader_ndk.h"
-#include "jni.h"
 
 namespace android {
 namespace {
 
-struct JniIds {
-    jfieldID dataBlockFileIno;
-    jfieldID dataBlockBlockIndex;
-    jfieldID dataBlockDataBytes;
-    jfieldID dataBlockCompressionType;
-
-    JniIds(JNIEnv* env) {
-        const auto dataBlock =
-                FindClassOrDie(env,
-                               "android/service/incremental/"
-                               "IncrementalDataLoaderService$FileSystemConnector$DataBlock");
-        dataBlockFileIno = GetFieldIDOrDie(env, dataBlock, "mFileIno", "J");
-        dataBlockBlockIndex =
-                GetFieldIDOrDie(env, dataBlock, "mBlockIndex", "I");
-        dataBlockDataBytes = GetFieldIDOrDie(env, dataBlock, "mDataBytes", "[B");
-        dataBlockCompressionType =
-                GetFieldIDOrDie(env, dataBlock, "mCompressionType", "I");
-    }
-};
-
-const JniIds& jniIds(JNIEnv* env) {
-    static const JniIds ids(env);
-    return ids;
-}
-
-class ScopedJniArrayCritical {
-public:
-    ScopedJniArrayCritical(JNIEnv* env, jarray array) : mEnv(env), mArr(array) {
-        mPtr = array ? env->GetPrimitiveArrayCritical(array, nullptr) : nullptr;
-    }
-    ~ScopedJniArrayCritical() {
-        if (mPtr) {
-            mEnv->ReleasePrimitiveArrayCritical(mArr, mPtr, 0);
-            mPtr = nullptr;
-        }
-    }
-
-    ScopedJniArrayCritical(const ScopedJniArrayCritical&) = delete;
-    void operator=(const ScopedJniArrayCritical&) = delete;
-
-    ScopedJniArrayCritical(ScopedJniArrayCritical&& other)
-        : mEnv(other.mEnv),
-          mArr(std::exchange(mArr, nullptr)),
-          mPtr(std::exchange(mPtr, nullptr)) {}
-    ScopedJniArrayCritical& operator=(ScopedJniArrayCritical&& other) {
-        mEnv = other.mEnv;
-        mArr = std::exchange(other.mArr, nullptr);
-        mPtr = std::exchange(other.mPtr, nullptr);
-        return *this;
-    }
-
-    void* ptr() const { return mPtr; }
-    jsize size() const { return mArr ? mEnv->GetArrayLength(mArr) : 0; }
-
-private:
-    JNIEnv* mEnv;
-    jarray mArr;
-    void* mPtr;
-};
-
 static jboolean nativeCreateDataLoader(JNIEnv* env,
                                        jobject thiz,
                                        jint storageId,
                                        jobject control,
                                        jobject params,
                                        jobject callback) {
-    ALOGE("nativeCreateDataLoader: %p/%d, %d, %p, %p, %p", thiz,
-          env->GetObjectRefType(thiz), storageId, params, control, callback);
     return DataLoaderService_OnCreate(env, thiz,
                      storageId, control, params, callback);
 }
@@ -100,130 +35,22 @@
 static jboolean nativeStartDataLoader(JNIEnv* env,
                                       jobject thiz,
                                       jint storageId) {
-    ALOGE("nativeStartDataLoader: %p/%d, %d", thiz, env->GetObjectRefType(thiz),
-          storageId);
     return DataLoaderService_OnStart(storageId);
 }
 
 static jboolean nativeStopDataLoader(JNIEnv* env,
                                      jobject thiz,
                                      jint storageId) {
-    ALOGE("nativeStopDataLoader: %p/%d, %d", thiz, env->GetObjectRefType(thiz),
-          storageId);
     return DataLoaderService_OnStop(storageId);
 }
 
 static jboolean nativeDestroyDataLoader(JNIEnv* env,
                                         jobject thiz,
                                         jint storageId) {
-    ALOGE("nativeDestroyDataLoader: %p/%d, %d", thiz,
-          env->GetObjectRefType(thiz), storageId);
     return DataLoaderService_OnDestroy(storageId);
 }
 
 
-static jboolean nativeOnFileCreated(JNIEnv* env,
-                                   jobject thiz,
-                                   jint storageId,
-                                   jlong inode,
-                                   jbyteArray metadata) {
-    ALOGE("nativeOnFileCreated: %p/%d, %d", thiz,
-          env->GetObjectRefType(thiz), storageId);
-    return DataLoaderService_OnFileCreated(storageId, inode, metadata);
-}
-
-static jboolean nativeIsFileRangeLoadedNode(JNIEnv* env,
-                                            jobject clazz,
-                                            jlong self,
-                                            jlong node,
-                                            jlong start,
-                                            jlong end) {
-    // TODO(b/136132412): implement this
-    return JNI_FALSE;
-}
-
-static jboolean nativeWriteMissingData(JNIEnv* env,
-                                       jobject clazz,
-                                       jlong self,
-                                       jobjectArray data_block,
-                                       jobjectArray hash_blocks) {
-    const auto& jni = jniIds(env);
-    auto length = env->GetArrayLength(data_block);
-    std::vector<incfs_new_data_block> instructions(length);
-
-    // May not call back into Java after even a single jniArrayCritical, so
-    // let's collect the Java pointers to byte buffers first and lock them in
-    // memory later.
-
-    std::vector<jbyteArray> blockBuffers(length);
-    for (int i = 0; i != length; ++i) {
-        auto& inst = instructions[i];
-        auto jniBlock = env->GetObjectArrayElement(data_block, i);
-        inst.file_ino = env->GetLongField(jniBlock, jni.dataBlockFileIno);
-        inst.block_index = env->GetIntField(jniBlock, jni.dataBlockBlockIndex);
-        blockBuffers[i] = (jbyteArray)env->GetObjectField(
-                jniBlock, jni.dataBlockDataBytes);
-        inst.compression = (incfs_compression_alg)env->GetIntField(
-                jniBlock, jni.dataBlockCompressionType);
-    }
-
-    std::vector<ScopedJniArrayCritical> jniScopedArrays;
-    jniScopedArrays.reserve(length);
-    for (int i = 0; i != length; ++i) {
-        auto buffer = blockBuffers[i];
-        jniScopedArrays.emplace_back(env, buffer);
-        auto& inst = instructions[i];
-        inst.data = (uint64_t)jniScopedArrays.back().ptr();
-        inst.data_len = jniScopedArrays.back().size();
-    }
-
-    auto connector = (DataLoaderFilesystemConnectorPtr)self;
-    if (auto err = DataLoader_FilesystemConnector_writeBlocks(
-                             connector, instructions.data(), length);
-        err < 0) {
-        jniScopedArrays.clear();
-        return JNI_FALSE;
-    }
-
-    return JNI_TRUE;
-}
-
-static jboolean nativeWriteSignerDataNode(JNIEnv* env,
-                                          jobject clazz,
-                                          jlong self,
-                                          jstring relative_path,
-                                          jbyteArray signer_data) {
-    // TODO(b/136132412): implement this
-    return JNI_TRUE;
-}
-
-static jbyteArray nativeGetFileMetadataNode(JNIEnv* env,
-                                            jobject clazz,
-                                            jlong self,
-                                            jlong inode) {
-    auto connector = (DataLoaderFilesystemConnectorPtr)self;
-    std::vector<char> metadata(INCFS_MAX_FILE_ATTR_SIZE);
-    size_t size = metadata.size();
-    if (DataLoader_FilesystemConnector_getRawMetadata(connector, inode,
-                  metadata.data(), &size) < 0) {
-        size = 0;
-    }
-    metadata.resize(size);
-
-    auto buffer = env->NewByteArray(metadata.size());
-    env->SetByteArrayRegion(buffer, 0, metadata.size(),
-                            (jbyte*)metadata.data());
-    return buffer;
-}
-
-static jbyteArray nativeGetFileInfoNode(JNIEnv* env,
-                                        jobject clazz,
-                                        jlong self,
-                                        jlong inode) {
-    // TODO(b/136132412): implement this
-    return nullptr;
-}
-
 static jboolean nativeReportStatus(JNIEnv* env,
                                    jobject clazz,
                                    jlong self,
@@ -235,34 +62,21 @@
 
 static const JNINativeMethod dlc_method_table[] = {
         {"nativeCreateDataLoader",
-         "(ILandroid/os/incremental/IncrementalFileSystemControlParcel;"
-         "Landroid/os/incremental/IncrementalDataLoaderParamsParcel;"
+         "(ILandroid/content/pm/FileSystemControlParcel;"
+         "Landroid/content/pm/DataLoaderParamsParcel;"
          "Landroid/content/pm/IDataLoaderStatusListener;)Z",
          (void*)nativeCreateDataLoader},
         {"nativeStartDataLoader", "(I)Z", (void*)nativeStartDataLoader},
         {"nativeStopDataLoader", "(I)Z", (void*)nativeStopDataLoader},
         {"nativeDestroyDataLoader", "(I)Z", (void*)nativeDestroyDataLoader},
-        {"nativeIsFileRangeLoadedNode", "(JJJJ)Z",
-         (void*)nativeIsFileRangeLoadedNode},
-        {"nativeWriteMissingData",
-         "(J[Landroid/service/incremental/"
-         "IncrementalDataLoaderService$FileSystemConnector$DataBlock;[Landroid/service/incremental/"
-         "IncrementalDataLoaderService$FileSystemConnector$HashBlock;)Z",
-         (void*)nativeWriteMissingData},
-        {"nativeWriteSignerDataNode", "(JJ[B)Z",
-         (void*)nativeWriteSignerDataNode},
-        {"nativeGetFileMetadataNode", "(JJ)[B",
-         (void*)nativeGetFileMetadataNode},
-        {"nativeGetFileInfoNode", "(JJ)[B", (void*)nativeGetFileInfoNode},
         {"nativeReportStatus", "(JI)Z", (void*)nativeReportStatus},
-        {"nativeOnFileCreated", "(IJ[B)Z", (void*)nativeOnFileCreated},
 };
 
 }  // namespace
 
 int register_android_service_DataLoaderService(JNIEnv* env) {
     return jniRegisterNativeMethods(env,
-                                    "android/service/incremental/IncrementalDataLoaderService",
+                                    "android/service/dataloader/DataLoaderService",
                                     dlc_method_table, NELEM(dlc_method_table));
 }
 
diff --git a/packages/Incremental/NativeAdbDataLoader/src/com/android/incremental/nativeadb/NativeAdbDataLoaderService.java b/packages/Incremental/NativeAdbDataLoader/src/com/android/incremental/nativeadb/NativeAdbDataLoaderService.java
index 1f88114..bd5b795 100644
--- a/packages/Incremental/NativeAdbDataLoader/src/com/android/incremental/nativeadb/NativeAdbDataLoaderService.java
+++ b/packages/Incremental/NativeAdbDataLoader/src/com/android/incremental/nativeadb/NativeAdbDataLoaderService.java
@@ -16,10 +16,10 @@
 
 package com.android.incremental.nativeadb;
 
-import android.service.incremental.IncrementalDataLoaderService;
+import android.service.dataloader.DataLoaderService;
 
 /** This code is used for testing only. */
-public class NativeAdbDataLoaderService extends IncrementalDataLoaderService {
+public class NativeAdbDataLoaderService extends DataLoaderService {
     public static final String TAG = "NativeAdbDataLoaderService";
     static {
         System.loadLibrary("nativeadbdataloaderservice_jni");
diff --git a/services/core/java/com/android/server/incremental/IncrementalManagerService.java b/services/core/java/com/android/server/incremental/IncrementalManagerService.java
index 1b1a292..789551b 100644
--- a/services/core/java/com/android/server/incremental/IncrementalManagerService.java
+++ b/services/core/java/com/android/server/incremental/IncrementalManagerService.java
@@ -19,6 +19,8 @@
 import android.annotation.NonNull;
 import android.content.Context;
 import android.content.pm.DataLoaderManager;
+import android.content.pm.DataLoaderParamsParcel;
+import android.content.pm.FileSystemControlParcel;
 import android.content.pm.IDataLoader;
 import android.content.pm.IDataLoaderStatusListener;
 import android.os.Bundle;
@@ -27,8 +29,6 @@
 import android.os.ServiceManager;
 import android.os.ShellCallback;
 import android.os.incremental.IIncrementalManager;
-import android.os.incremental.IncrementalDataLoaderParamsParcel;
-import android.os.incremental.IncrementalFileSystemControlParcel;
 import android.util.Slog;
 
 import java.io.FileDescriptor;
@@ -80,8 +80,8 @@
      * Finds data loader service provider and binds to it. This requires PackageManager.
      */
     @Override
-    public boolean prepareDataLoader(int mountId, IncrementalFileSystemControlParcel control,
-            IncrementalDataLoaderParamsParcel params,
+    public boolean prepareDataLoader(int mountId, FileSystemControlParcel control,
+            DataLoaderParamsParcel params,
             IDataLoaderStatusListener listener) {
         Bundle dataLoaderParams = new Bundle();
         dataLoaderParams.putCharSequence("packageName", params.packageName);
@@ -138,10 +138,6 @@
             Slog.e(TAG, "Failed to retrieve data loader for ID=" + mountId);
             return;
         }
-        try {
-            dataLoader.onFileCreated(inode, metadata);
-        } catch (RemoteException ex) {
-        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/incremental/IncrementalManagerShellCommand.java b/services/core/java/com/android/server/incremental/IncrementalManagerShellCommand.java
index d35e806..6a8434a 100644
--- a/services/core/java/com/android/server/incremental/IncrementalManagerShellCommand.java
+++ b/services/core/java/com/android/server/incremental/IncrementalManagerShellCommand.java
@@ -24,6 +24,7 @@
 import android.content.IIntentSender;
 import android.content.Intent;
 import android.content.IntentSender;
+import android.content.pm.DataLoaderParams;
 import android.content.pm.InstallationFile;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
@@ -31,7 +32,6 @@
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.ShellCommand;
-import android.os.incremental.IncrementalDataLoaderParams;
 import android.util.Slog;
 
 import java.io.FileDescriptor;
@@ -111,7 +111,7 @@
             pw.println("File names and sizes don't match.");
             return ERROR_DATA_LOADER_INIT;
         }
-        final IncrementalDataLoaderParams params = new IncrementalDataLoaderParams(
+        final DataLoaderParams params = new DataLoaderParams(
                 "", LOADER_PACKAGE_NAME, dataLoaderDynamicArgs);
         PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams(
                 PackageInstaller.SessionParams.MODE_FULL_INSTALL);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 286d291..dfdc29c 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -57,6 +57,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.IPackageInstallerSession;
+import android.content.pm.IPackageInstallerSessionFileSystemConnector;
 import android.content.pm.InstallationFile;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageInstaller;
@@ -1003,6 +1004,21 @@
         mHandler.obtainMessage(MSG_COMMIT).sendToTarget();
     }
 
+    private class FileSystemConnector extends IPackageInstallerSessionFileSystemConnector.Stub {
+        @Override
+        public void writeData(String name, long offsetBytes, long lengthBytes,
+                ParcelFileDescriptor incomingFd) {
+            if (incomingFd == null) {
+                throw new IllegalArgumentException("incomingFd can't be null");
+            }
+            try {
+                doWriteInternal(name, offsetBytes, lengthBytes, incomingFd);
+            } catch (IOException e) {
+                throw ExceptionUtils.wrap(e);
+            }
+        }
+    }
+
     private class ChildStatusIntentReceiver {
         private final SparseIntArray mChildSessionsRemaining;
         private final IntentSender mStatusReceiver;
@@ -2405,7 +2421,7 @@
             return;
         }
 
-        FilesystemConnector connector = new FilesystemConnector();
+        FileSystemConnector connector = new FileSystemConnector();
 
         FileInfo[] addedFiles = mFiles.stream().filter(
                 file -> sAddedFilter.accept(new File(file.name))).toArray(FileInfo[]::new);
@@ -2430,19 +2446,11 @@
         }
     }
 
-    // TODO(b/146080380): implement DataLoader using Incremental infrastructure.
-    class FilesystemConnector {
-        void writeData(FileInfo fileInfo, long offset, long lengthBytes,
-                ParcelFileDescriptor incomingFd) throws IOException {
-            doWriteInternal(fileInfo.name, offset, lengthBytes, incomingFd);
-        }
-    }
-
     static class DataLoader {
         private ParcelFileDescriptor mInFd = null;
-        private FilesystemConnector mConnector = null;
+        private FileSystemConnector mConnector = null;
 
-        void onCreate(FilesystemConnector connector) throws IOException {
+        void onCreate(FileSystemConnector connector) throws IOException {
             mConnector = connector;
         }
 
@@ -2460,14 +2468,14 @@
                         return false;
                     }
                     ParcelFileDescriptor inFd = ParcelFileDescriptor.dup(mInFd.getFileDescriptor());
-                    mConnector.writeData(fileInfo, 0, fileInfo.lengthBytes, inFd);
+                    mConnector.writeData(fileInfo.name, 0, fileInfo.lengthBytes, inFd);
                 } else {
                     File localFile = new File(filePath);
                     ParcelFileDescriptor incomingFd = null;
                     try {
                         incomingFd = ParcelFileDescriptor.open(localFile,
                                 ParcelFileDescriptor.MODE_READ_ONLY);
-                        mConnector.writeData(fileInfo, 0, localFile.length(), incomingFd);
+                        mConnector.writeData(fileInfo.name, 0, localFile.length(), incomingFd);
                     } finally {
                         IoUtils.closeQuietly(incomingFd);
                     }