summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/java/android/app/ApplicationPackageManager.java4
-rw-r--r--core/java/android/content/pm/IPackageInstaller.aidl8
-rw-r--r--core/java/android/content/pm/PackageInstaller.java18
-rw-r--r--core/java/android/content/pm/PackageInstallerParams.java24
-rw-r--r--core/java/android/content/pm/PackageParser.java11
-rw-r--r--core/java/android/content/pm/Signature.java3
-rw-r--r--core/java/android/os/FileBridge.java29
-rw-r--r--core/java/com/android/internal/util/SizedInputStream.java66
8 files changed, 128 insertions, 35 deletions
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 97f1e50..2935b8e 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1463,8 +1463,8 @@ final class ApplicationPackageManager extends PackageManager {
@Override
public PackageInstaller getPackageInstaller() {
try {
- return new PackageInstaller(this, mPM.getPackageInstaller(), mContext.getUserId(),
- mContext.getPackageName());
+ return new PackageInstaller(this, mPM.getPackageInstaller(), mContext.getPackageName(),
+ mContext.getUserId());
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
diff --git a/core/java/android/content/pm/IPackageInstaller.aidl b/core/java/android/content/pm/IPackageInstaller.aidl
index 68c019b..4d6ee64 100644
--- a/core/java/android/content/pm/IPackageInstaller.aidl
+++ b/core/java/android/content/pm/IPackageInstaller.aidl
@@ -23,11 +23,11 @@ import android.os.ParcelFileDescriptor;
/** {@hide} */
interface IPackageInstaller {
- int createSession(int userId, String installerPackageName, in PackageInstallerParams params);
+ int createSession(String installerPackageName, in PackageInstallerParams params, int userId);
IPackageInstallerSession openSession(int sessionId);
- int[] getSessions(int userId, String installerPackageName);
+ int[] getSessions(String installerPackageName, int userId);
- void uninstall(int userId, String basePackageName, in IPackageDeleteObserver observer);
- void uninstallSplit(int userId, String basePackageName, String splitName, in IPackageDeleteObserver observer);
+ void uninstall(String basePackageName, int flags, in IPackageDeleteObserver observer, int userId);
+ void uninstallSplit(String basePackageName, String splitName, int flags, in IPackageDeleteObserver observer, int userId);
}
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 4672015..a60a2fe 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -23,6 +23,7 @@ import android.os.FileBridge;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
+import java.io.Closeable;
import java.io.OutputStream;
/** {@hide} */
@@ -33,12 +34,12 @@ public class PackageInstaller {
private final String mInstallerPackageName;
/** {@hide} */
- public PackageInstaller(PackageManager pm, IPackageInstaller installer, int userId,
- String installerPackageName) {
+ public PackageInstaller(PackageManager pm, IPackageInstaller installer,
+ String installerPackageName, int userId) {
mPm = pm;
mInstaller = installer;
- mUserId = userId;
mInstallerPackageName = installerPackageName;
+ mUserId = userId;
}
public boolean isPackageAvailable(String basePackageName) {
@@ -63,7 +64,7 @@ public class PackageInstaller {
public int createSession(PackageInstallerParams params) {
try {
- return mInstaller.createSession(mUserId, mInstallerPackageName, params);
+ return mInstaller.createSession(mInstallerPackageName, params, mUserId);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -79,7 +80,7 @@ public class PackageInstaller {
public int[] getSessions() {
try {
- return mInstaller.getSessions(mUserId, mInstallerPackageName);
+ return mInstaller.getSessions(mInstallerPackageName, mUserId);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -87,7 +88,7 @@ public class PackageInstaller {
public void uninstall(String basePackageName, PackageUninstallObserver observer) {
try {
- mInstaller.uninstall(mUserId, basePackageName, observer.getBinder());
+ mInstaller.uninstall(basePackageName, 0, observer.getBinder(), mUserId);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -96,7 +97,7 @@ public class PackageInstaller {
public void uninstall(String basePackageName, String splitName,
PackageUninstallObserver observer) {
try {
- mInstaller.uninstallSplit(mUserId, basePackageName, splitName, observer.getBinder());
+ mInstaller.uninstallSplit(basePackageName, splitName, 0, observer.getBinder(), mUserId);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -114,7 +115,7 @@ public class PackageInstaller {
* installation (for example, the same split name), the package in this
* session will replace the existing package.
*/
- public class Session {
+ public static class Session implements Closeable {
private IPackageInstallerSession mSession;
/** {@hide} */
@@ -154,6 +155,7 @@ public class PackageInstaller {
}
}
+ @Override
public void close() {
// No resources to release at the moment
}
diff --git a/core/java/android/content/pm/PackageInstallerParams.java b/core/java/android/content/pm/PackageInstallerParams.java
index 67cf276..527edee 100644
--- a/core/java/android/content/pm/PackageInstallerParams.java
+++ b/core/java/android/content/pm/PackageInstallerParams.java
@@ -41,6 +41,8 @@ public class PackageInstallerParams implements Parcelable {
/** {@hide} */
public long deltaSize = -1;
/** {@hide} */
+ public String basePackageName;
+ /** {@hide} */
public Bitmap icon;
/** {@hide} */
public String title;
@@ -48,23 +50,27 @@ public class PackageInstallerParams implements Parcelable {
public Uri originatingUri;
/** {@hide} */
public Uri referrerUri;
+ /** {@hide} */
+ public String abiOverride;
public PackageInstallerParams() {
}
/** {@hide} */
public PackageInstallerParams(Parcel source) {
- this.fullInstall = source.readInt() != 0;
- this.installFlags = source.readInt();
- this.installLocation = source.readInt();
- this.signatures = (Signature[]) source.readParcelableArray(null);
+ fullInstall = source.readInt() != 0;
+ installFlags = source.readInt();
+ installLocation = source.readInt();
+ signatures = (Signature[]) source.readParcelableArray(null);
deltaSize = source.readLong();
+ basePackageName = source.readString();
if (source.readInt() != 0) {
icon = Bitmap.CREATOR.createFromParcel(source);
}
title = source.readString();
- originatingUri = Uri.CREATOR.createFromParcel(source);
- referrerUri = Uri.CREATOR.createFromParcel(source);
+ originatingUri = source.readParcelable(null);
+ referrerUri = source.readParcelable(null);
+ abiOverride = source.readString();
}
public void setFullInstall(boolean fullInstall) {
@@ -87,6 +93,10 @@ public class PackageInstallerParams implements Parcelable {
this.deltaSize = deltaSize;
}
+ public void setBasePackageName(String basePackageName) {
+ this.basePackageName = basePackageName;
+ }
+
public void setIcon(Bitmap icon) {
this.icon = icon;
}
@@ -115,6 +125,7 @@ public class PackageInstallerParams implements Parcelable {
dest.writeInt(installLocation);
dest.writeParcelableArray(signatures, flags);
dest.writeLong(deltaSize);
+ dest.writeString(basePackageName);
if (icon != null) {
dest.writeInt(1);
icon.writeToParcel(dest, flags);
@@ -124,6 +135,7 @@ public class PackageInstallerParams implements Parcelable {
dest.writeString(title);
dest.writeParcelable(originatingUri, flags);
dest.writeParcelable(referrerUri, flags);
+ dest.writeString(abiOverride);
}
public static final Parcelable.Creator<PackageInstallerParams>
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 3b118c0..ab0bf25 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -71,7 +71,6 @@ import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -923,19 +922,17 @@ public class PackageParser {
"Package " + apkPath + " has no certificates at entry "
+ entry.getName());
}
+ final Signature[] entrySignatures = convertToSignatures(entryCerts);
if (pkg.mCertificates == null) {
pkg.mCertificates = entryCerts;
- pkg.mSignatures = convertToSignatures(entryCerts);
+ pkg.mSignatures = entrySignatures;
pkg.mSigningKeys = new ArraySet<PublicKey>();
for (int i=0; i < entryCerts.length; i++) {
pkg.mSigningKeys.add(entryCerts[i][0].getPublicKey());
}
} else {
- final boolean certsMatch = (pkg.mCertificates.length == entryCerts.length)
- && ArrayUtils.containsAll(pkg.mCertificates, entryCerts)
- && ArrayUtils.containsAll(entryCerts, pkg.mCertificates);
- if (!certsMatch) {
+ if (!Signature.areExactMatch(pkg.mSignatures, entrySignatures)) {
throw new PackageParserException(
INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, "Package " + apkPath
+ " has mismatched certificates at entry "
@@ -1097,7 +1094,7 @@ public class PackageParser {
if (splitName.length() == 0) {
splitName = null;
} else {
- final String error = validateName(splitName, true);
+ final String error = validateName(splitName, false);
if (error != null) {
throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
"Invalid manifest split: " + error);
diff --git a/core/java/android/content/pm/Signature.java b/core/java/android/content/pm/Signature.java
index 96aa083..7edf4b9 100644
--- a/core/java/android/content/pm/Signature.java
+++ b/core/java/android/content/pm/Signature.java
@@ -249,6 +249,7 @@ public class Signature implements Parcelable {
* @hide
*/
public static boolean areExactMatch(Signature[] a, Signature[] b) {
- return ArrayUtils.containsAll(a, b) && ArrayUtils.containsAll(b, a);
+ return (a.length == b.length) && ArrayUtils.containsAll(a, b)
+ && ArrayUtils.containsAll(b, a);
}
}
diff --git a/core/java/android/os/FileBridge.java b/core/java/android/os/FileBridge.java
index 7f8bc9f..691afdd 100644
--- a/core/java/android/os/FileBridge.java
+++ b/core/java/android/os/FileBridge.java
@@ -54,6 +54,8 @@ public class FileBridge extends Thread {
private static final int CMD_WRITE = 1;
/** CMD_FSYNC */
private static final int CMD_FSYNC = 2;
+ /** CMD_CLOSE */
+ private static final int CMD_CLOSE = 3;
private FileDescriptor mTarget;
@@ -102,12 +104,17 @@ public class FileBridge extends Thread {
// Sync and echo back to confirm
Os.fsync(mTarget);
IoBridge.write(mServer, temp, 0, MSG_LENGTH);
+
+ } else if (cmd == CMD_CLOSE) {
+ // Close and echo back to confirm
+ Os.fsync(mTarget);
+ Os.close(mTarget);
+ mClosed = true;
+ IoBridge.write(mServer, temp, 0, MSG_LENGTH);
+ break;
}
}
- // Client was closed; one last fsync
- Os.fsync(mTarget);
-
} catch (ErrnoException e) {
Log.e(TAG, "Failed during bridge: ", e);
} catch (IOException e) {
@@ -130,22 +137,30 @@ public class FileBridge extends Thread {
@Override
public void close() throws IOException {
- IoBridge.closeAndSignalBlockedThreads(mClient);
+ try {
+ writeCommandAndBlock(CMD_CLOSE, "close()");
+ } finally {
+ IoBridge.closeAndSignalBlockedThreads(mClient);
+ }
}
@Override
public void flush() throws IOException {
- Memory.pokeInt(mTemp, 0, CMD_FSYNC, ByteOrder.BIG_ENDIAN);
+ writeCommandAndBlock(CMD_FSYNC, "fsync()");
+ }
+
+ private void writeCommandAndBlock(int cmd, String cmdString) throws IOException {
+ Memory.pokeInt(mTemp, 0, cmd, ByteOrder.BIG_ENDIAN);
IoBridge.write(mClient, mTemp, 0, MSG_LENGTH);
// Wait for server to ack
if (IoBridge.read(mClient, mTemp, 0, MSG_LENGTH) == MSG_LENGTH) {
- if (Memory.peekInt(mTemp, 0, ByteOrder.BIG_ENDIAN) == CMD_FSYNC) {
+ if (Memory.peekInt(mTemp, 0, ByteOrder.BIG_ENDIAN) == cmd) {
return;
}
}
- throw new SyncFailedException("Failed to fsync() across bridge");
+ throw new IOException("Failed to execute " + cmdString + " across bridge");
}
@Override
diff --git a/core/java/com/android/internal/util/SizedInputStream.java b/core/java/com/android/internal/util/SizedInputStream.java
new file mode 100644
index 0000000..00a729d
--- /dev/null
+++ b/core/java/com/android/internal/util/SizedInputStream.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 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 com.android.internal.util;
+
+import libcore.io.Streams;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Reads exact number of bytes from wrapped stream, returning EOF once those
+ * bytes have been read.
+ */
+public class SizedInputStream extends InputStream {
+ private final InputStream mWrapped;
+ private long mLength;
+
+ public SizedInputStream(InputStream wrapped, long length) {
+ mWrapped = wrapped;
+ mLength = length;
+ }
+
+ @Override
+ public void close() throws IOException {
+ super.close();
+ mWrapped.close();
+ }
+
+ @Override
+ public int read() throws IOException {
+ return Streams.readSingleByte(this);
+ }
+
+ @Override
+ public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
+ if (mLength <= 0) {
+ return -1;
+ } else if (byteCount > mLength) {
+ byteCount = (int) mLength;
+ }
+
+ final int n = mWrapped.read(buffer, byteOffset, byteCount);
+ if (n == -1) {
+ if (mLength > 0) {
+ throw new IOException("Unexpected EOF; expected " + mLength + " more bytes");
+ }
+ } else {
+ mLength -= n;
+ }
+ return n;
+ }
+}