Merge "make IDataLoaderManager and IDataLoader stable interfaces" into rvc-dev am: ecd96c2be4 am: 1716f68245

Change-Id: I523a06731beef6833169b73015f8bbd2bace847b
This commit is contained in:
Automerger Merge Worker
2020-03-04 23:13:57 +00:00
15 changed files with 146 additions and 139 deletions

View File

@@ -966,6 +966,10 @@ filegroup {
"core/java/android/content/pm/DataLoaderParamsParcel.aidl", "core/java/android/content/pm/DataLoaderParamsParcel.aidl",
"core/java/android/content/pm/DataLoaderType.aidl", "core/java/android/content/pm/DataLoaderType.aidl",
"core/java/android/content/pm/FileSystemControlParcel.aidl", "core/java/android/content/pm/FileSystemControlParcel.aidl",
"core/java/android/content/pm/IDataLoader.aidl",
"core/java/android/content/pm/IDataLoaderManager.aidl",
"core/java/android/content/pm/InstallationFileParcel.aidl",
"core/java/android/content/pm/InstallationFileLocation.aidl",
"core/java/android/content/pm/IDataLoaderStatusListener.aidl", "core/java/android/content/pm/IDataLoaderStatusListener.aidl",
"core/java/android/content/pm/IPackageInstallerSessionFileSystemConnector.aidl", "core/java/android/content/pm/IPackageInstallerSessionFileSystemConnector.aidl",
"core/java/android/content/pm/NamedParcelFileDescriptor.aidl", "core/java/android/content/pm/NamedParcelFileDescriptor.aidl",

View File

@@ -2018,16 +2018,13 @@ package android.content.pm {
method @NonNull public final int getType(); method @NonNull public final int getType();
} }
public final class InstallationFile implements android.os.Parcelable { public final class InstallationFile {
ctor public InstallationFile(int, @NonNull String, long, @Nullable byte[], @Nullable byte[]); ctor public InstallationFile(int, @NonNull String, long, @Nullable byte[], @Nullable byte[]);
method public int describeContents();
method public long getLengthBytes(); method public long getLengthBytes();
method public int getLocation(); method public int getLocation();
method @Nullable public byte[] getMetadata(); method @Nullable public byte[] getMetadata();
method @NonNull public String getName(); method @NonNull public String getName();
method @Nullable public byte[] getSignature(); method @Nullable public byte[] getSignature();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.InstallationFile> CREATOR;
} }
public final class InstantAppInfo implements android.os.Parcelable { public final class InstantAppInfo implements android.os.Parcelable {

View File

@@ -18,7 +18,6 @@ package android.content.pm;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.os.Bundle;
import android.os.RemoteException; import android.os.RemoteException;
/** /**
@@ -40,22 +39,19 @@ public class DataLoaderManager {
* Finds a data loader binder service and binds to it. This requires PackageManager. * Finds a data loader binder service and binds to it. This requires PackageManager.
* *
* @param dataLoaderId ID for the new data loader binder service. * @param dataLoaderId ID for the new data loader binder service.
* @param params Bundle that contains parameters to configure the data loader service. * @param params DataLoaderParamsParcel object that contains data loader params, including
* Must contain: * its package name, class name, and additional parameters.
* key: "packageName", value: String, package name of data loader service * @param control FileSystemControlParcel that contains filesystem control handlers.
* package;
* key: "extras", value: Bundle, client-specific data structures
*
* @param listener Callback for the data loader service to report status back to the * @param listener Callback for the data loader service to report status back to the
* caller. * caller.
* @return false if 1) target ID collides with a data loader that is already bound to data * @return false if 1) target ID collides with a data loader that is already bound to data
* loader manager; 2) package name is not specified; 3) fails to find data loader package; * loader manager; 2) package name is not specified; 3) fails to find data loader package;
* or 4) fails to bind to the specified data loader service, otherwise return true. * or 4) fails to bind to the specified data loader service, otherwise return true.
*/ */
public boolean initializeDataLoader(int dataLoaderId, @NonNull Bundle params, public boolean initializeDataLoader(int dataLoaderId, @NonNull DataLoaderParamsParcel params,
@NonNull IDataLoaderStatusListener listener) { @NonNull FileSystemControlParcel control, @NonNull IDataLoaderStatusListener listener) {
try { try {
return mService.initializeDataLoader(dataLoaderId, params, listener); return mService.initializeDataLoader(dataLoaderId, params, control, listener);
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} }

View File

@@ -16,20 +16,22 @@
package android.content.pm; package android.content.pm;
import android.os.Bundle; import android.content.pm.DataLoaderParamsParcel;
import android.content.pm.FileSystemControlParcel;
import android.content.pm.IDataLoaderStatusListener; import android.content.pm.IDataLoaderStatusListener;
import android.content.pm.InstallationFile; import android.content.pm.InstallationFileParcel;
import java.util.List; import java.util.List;
/** /**
* TODO: update with new APIs
* @hide * @hide
*/ */
oneway interface IDataLoader { oneway interface IDataLoader {
void create(int id, in Bundle params, IDataLoaderStatusListener listener); void create(int id, in DataLoaderParamsParcel params,
in FileSystemControlParcel control,
IDataLoaderStatusListener listener);
void start(); void start();
void stop(); void stop();
void destroy(); void destroy();
void prepareImage(in List<InstallationFile> addedFiles, in List<String> removedFiles); void prepareImage(in InstallationFileParcel[] addedFiles, in @utf8InCpp String[] removedFiles);
} }

View File

@@ -16,14 +16,15 @@
package android.content.pm; package android.content.pm;
import android.os.Bundle; import android.content.pm.DataLoaderParamsParcel;
import android.content.pm.FileSystemControlParcel;
import android.content.pm.IDataLoader; import android.content.pm.IDataLoader;
import android.content.pm.IDataLoaderStatusListener; import android.content.pm.IDataLoaderStatusListener;
import java.util.List;
/** @hide */ /** @hide */
interface IDataLoaderManager { interface IDataLoaderManager {
boolean initializeDataLoader(int id, in Bundle params, IDataLoaderStatusListener listener); boolean initializeDataLoader(int id, in DataLoaderParamsParcel params,
in FileSystemControlParcel control, IDataLoaderStatusListener listener);
IDataLoader getDataLoader(int dataLoaderId); IDataLoader getDataLoader(int dataLoaderId);
void destroyDataLoader(int dataLoaderId); void destroyDataLoader(int dataLoaderId);
} }

View File

@@ -19,81 +19,47 @@ package android.content.pm;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.SystemApi; import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
/** /**
* Defines the properties of a file in an installation session. * Defines the properties of a file in an installation session.
* @hide * @hide
*/ */
@SystemApi @SystemApi
public final class InstallationFile implements Parcelable { public final class InstallationFile {
private final @PackageInstaller.FileLocation int mLocation; private final @NonNull InstallationFileParcel mParcel;
private final @NonNull String mName;
private final long mLengthBytes;
private final @Nullable byte[] mMetadata;
private final @Nullable byte[] mSignature;
public InstallationFile(@PackageInstaller.FileLocation int location, @NonNull String name, public InstallationFile(@PackageInstaller.FileLocation int location, @NonNull String name,
long lengthBytes, @Nullable byte[] metadata, @Nullable byte[] signature) { long lengthBytes, @Nullable byte[] metadata, @Nullable byte[] signature) {
mLocation = location; mParcel = new InstallationFileParcel();
mName = name; mParcel.location = location;
mLengthBytes = lengthBytes; mParcel.name = name;
mMetadata = metadata; mParcel.size = lengthBytes;
mSignature = signature; mParcel.metadata = metadata;
mParcel.signature = signature;
} }
public @PackageInstaller.FileLocation int getLocation() { public @PackageInstaller.FileLocation int getLocation() {
return mLocation; return mParcel.location;
} }
public @NonNull String getName() { public @NonNull String getName() {
return mName; return mParcel.name;
} }
public long getLengthBytes() { public long getLengthBytes() {
return mLengthBytes; return mParcel.size;
} }
public @Nullable byte[] getMetadata() { public @Nullable byte[] getMetadata() {
return mMetadata; return mParcel.metadata;
} }
public @Nullable byte[] getSignature() { public @Nullable byte[] getSignature() {
return mSignature; return mParcel.signature;
} }
private InstallationFile(Parcel source) { /** @hide */
mLocation = source.readInt(); public @NonNull InstallationFileParcel getData() {
mName = source.readString(); return mParcel;
mLengthBytes = source.readLong();
mMetadata = source.createByteArray();
mSignature = source.createByteArray();
} }
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mLocation);
dest.writeString(mName);
dest.writeLong(mLengthBytes);
dest.writeByteArray(mMetadata);
dest.writeByteArray(mSignature);
}
public static final @NonNull Creator<InstallationFile> CREATOR =
new Creator<InstallationFile>() {
public InstallationFile createFromParcel(Parcel source) {
return new InstallationFile(source);
}
public InstallationFile[] newArray(int size) {
return new InstallationFile[size];
}
};
} }

View File

@@ -0,0 +1,26 @@
/*
* Copyright (C) 2020 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;
/** @hide */
@Backing(type="int")
enum InstallationFileLocation {
UNKNOWN = -1,
DATA_APP = 0,
MEDIA_OBB = 1,
MEDIA_DATA = 2
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2020 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.InstallationFileLocation;
/**
* Describes a file which is part of a package installation.
* @hide
*/
parcelable InstallationFileParcel {
String name;
InstallationFileLocation location;
long size;
byte[] metadata;
byte[] signature;
}

View File

@@ -372,7 +372,7 @@ public class PackageInstaller {
* {@hide} * {@hide}
*/ */
@SystemApi @SystemApi
public static final int LOCATION_DATA_APP = 0; public static final int LOCATION_DATA_APP = InstallationFileLocation.DATA_APP;
/** /**
* Target location for the file in installation session is * Target location for the file in installation session is
@@ -380,7 +380,7 @@ public class PackageInstaller {
* {@hide} * {@hide}
*/ */
@SystemApi @SystemApi
public static final int LOCATION_MEDIA_OBB = 1; public static final int LOCATION_MEDIA_OBB = InstallationFileLocation.MEDIA_OBB;
/** /**
* Target location for the file in installation session is * Target location for the file in installation session is
@@ -390,7 +390,7 @@ public class PackageInstaller {
* {@hide} * {@hide}
*/ */
@SystemApi @SystemApi
public static final int LOCATION_MEDIA_DATA = 2; public static final int LOCATION_MEDIA_DATA = InstallationFileLocation.MEDIA_DATA;
/** @hide */ /** @hide */
@IntDef(prefix = { "LOCATION_" }, value = { @IntDef(prefix = { "LOCATION_" }, value = {

View File

@@ -36,7 +36,7 @@ import android.annotation.Nullable;
import android.content.Context; import android.content.Context;
import android.content.pm.DataLoaderParams; import android.content.pm.DataLoaderParams;
import android.content.pm.IDataLoaderStatusListener; import android.content.pm.IDataLoaderStatusListener;
import android.content.pm.InstallationFile; import android.content.pm.InstallationFileParcel;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Slog; import android.util.Slog;
@@ -76,7 +76,7 @@ public final class IncrementalFileStorages {
@NonNull File stageDir, @NonNull File stageDir,
@NonNull DataLoaderParams dataLoaderParams, @NonNull DataLoaderParams dataLoaderParams,
@Nullable IDataLoaderStatusListener dataLoaderStatusListener, @Nullable IDataLoaderStatusListener dataLoaderStatusListener,
List<InstallationFile> addedFiles) throws IOException { List<InstallationFileParcel> addedFiles) throws IOException {
// TODO(b/136132412): sanity check if session should not be incremental // TODO(b/136132412): sanity check if session should not be incremental
IncrementalManager incrementalManager = (IncrementalManager) context.getSystemService( IncrementalManager incrementalManager = (IncrementalManager) context.getSystemService(
Context.INCREMENTAL_SERVICE); Context.INCREMENTAL_SERVICE);
@@ -94,17 +94,17 @@ public final class IncrementalFileStorages {
result.mDefaultStorage.bind(stageDir.getAbsolutePath()); result.mDefaultStorage.bind(stageDir.getAbsolutePath());
} }
for (InstallationFile file : addedFiles) { for (InstallationFileParcel file : addedFiles) {
if (file.getLocation() == LOCATION_DATA_APP) { if (file.location == LOCATION_DATA_APP) {
try { try {
result.addApkFile(file); result.addApkFile(file);
} catch (IOException e) { } catch (IOException e) {
// TODO(b/146080380): add incremental-specific error code // TODO(b/146080380): add incremental-specific error code
throw new IOException( throw new IOException(
"Failed to add file to IncFS: " + file.getName() + ", reason: ", e); "Failed to add file to IncFS: " + file.name + ", reason: ", e);
} }
} else { } else {
throw new IOException("Unknown file location: " + file.getLocation()); throw new IOException("Unknown file location: " + file.location);
} }
} }
@@ -154,12 +154,11 @@ public final class IncrementalFileStorages {
} }
} }
private void addApkFile(@NonNull InstallationFile apk) throws IOException { private void addApkFile(@NonNull InstallationFileParcel apk) throws IOException {
final String apkName = apk.getName(); final String apkName = apk.name;
final File targetFile = new File(mStageDir, apkName); final File targetFile = new File(mStageDir, apkName);
if (!targetFile.exists()) { if (!targetFile.exists()) {
mDefaultStorage.makeFile(apkName, apk.getLengthBytes(), null, apk.getMetadata(), mDefaultStorage.makeFile(apkName, apk.size, null, apk.metadata, apk.signature);
apk.getSignature());
} }
} }

View File

@@ -27,8 +27,8 @@ import android.content.pm.FileSystemControlParcel;
import android.content.pm.IDataLoader; import android.content.pm.IDataLoader;
import android.content.pm.IDataLoaderStatusListener; import android.content.pm.IDataLoaderStatusListener;
import android.content.pm.InstallationFile; import android.content.pm.InstallationFile;
import android.content.pm.InstallationFileParcel;
import android.content.pm.NamedParcelFileDescriptor; import android.content.pm.NamedParcelFileDescriptor;
import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.util.ExceptionUtils; import android.util.ExceptionUtils;
@@ -36,7 +36,6 @@ import android.util.Slog;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.List;
/** /**
* The base class for implementing data loader service to control data loaders. Expecting * The base class for implementing data loader service to control data loaders. Expecting
@@ -105,18 +104,11 @@ public abstract class DataLoaderService extends Service {
private int mId; private int mId;
@Override @Override
public void create(int id, @NonNull Bundle options, public void create(int id, @NonNull DataLoaderParamsParcel params,
@NonNull FileSystemControlParcel control,
@NonNull IDataLoaderStatusListener listener) @NonNull IDataLoaderStatusListener listener)
throws IllegalArgumentException, RuntimeException { throws RuntimeException {
mId = id; mId = id;
final DataLoaderParamsParcel params = options.getParcelable("params");
if (params == null) {
throw new IllegalArgumentException("Must specify data loader params");
}
final FileSystemControlParcel control = options.getParcelable("control");
if (control == null) {
throw new IllegalArgumentException("Must specify control parcel");
}
try { try {
if (!nativeCreateDataLoader(id, control, params, listener)) { if (!nativeCreateDataLoader(id, control, params, listener)) {
Slog.e(TAG, "Failed to create native loader for " + mId); Slog.e(TAG, "Failed to create native loader for " + mId);
@@ -178,7 +170,7 @@ public abstract class DataLoaderService extends Service {
} }
@Override @Override
public void prepareImage(List<InstallationFile> addedFiles, List<String> removedFiles) { public void prepareImage(InstallationFileParcel[] addedFiles, String[] removedFiles) {
if (!nativePrepareImage(mId, addedFiles, removedFiles)) { if (!nativePrepareImage(mId, addedFiles, removedFiles)) {
Slog.w(TAG, "Failed to destroy loader: " + mId); Slog.w(TAG, "Failed to destroy loader: " + mId);
} }
@@ -240,7 +232,7 @@ public abstract class DataLoaderService extends Service {
private native boolean nativeDestroyDataLoader(int storageId); private native boolean nativeDestroyDataLoader(int storageId);
private native boolean nativePrepareImage(int storageId, private native boolean nativePrepareImage(int storageId,
List<InstallationFile> addedFiles, List<String> removedFiles); InstallationFileParcel[] addedFiles, String[] removedFiles);
private static native void nativeWriteData(long nativeInstance, String name, long offsetBytes, private static native void nativeWriteData(long nativeInstance, String name, long offsetBytes,
long lengthBytes, ParcelFileDescriptor incomingFd); long lengthBytes, ParcelFileDescriptor incomingFd);

View File

@@ -50,8 +50,8 @@ static jboolean nativeDestroyDataLoader(JNIEnv* env,
return DataLoaderService_OnDestroy(env, storageId); return DataLoaderService_OnDestroy(env, storageId);
} }
static jboolean nativePrepareImage(JNIEnv* env, jobject thiz, jint storageId,
static jboolean nativePrepareImage(JNIEnv* env, jobject thiz, jint storageId, jobject addedFiles, jobject removedFiles) { jobjectArray addedFiles, jobjectArray removedFiles) {
return DataLoaderService_OnPrepareImage(env, storageId, addedFiles, removedFiles); return DataLoaderService_OnPrepareImage(env, storageId, addedFiles, removedFiles);
} }
@@ -75,7 +75,9 @@ static const JNINativeMethod dlc_method_table[] = {
{"nativeStartDataLoader", "(I)Z", (void*)nativeStartDataLoader}, {"nativeStartDataLoader", "(I)Z", (void*)nativeStartDataLoader},
{"nativeStopDataLoader", "(I)Z", (void*)nativeStopDataLoader}, {"nativeStopDataLoader", "(I)Z", (void*)nativeStopDataLoader},
{"nativeDestroyDataLoader", "(I)Z", (void*)nativeDestroyDataLoader}, {"nativeDestroyDataLoader", "(I)Z", (void*)nativeDestroyDataLoader},
{"nativePrepareImage", "(ILjava/util/List;Ljava/util/List;)Z", (void*)nativePrepareImage}, {"nativePrepareImage",
"(I[Landroid/content/pm/InstallationFileParcel;[Ljava/lang/String;)Z",
(void*)nativePrepareImage},
{"nativeWriteData", "(JLjava/lang/String;JJLandroid/os/ParcelFileDescriptor;)V", {"nativeWriteData", "(JLjava/lang/String;JJLandroid/os/ParcelFileDescriptor;)V",
(void*)nativeWriteData}, (void*)nativeWriteData},
}; };

View File

@@ -17,14 +17,12 @@
package com.android.server.incremental; package com.android.server.incremental;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.pm.DataLoaderManager; import android.content.pm.DataLoaderManager;
import android.content.pm.DataLoaderParamsParcel; import android.content.pm.DataLoaderParamsParcel;
import android.content.pm.FileSystemControlParcel; import android.content.pm.FileSystemControlParcel;
import android.content.pm.IDataLoader; import android.content.pm.IDataLoader;
import android.content.pm.IDataLoaderStatusListener; import android.content.pm.IDataLoaderStatusListener;
import android.os.Bundle;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.os.incremental.IIncrementalManager; import android.os.incremental.IIncrementalManager;
@@ -93,17 +91,12 @@ public class IncrementalManagerService extends IIncrementalManager.Stub {
public boolean prepareDataLoader(int mountId, FileSystemControlParcel control, public boolean prepareDataLoader(int mountId, FileSystemControlParcel control,
DataLoaderParamsParcel params, DataLoaderParamsParcel params,
IDataLoaderStatusListener listener) { IDataLoaderStatusListener listener) {
Bundle dataLoaderParams = new Bundle();
dataLoaderParams.putParcelable("componentName",
new ComponentName(params.packageName, params.className));
dataLoaderParams.putParcelable("control", control);
dataLoaderParams.putParcelable("params", params);
DataLoaderManager dataLoaderManager = mContext.getSystemService(DataLoaderManager.class); DataLoaderManager dataLoaderManager = mContext.getSystemService(DataLoaderManager.class);
if (dataLoaderManager == null) { if (dataLoaderManager == null) {
Slog.e(TAG, "Failed to find data loader manager service"); Slog.e(TAG, "Failed to find data loader manager service");
return false; return false;
} }
if (!dataLoaderManager.initializeDataLoader(mountId, dataLoaderParams, listener)) { if (!dataLoaderManager.initializeDataLoader(mountId, params, control, listener)) {
Slog.e(TAG, "Failed to initialize data loader"); Slog.e(TAG, "Failed to initialize data loader");
return false; return false;
} }

View File

@@ -22,12 +22,13 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.DataLoaderParamsParcel;
import android.content.pm.FileSystemControlParcel;
import android.content.pm.IDataLoader; import android.content.pm.IDataLoader;
import android.content.pm.IDataLoaderManager; import android.content.pm.IDataLoaderManager;
import android.content.pm.IDataLoaderStatusListener; import android.content.pm.IDataLoaderStatusListener;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
@@ -65,26 +66,22 @@ public class DataLoaderManagerService extends SystemService {
final class DataLoaderManagerBinderService extends IDataLoaderManager.Stub { final class DataLoaderManagerBinderService extends IDataLoaderManager.Stub {
@Override @Override
public boolean initializeDataLoader(int dataLoaderId, Bundle params, public boolean initializeDataLoader(int dataLoaderId, DataLoaderParamsParcel params,
IDataLoaderStatusListener listener) { FileSystemControlParcel control, IDataLoaderStatusListener listener) {
synchronized (mLock) { synchronized (mLock) {
if (mServiceConnections.get(dataLoaderId) != null) { if (mServiceConnections.get(dataLoaderId) != null) {
Slog.e(TAG, "Data loader of ID=" + dataLoaderId + " already exists."); Slog.e(TAG, "Data loader of ID=" + dataLoaderId + " already exists.");
return false; return false;
} }
} }
ComponentName componentName = params.getParcelable("componentName"); ComponentName componentName = new ComponentName(params.packageName, params.className);
if (componentName == null) {
Slog.e(TAG, "Must specify component name.");
return false;
}
ComponentName dataLoaderComponent = resolveDataLoaderComponentName(componentName); ComponentName dataLoaderComponent = resolveDataLoaderComponentName(componentName);
if (dataLoaderComponent == null) { if (dataLoaderComponent == null) {
return false; return false;
} }
// Binds to the specific data loader service // Binds to the specific data loader service
DataLoaderServiceConnection connection = DataLoaderServiceConnection connection =
new DataLoaderServiceConnection(dataLoaderId, params, listener); new DataLoaderServiceConnection(dataLoaderId, params, control, listener);
Intent intent = new Intent(); Intent intent = new Intent();
intent.setComponent(dataLoaderComponent); intent.setComponent(dataLoaderComponent);
if (!mContext.bindServiceAsUser(intent, connection, Context.BIND_AUTO_CREATE, if (!mContext.bindServiceAsUser(intent, connection, Context.BIND_AUTO_CREATE,
@@ -181,13 +178,16 @@ public class DataLoaderManagerService extends SystemService {
class DataLoaderServiceConnection implements ServiceConnection { class DataLoaderServiceConnection implements ServiceConnection {
final int mId; final int mId;
final Bundle mParams; final DataLoaderParamsParcel mParams;
final FileSystemControlParcel mControl;
final IDataLoaderStatusListener mListener; final IDataLoaderStatusListener mListener;
IDataLoader mDataLoader; IDataLoader mDataLoader;
DataLoaderServiceConnection(int id, Bundle params, IDataLoaderStatusListener listener) { DataLoaderServiceConnection(int id, DataLoaderParamsParcel params,
FileSystemControlParcel control, IDataLoaderStatusListener listener) {
mId = id; mId = id;
mParams = params; mParams = params;
mControl = control;
mListener = listener; mListener = listener;
mDataLoader = null; mDataLoader = null;
} }
@@ -199,7 +199,7 @@ public class DataLoaderManagerService extends SystemService {
mServiceConnections.append(mId, this); mServiceConnections.append(mId, this);
} }
try { try {
mDataLoader.create(mId, mParams, mListener); mDataLoader.create(mId, mParams, mControl, mListener);
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.e(TAG, "Failed to create data loader service.", e); Slog.e(TAG, "Failed to create data loader service.", e);
} }
@@ -226,7 +226,6 @@ public class DataLoaderManagerService extends SystemService {
synchronized (mLock) { synchronized (mLock) {
mServiceConnections.remove(mId); mServiceConnections.remove(mId);
} }
mParams.clear();
} }
} }
} }

View File

@@ -69,6 +69,7 @@ import android.content.pm.IPackageInstallObserver2;
import android.content.pm.IPackageInstallerSession; import android.content.pm.IPackageInstallerSession;
import android.content.pm.IPackageInstallerSessionFileSystemConnector; import android.content.pm.IPackageInstallerSessionFileSystemConnector;
import android.content.pm.InstallationFile; import android.content.pm.InstallationFile;
import android.content.pm.InstallationFileParcel;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller; import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionInfo; import android.content.pm.PackageInstaller.SessionInfo;
@@ -1052,9 +1053,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
IPackageInstallerSessionFileSystemConnector.Stub { IPackageInstallerSessionFileSystemConnector.Stub {
final Set<String> mAddedFiles = new ArraySet<>(); final Set<String> mAddedFiles = new ArraySet<>();
FileSystemConnector(List<InstallationFile> addedFiles) { FileSystemConnector(List<InstallationFileParcel> addedFiles) {
for (InstallationFile file : addedFiles) { for (InstallationFileParcel file : addedFiles) {
mAddedFiles.add(file.getName()); mAddedFiles.add(file.name);
} }
} }
@@ -2444,14 +2445,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
return true; return true;
} }
final List<InstallationFile> addedFiles = new ArrayList<>(mFiles.size()); final List<InstallationFileParcel> addedFiles = new ArrayList<>();
final List<String> removedFiles = new ArrayList<>();
for (InstallationFile file : mFiles) { for (InstallationFile file : mFiles) {
if (sAddedFilter.accept(new File(this.stageDir, file.getName()))) { if (sAddedFilter.accept(new File(this.stageDir, file.getName()))) {
addedFiles.add(file); addedFiles.add(file.getData());
continue;
} }
}
final List<String> removedFiles = new ArrayList<>(mFiles.size());
for (InstallationFile file : mFiles) {
if (sRemovedFilter.accept(new File(this.stageDir, file.getName()))) { if (sRemovedFilter.accept(new File(this.stageDir, file.getName()))) {
String name = file.getName().substring( String name = file.getName().substring(
0, file.getName().length() - REMOVE_MARKER_EXTENSION.length()); 0, file.getName().length() - REMOVE_MARKER_EXTENSION.length());
@@ -2494,7 +2495,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
break; break;
} }
case IDataLoaderStatusListener.DATA_LOADER_STARTED: { case IDataLoaderStatusListener.DATA_LOADER_STARTED: {
dataLoader.prepareImage(addedFiles, removedFiles); dataLoader.prepareImage(
addedFiles.toArray(
new InstallationFileParcel[addedFiles.size()]),
removedFiles.toArray(new String[removedFiles.size()]));
break; break;
} }
case IDataLoaderStatusListener.DATA_LOADER_IMAGE_READY: { case IDataLoaderStatusListener.DATA_LOADER_IMAGE_READY: {
@@ -2547,13 +2551,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
control.callback = connector; control.callback = connector;
final DataLoaderParams params = this.params.dataLoaderParams; final DataLoaderParams params = this.params.dataLoaderParams;
if (!dataLoaderManager.initializeDataLoader(
Bundle dataLoaderParams = new Bundle(); sessionId, params.getData(), control, listener)) {
dataLoaderParams.putParcelable("componentName", params.getComponentName());
dataLoaderParams.putParcelable("control", control);
dataLoaderParams.putParcelable("params", params.getData());
if (!dataLoaderManager.initializeDataLoader(sessionId, dataLoaderParams, listener)) {
throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE, throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE,
"Failed to initialize data loader"); "Failed to initialize data loader");
} }