summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt38
-rw-r--r--api/system-current.txt38
-rw-r--r--core/java/android/app/ActivityThread.java116
-rw-r--r--core/java/android/database/sqlite/SQLiteConnection.java17
-rw-r--r--core/java/android/net/Uri.java2
-rw-r--r--core/java/android/os/Bundle.java8
-rw-r--r--core/java/android/os/Process.java3
-rw-r--r--core/java/android/view/ViewDebug.java8
-rw-r--r--core/java/com/android/internal/os/Zygote.java2
-rw-r--r--core/java/com/android/internal/os/ZygoteConnection.java4
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java7
-rw-r--r--core/jni/AndroidRuntime.cpp13
-rw-r--r--keystore/java/android/security/AndroidKeyPairGenerator.java14
-rw-r--r--keystore/java/android/security/CryptoOperationException.java61
-rw-r--r--keystore/java/android/security/KeyExpiredException.java4
-rw-r--r--keystore/java/android/security/KeyNotYetValidException.java4
-rw-r--r--keystore/java/android/security/KeyStore.java29
-rw-r--r--keystore/java/android/security/KeyStoreCipherSpi.java107
-rw-r--r--keystore/java/android/security/KeyStoreConnectException.java2
-rw-r--r--keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java12
-rw-r--r--keystore/java/android/security/KeyStoreHmacSpi.java76
-rw-r--r--keystore/java/android/security/KeyStoreKeyGeneratorSpi.java3
-rw-r--r--keystore/java/android/security/UserNotAuthenticatedException.java4
-rw-r--r--keystore/tests/src/android/security/AndroidKeyStoreTest.java18
-rw-r--r--keystore/tests/src/android/security/KeyStoreTest.java30
-rw-r--r--libs/androidfw/ObbFile.cpp4
-rw-r--r--media/java/android/media/MediaHTTPConnection.java6
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindowManager.java5
-rw-r--r--preloaded-classes5
-rw-r--r--rs/java/android/renderscript/Script.java2
-rw-r--r--rs/java/android/renderscript/ScriptGroup.java597
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java227
-rw-r--r--tools/obbtool/pbkdf2gen.cpp1
33 files changed, 1074 insertions, 393 deletions
diff --git a/api/current.txt b/api/current.txt
index 22c9afd303f6..8d650cb51ed9 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -26520,6 +26520,7 @@ package android.renderscript {
public class Script extends android.renderscript.BaseObj {
method public void bindAllocation(android.renderscript.Allocation, int);
method protected android.renderscript.Script.FieldID createFieldID(int, android.renderscript.Element);
+ method protected android.renderscript.Script.InvokeID createInvokeID(int);
method protected android.renderscript.Script.KernelID createKernelID(int, int, android.renderscript.Element, android.renderscript.Element);
method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker);
method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
@@ -26560,6 +26561,9 @@ package android.renderscript {
public static final class Script.FieldID extends android.renderscript.BaseObj {
}
+ public static final class Script.InvokeID extends android.renderscript.BaseObj {
+ }
+
public static final class Script.KernelID extends android.renderscript.BaseObj {
}
@@ -26584,12 +26588,19 @@ package android.renderscript {
}
public final class ScriptGroup extends android.renderscript.BaseObj {
- method public void execute();
- method public void setInput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
- method public void setOutput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
+ method public java.lang.Object[] execute(java.lang.Object...);
+ method public deprecated void execute();
+ method public deprecated void setInput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
+ method public deprecated void setOutput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
}
- public static final class ScriptGroup.Builder {
+ public static final class ScriptGroup.Binding {
+ ctor public ScriptGroup.Binding(android.renderscript.Script.FieldID, java.lang.Object);
+ method public android.renderscript.Script.FieldID getField();
+ method public java.lang.Object getValue();
+ }
+
+ public static final deprecated class ScriptGroup.Builder {
ctor public ScriptGroup.Builder(android.renderscript.RenderScript);
method public android.renderscript.ScriptGroup.Builder addConnection(android.renderscript.Type, android.renderscript.Script.KernelID, android.renderscript.Script.FieldID);
method public android.renderscript.ScriptGroup.Builder addConnection(android.renderscript.Type, android.renderscript.Script.KernelID, android.renderscript.Script.KernelID);
@@ -26597,6 +26608,25 @@ package android.renderscript {
method public android.renderscript.ScriptGroup create();
}
+ public static final class ScriptGroup.Builder2 {
+ ctor public ScriptGroup.Builder2(android.renderscript.RenderScript);
+ method public android.renderscript.ScriptGroup.Input addInput();
+ method public android.renderscript.ScriptGroup.Closure addInvoke(android.renderscript.Script.InvokeID, java.lang.Object...);
+ method public android.renderscript.ScriptGroup.Closure addKernel(android.renderscript.Script.KernelID, android.renderscript.Type, java.lang.Object...);
+ method public android.renderscript.ScriptGroup create(java.lang.String, android.renderscript.ScriptGroup.Future...);
+ }
+
+ public static final class ScriptGroup.Closure extends android.renderscript.BaseObj {
+ method public android.renderscript.ScriptGroup.Future getGlobal(android.renderscript.Script.FieldID);
+ method public android.renderscript.ScriptGroup.Future getReturn();
+ }
+
+ public static final class ScriptGroup.Future {
+ }
+
+ public static final class ScriptGroup.Input {
+ }
+
public abstract class ScriptIntrinsic extends android.renderscript.Script {
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 209a526e502c..8af6a956cc89 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -28117,6 +28117,7 @@ package android.renderscript {
public class Script extends android.renderscript.BaseObj {
method public void bindAllocation(android.renderscript.Allocation, int);
method protected android.renderscript.Script.FieldID createFieldID(int, android.renderscript.Element);
+ method protected android.renderscript.Script.InvokeID createInvokeID(int);
method protected android.renderscript.Script.KernelID createKernelID(int, int, android.renderscript.Element, android.renderscript.Element);
method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker);
method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
@@ -28157,6 +28158,9 @@ package android.renderscript {
public static final class Script.FieldID extends android.renderscript.BaseObj {
}
+ public static final class Script.InvokeID extends android.renderscript.BaseObj {
+ }
+
public static final class Script.KernelID extends android.renderscript.BaseObj {
}
@@ -28181,12 +28185,19 @@ package android.renderscript {
}
public final class ScriptGroup extends android.renderscript.BaseObj {
- method public void execute();
- method public void setInput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
- method public void setOutput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
+ method public java.lang.Object[] execute(java.lang.Object...);
+ method public deprecated void execute();
+ method public deprecated void setInput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
+ method public deprecated void setOutput(android.renderscript.Script.KernelID, android.renderscript.Allocation);
}
- public static final class ScriptGroup.Builder {
+ public static final class ScriptGroup.Binding {
+ ctor public ScriptGroup.Binding(android.renderscript.Script.FieldID, java.lang.Object);
+ method public android.renderscript.Script.FieldID getField();
+ method public java.lang.Object getValue();
+ }
+
+ public static final deprecated class ScriptGroup.Builder {
ctor public ScriptGroup.Builder(android.renderscript.RenderScript);
method public android.renderscript.ScriptGroup.Builder addConnection(android.renderscript.Type, android.renderscript.Script.KernelID, android.renderscript.Script.FieldID);
method public android.renderscript.ScriptGroup.Builder addConnection(android.renderscript.Type, android.renderscript.Script.KernelID, android.renderscript.Script.KernelID);
@@ -28194,6 +28205,25 @@ package android.renderscript {
method public android.renderscript.ScriptGroup create();
}
+ public static final class ScriptGroup.Builder2 {
+ ctor public ScriptGroup.Builder2(android.renderscript.RenderScript);
+ method public android.renderscript.ScriptGroup.Input addInput();
+ method public android.renderscript.ScriptGroup.Closure addInvoke(android.renderscript.Script.InvokeID, java.lang.Object...);
+ method public android.renderscript.ScriptGroup.Closure addKernel(android.renderscript.Script.KernelID, android.renderscript.Type, java.lang.Object...);
+ method public android.renderscript.ScriptGroup create(java.lang.String, android.renderscript.ScriptGroup.Future...);
+ }
+
+ public static final class ScriptGroup.Closure extends android.renderscript.BaseObj {
+ method public android.renderscript.ScriptGroup.Future getGlobal(android.renderscript.Script.FieldID);
+ method public android.renderscript.ScriptGroup.Future getReturn();
+ }
+
+ public static final class ScriptGroup.Future {
+ }
+
+ public static final class ScriptGroup.Input {
+ }
+
public abstract class ScriptIntrinsic extends android.renderscript.Script {
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b063209b3856..e32254a91d1e 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -257,23 +257,18 @@ public final class ActivityThread {
}
}
- static final class AcquiringProviderRecord {
- IActivityManager.ContentProviderHolder holder;
- boolean acquiring = true;
- int requests = 1;
- // Set if there was a runtime exception when trying to acquire the provider.
- RuntimeException runtimeException = null;
- }
-
// The lock of mProviderMap protects the following variables.
- final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap = new ArrayMap<>();
- final ArrayMap<ProviderKey, AcquiringProviderRecord> mAcquiringProviderMap = new ArrayMap<>();
- final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap = new ArrayMap<>();
- final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders = new ArrayMap<>();
- final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName = new ArrayMap<>();
+ final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap
+ = new ArrayMap<ProviderKey, ProviderClientRecord>();
+ final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap
+ = new ArrayMap<IBinder, ProviderRefCount>();
+ final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders
+ = new ArrayMap<IBinder, ProviderClientRecord>();
+ final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
+ = new ArrayMap<ComponentName, ProviderClientRecord>();
final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
- = new ArrayMap<>();
+ = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>();
final GcIdler mGcIdler = new GcIdler();
boolean mGcIdlerScheduled = false;
@@ -350,7 +345,7 @@ public final class ActivityThread {
}
}
- static final class ProviderClientRecord {
+ final class ProviderClientRecord {
final String[] mNames;
final IContentProvider mProvider;
final ContentProvider mLocalProvider;
@@ -4653,74 +4648,23 @@ public final class ActivityThread {
public final IContentProvider acquireProvider(
Context c, String auth, int userId, boolean stable) {
- final ProviderKey key = new ProviderKey(auth, userId);
- final IContentProvider provider = acquireExistingProvider(c, key, stable);
+ final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
if (provider != null) {
return provider;
}
- AcquiringProviderRecord r;
- boolean first = false;
- synchronized (mAcquiringProviderMap) {
- r = mAcquiringProviderMap.get(key);
- if (r == null) {
- r = new AcquiringProviderRecord();
- mAcquiringProviderMap.put(key, r);
- first = true;
- } else {
- r.requests++;
- }
- }
+ // There is a possible race here. Another thread may try to acquire
+ // the same provider at the same time. When this happens, we want to ensure
+ // that the first one wins.
+ // Note that we cannot hold the lock while acquiring and installing the
+ // provider since it might take a long time to run and it could also potentially
+ // be re-entrant in the case where the provider is in the same process.
IActivityManager.ContentProviderHolder holder = null;
try {
- if (first) {
- // Multiple threads may try to acquire the same provider at the same time.
- // When this happens, we only let the first one really gets provider.
- // Other threads just wait for its result.
- // Note that we cannot hold the lock while acquiring and installing the
- // provider since it might take a long time to run and it could also potentially
- // be re-entrant in the case where the provider is in the same process.
- holder = ActivityManagerNative.getDefault().getContentProvider(
- getApplicationThread(), auth, userId, stable);
- } else {
- synchronized (r) {
- while (r.acquiring) {
- try {
- r.wait();
- } catch (InterruptedException e) {
- }
- }
- holder = r.holder;
- }
- }
+ holder = ActivityManagerNative.getDefault().getContentProvider(
+ getApplicationThread(), auth, userId, stable);
} catch (RemoteException ex) {
- } catch (RuntimeException e) {
- synchronized (r) {
- r.runtimeException = e;
- }
- } finally {
- if (first) {
- synchronized (r) {
- r.holder = holder;
- r.acquiring = false;
- r.notifyAll();
- }
- }
-
- synchronized (mAcquiringProviderMap) {
- if (--r.requests == 0) {
- mAcquiringProviderMap.remove(key);
- }
- }
-
- if (r.runtimeException != null) {
- // Was set when the first thread tried to acquire the provider,
- // but we should make sure it is thrown for all threads trying to
- // acquire the provider.
- throw r.runtimeException;
- }
}
-
if (holder == null) {
Slog.e(TAG, "Failed to find provider info for " + auth);
return null;
@@ -4803,12 +4747,8 @@ public final class ActivityThread {
public final IContentProvider acquireExistingProvider(
Context c, String auth, int userId, boolean stable) {
- return acquireExistingProvider(c, new ProviderKey(auth, userId), stable);
- }
-
- final IContentProvider acquireExistingProvider(
- Context c, ProviderKey key, boolean stable) {
synchronized (mProviderMap) {
+ final ProviderKey key = new ProviderKey(auth, userId);
final ProviderClientRecord pr = mProviderMap.get(key);
if (pr == null) {
return null;
@@ -4819,7 +4759,7 @@ public final class ActivityThread {
if (!jBinder.isBinderAlive()) {
// The hosting process of the provider has died; we can't
// use this one.
- Log.i(TAG, "Acquiring provider " + key.authority + " for user " + key.userId
+ Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
+ ": existing object's process dead");
handleUnstableProviderDiedLocked(jBinder, true);
return null;
@@ -5141,12 +5081,18 @@ public final class ActivityThread {
if (DEBUG_PROVIDER) {
Slog.v(TAG, "installProvider: lost the race, updating ref count");
}
- // The provider has already been installed, so we need
- // to increase reference count to the existing one, but
- // only if release is needed (that is, it is not running
- // in the system process or local to the process).
+ // We need to transfer our new reference to the existing
+ // ref count, releasing the old one... but only if
+ // release is needed (that is, it is not running in the
+ // system process).
if (!noReleaseNeeded) {
incProviderRefLocked(prc, stable);
+ try {
+ ActivityManagerNative.getDefault().removeContentProvider(
+ holder.connection, stable);
+ } catch (RemoteException e) {
+ //do nothing content provider object is dead any way
+ }
}
} else {
ProviderClientRecord client = installProviderAuthoritiesLocked(
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index 24a7d3327664..3cda39ae9aad 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -91,8 +91,6 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
private static final String[] EMPTY_STRING_ARRAY = new String[0];
private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
- private static final Pattern TRIM_SQL_PATTERN = Pattern.compile("[\\s]*\\n+[\\s]*");
-
private final CloseGuard mCloseGuard = CloseGuard.get();
private final SQLiteConnectionPool mPool;
@@ -1203,7 +1201,11 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
}
private static String trimSqlForDisplay(String sql) {
- return TRIM_SQL_PATTERN.matcher(sql).replaceAll(" ");
+ // Note: Creating and caching a regular expression is expensive at preload-time
+ // and stops compile-time initialization. This pattern is only used when
+ // dumping the connection, which is a rare (mainly error) case. So:
+ // DO NOT CACHE.
+ return sql.replaceAll("[\\s]*\\n+[\\s]*", " ");
}
/**
@@ -1437,9 +1439,6 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
}
private static final class Operation {
- private static final SimpleDateFormat sDateFormat =
- new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
-
public long mStartTime;
public long mEndTime;
public String mKind;
@@ -1494,7 +1493,11 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
}
private String getFormattedStartTime() {
- return sDateFormat.format(new Date(mStartTime));
+ // Note: SimpleDateFormat is not thread-safe, cannot be compile-time created, and is
+ // relatively expensive to create during preloading. This method is only used
+ // when dumping a connection, which is a rare (mainly error) case. So:
+ // DO NOT CACHE.
+ return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(mStartTime));
}
}
}
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index fb2f445002ee..54532837cec2 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -1657,7 +1657,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
/**
* Searches the query string for the first value with the given key.
*
- * <p><strong>Warning:</strong> Prior to Ice Cream Sandwich, this decoded
+ * <p><strong>Warning:</strong> Prior to Jelly Bean, this decoded
* the '+' character as '+' rather than ' '.
*
* @param key which will be encoded
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index c5c537263bbd..cb3e22be915b 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -211,8 +211,9 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
} else if (obj instanceof Parcelable[]) {
Parcelable[] array = (Parcelable[]) obj;
for (int n = array.length - 1; n >= 0; n--) {
- if ((array[n].describeContents()
- & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
+ Parcelable p = array[n];
+ if (p != null && ((p.describeContents()
+ & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0)) {
fdFound = true;
break;
}
@@ -221,7 +222,8 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
SparseArray<? extends Parcelable> array =
(SparseArray<? extends Parcelable>) obj;
for (int n = array.size() - 1; n >= 0; n--) {
- if ((array.valueAt(n).describeContents()
+ Parcelable p = array.valueAt(n);
+ if (p != null && (p.describeContents()
& Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
fdFound = true;
break;
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 0de9c702a290..d2eaed368689 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -634,6 +634,9 @@ public class Process {
if ((debugFlags & Zygote.DEBUG_ENABLE_JIT) != 0) {
argsForZygote.add("--enable-jit");
}
+ if ((debugFlags & Zygote.DEBUG_GENERATE_CFI) != 0) {
+ argsForZygote.add("--generate-cfi");
+ }
if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
argsForZygote.add("--enable-assert");
}
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index a237afd3d500..27304f59e437 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -1040,14 +1040,10 @@ public class ViewDebug {
return methods;
}
- final ArrayList<Method> declaredMethods = new ArrayList();
- klass.getDeclaredMethodsUnchecked(false, declaredMethods);
+ methods = klass.getDeclaredMethodsUnchecked(false);
final ArrayList<Method> foundMethods = new ArrayList<Method>();
- final int count = declaredMethods.size();
- for (int i = 0; i < count; i++) {
- final Method method = declaredMethods.get(i);
-
+ for (final Method method : methods) {
// Ensure the method return and parameter types can be resolved.
try {
method.getReturnType();
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 8674a2111c18..86ba780acb40 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -40,6 +40,8 @@ public final class Zygote {
public static final int DEBUG_ENABLE_JNI_LOGGING = 1 << 4;
/** enable the JIT compiler */
public static final int DEBUG_ENABLE_JIT = 1 << 5;
+ /** Force generation of CFI code */
+ public static final int DEBUG_GENERATE_CFI = 1 << 6;
/** No external storage should be mounted. */
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 0dc242d59419..f43cc62491b4 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -322,7 +322,7 @@ class ZygoteConnection {
/**
* From --enable-debugger, --enable-checkjni, --enable-assert,
- * --enable-safemode, --enable-jit, and --enable-jni-logging.
+ * --enable-safemode, --enable-jit, --generate-cfi and --enable-jni-logging.
*/
int debugFlags;
@@ -434,6 +434,8 @@ class ZygoteConnection {
debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
} else if (arg.equals("--enable-jit")) {
debugFlags |= Zygote.DEBUG_ENABLE_JIT;
+ } else if (arg.equals("--generate-cfi")) {
+ debugFlags |= Zygote.DEBUG_GENERATE_CFI;
} else if (arg.equals("--enable-jni-logging")) {
debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
} else if (arg.equals("--enable-assert")) {
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 50ddbd16ba39..d44959b05d50 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -267,7 +267,12 @@ public class ZygoteInit {
if (false) {
Log.v(TAG, "Preloading " + line + "...");
}
- Class.forName(line);
+ // Load and explicitly initialize the given class. Use
+ // Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
+ // (to derive the caller's class-loader). Use true to force initialization, and
+ // null for the boot classpath class-loader (could as well cache the
+ // class-loader of this class in a variable).
+ Class.forName(line, true, null);
count++;
} catch (ClassNotFoundException e) {
Log.w(TAG, "Class not found for preloading: " + line);
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 0bfc0c96492c..82fe227c1787 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -873,6 +873,19 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
snprintf(cpuAbiListBuf, sizeof(cpuAbiListBuf), "--cpu-abilist=%s", propBuf);
addOption(cpuAbiListBuf);
+ /*
+ * When running with debug.gencfi, add --include-cfi to the compiler options so that the boot
+ * image, if it is compiled on device, will include CFI info, as well as other compilations
+ * started by the runtime.
+ */
+ property_get("debug.gencfi", propBuf, "");
+ if (strcmp(propBuf, "true") == 0) {
+ addOption("-Xcompiler-option");
+ addOption("--include-cfi");
+ addOption("-Ximage-compiler-option");
+ addOption("--include-cfi");
+ }
+
initArgs.version = JNI_VERSION_1_4;
initArgs.options = mOptions.editArray();
initArgs.nOptions = mOptions.size();
diff --git a/keystore/java/android/security/AndroidKeyPairGenerator.java b/keystore/java/android/security/AndroidKeyPairGenerator.java
index 5fae831de8d7..3b25ba66b9c3 100644
--- a/keystore/java/android/security/AndroidKeyPairGenerator.java
+++ b/keystore/java/android/security/AndroidKeyPairGenerator.java
@@ -17,7 +17,7 @@
package android.security;
import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
-import com.android.org.conscrypt.NativeCrypto;
+import com.android.org.conscrypt.NativeConstants;
import com.android.org.conscrypt.OpenSSLEngine;
import java.security.InvalidAlgorithmParameterException;
@@ -206,9 +206,9 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
}
private static int getDefaultKeySize(int keyType) {
- if (keyType == NativeCrypto.EVP_PKEY_EC) {
+ if (keyType == NativeConstants.EVP_PKEY_EC) {
return EC_DEFAULT_KEY_SIZE;
- } else if (keyType == NativeCrypto.EVP_PKEY_RSA) {
+ } else if (keyType == NativeConstants.EVP_PKEY_RSA) {
return RSA_DEFAULT_KEY_SIZE;
}
return -1;
@@ -216,12 +216,12 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
private static void checkValidKeySize(String keyAlgorithm, int keyType, int keySize)
throws InvalidAlgorithmParameterException {
- if (keyType == NativeCrypto.EVP_PKEY_EC) {
+ if (keyType == NativeConstants.EVP_PKEY_EC) {
if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) {
throw new InvalidAlgorithmParameterException("EC keys must be >= "
+ EC_MIN_KEY_SIZE + " and <= " + EC_MAX_KEY_SIZE);
}
- } else if (keyType == NativeCrypto.EVP_PKEY_RSA) {
+ } else if (keyType == NativeConstants.EVP_PKEY_RSA) {
if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
throw new InvalidAlgorithmParameterException("RSA keys must be >= "
+ RSA_MIN_KEY_SIZE + " and <= " + RSA_MAX_KEY_SIZE);
@@ -234,7 +234,7 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
private static void checkCorrectParametersSpec(int keyType, int keySize,
AlgorithmParameterSpec spec) throws InvalidAlgorithmParameterException {
- if (keyType == NativeCrypto.EVP_PKEY_RSA && spec != null) {
+ if (keyType == NativeConstants.EVP_PKEY_RSA && spec != null) {
if (spec instanceof RSAKeyGenParameterSpec) {
RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) spec;
if (keySize != -1 && keySize != rsaSpec.getKeysize()) {
@@ -260,7 +260,7 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
private static byte[][] getArgsForKeyType(int keyType, AlgorithmParameterSpec spec) {
switch (keyType) {
- case NativeCrypto.EVP_PKEY_RSA:
+ case NativeConstants.EVP_PKEY_RSA:
if (spec instanceof RSAKeyGenParameterSpec) {
RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) spec;
return new byte[][] { rsaSpec.getPublicExponent().toByteArray() };
diff --git a/keystore/java/android/security/CryptoOperationException.java b/keystore/java/android/security/CryptoOperationException.java
deleted file mode 100644
index 00c142fbec9d..000000000000
--- a/keystore/java/android/security/CryptoOperationException.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2015 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.security;
-
-/**
- * Base class for exceptions during cryptographic operations which cannot throw a suitable checked
- * exception.
- *
- * <p>The contract of the majority of crypto primitives/operations (e.g. {@code Cipher} or
- * {@code Signature}) is that they can throw a checked exception during initialization, but are not
- * permitted to throw a checked exception during operation. Because crypto operations can fail
- * for a variety of reasons after initialization, this base class provides type-safety for unchecked
- * exceptions that may be thrown in those cases.
- *
- * @hide
- */
-public class CryptoOperationException extends RuntimeException {
-
- /**
- * Constructs a new {@code CryptoOperationException} without detail message and cause.
- */
- public CryptoOperationException() {
- super();
- }
-
- /**
- * Constructs a new {@code CryptoOperationException} with the provided detail message and no
- * cause.
- */
- public CryptoOperationException(String message) {
- super(message);
- }
-
- /**
- * Constructs a new {@code CryptoOperationException} with the provided detail message and cause.
- */
- public CryptoOperationException(String message, Throwable cause) {
- super(message, cause);
- }
-
- /**
- * Constructs a new {@code CryptoOperationException} with the provided cause.
- */
- public CryptoOperationException(Throwable cause) {
- super(cause);
- }
-}
diff --git a/keystore/java/android/security/KeyExpiredException.java b/keystore/java/android/security/KeyExpiredException.java
index 35a5accbc94c..e64bffa481db 100644
--- a/keystore/java/android/security/KeyExpiredException.java
+++ b/keystore/java/android/security/KeyExpiredException.java
@@ -16,13 +16,15 @@
package android.security;
+import java.security.InvalidKeyException;
+
/**
* Indicates that a cryptographic operation failed because the employed key's validity end date
* is in the past.
*
* @hide
*/
-public class KeyExpiredException extends CryptoOperationException {
+public class KeyExpiredException extends InvalidKeyException {
/**
* Constructs a new {@code KeyExpiredException} without detail message and cause.
diff --git a/keystore/java/android/security/KeyNotYetValidException.java b/keystore/java/android/security/KeyNotYetValidException.java
index f1c2cac672b9..d36d80c80ca6 100644
--- a/keystore/java/android/security/KeyNotYetValidException.java
+++ b/keystore/java/android/security/KeyNotYetValidException.java
@@ -16,13 +16,15 @@
package android.security;
+import java.security.InvalidKeyException;
+
/**
* Indicates that a cryptographic operation failed because the employed key's validity start date
* is in the future.
*
* @hide
*/
-public class KeyNotYetValidException extends CryptoOperationException {
+public class KeyNotYetValidException extends InvalidKeyException {
/**
* Constructs a new {@code KeyNotYetValidException} without detail message and cause.
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 84a664e30163..3bc1b1773695 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -16,7 +16,7 @@
package android.security;
-import com.android.org.conscrypt.NativeCrypto;
+import com.android.org.conscrypt.NativeConstants;
import android.os.Binder;
import android.os.IBinder;
@@ -30,6 +30,7 @@ import android.security.keymaster.KeymasterDefs;
import android.security.keymaster.OperationResult;
import android.util.Log;
+import java.security.InvalidKeyException;
import java.util.Locale;
/**
@@ -87,9 +88,9 @@ public class KeyStore {
static int getKeyTypeForAlgorithm(String keyType) {
if ("RSA".equalsIgnoreCase(keyType)) {
- return NativeCrypto.EVP_PKEY_RSA;
+ return NativeConstants.EVP_PKEY_RSA;
} else if ("EC".equalsIgnoreCase(keyType)) {
- return NativeCrypto.EVP_PKEY_EC;
+ return NativeConstants.EVP_PKEY_EC;
} else {
return -1;
}
@@ -508,7 +509,11 @@ public class KeyStore {
}
}
- public static KeyStoreException getKeyStoreException(int errorCode) {
+ /**
+ * Returns a {@link KeyStoreException} corresponding to the provided keystore/keymaster error
+ * code.
+ */
+ static KeyStoreException getKeyStoreException(int errorCode) {
if (errorCode > 0) {
// KeyStore layer error
switch (errorCode) {
@@ -544,7 +549,11 @@ public class KeyStore {
}
}
- public static CryptoOperationException getCryptoOperationException(KeyStoreException e) {
+ /**
+ * Returns an {@link InvalidKeyException} corresponding to the provided
+ * {@link KeyStoreException}.
+ */
+ static InvalidKeyException getInvalidKeyException(KeyStoreException e) {
switch (e.getErrorCode()) {
case KeymasterDefs.KM_ERROR_KEY_EXPIRED:
return new KeyExpiredException();
@@ -553,11 +562,15 @@ public class KeyStore {
case KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED:
return new UserNotAuthenticatedException();
default:
- return new CryptoOperationException("Crypto operation failed", e);
+ return new InvalidKeyException("Keystore operation failed", e);
}
}
- public static CryptoOperationException getCryptoOperationException(int errorCode) {
- return getCryptoOperationException(getKeyStoreException(errorCode));
+ /**
+ * Returns an {@link InvalidKeyException} corresponding to the provided keystore/keymaster error
+ * code.
+ */
+ static InvalidKeyException getInvalidKeyException(int errorCode) {
+ return getInvalidKeyException(getKeyStoreException(errorCode));
}
}
diff --git a/keystore/java/android/security/KeyStoreCipherSpi.java b/keystore/java/android/security/KeyStoreCipherSpi.java
index 37e00b28cd83..3b13e83520bb 100644
--- a/keystore/java/android/security/KeyStoreCipherSpi.java
+++ b/keystore/java/android/security/KeyStoreCipherSpi.java
@@ -136,6 +136,14 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
private Long mOperationHandle;
private KeyStoreCryptoOperationChunkedStreamer mMainDataStreamer;
+ /**
+ * Encountered exception which could not be immediately thrown because it was encountered inside
+ * a method that does not throw checked exception. This exception will be thrown from
+ * {@code engineDoFinal}. Once such an exception is encountered, {@code engineUpdate} and
+ * {@code engineDoFinal} start ignoring input data.
+ */
+ private Exception mCachedException;
+
protected KeyStoreCipherSpi(
int keymasterAlgorithm,
int keymasterBlockMode,
@@ -152,29 +160,62 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
@Override
protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
- init(opmode, key, random);
- initAlgorithmSpecificParameters();
- ensureKeystoreOperationInitialized();
+ resetAll();
+
+ boolean success = false;
+ try {
+ init(opmode, key, random);
+ initAlgorithmSpecificParameters();
+ try {
+ ensureKeystoreOperationInitialized();
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new InvalidKeyException(e);
+ }
+ success = true;
+ } finally {
+ if (!success) {
+ resetAll();
+ }
+ }
}
@Override
protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException {
- init(opmode, key, random);
- initAlgorithmSpecificParameters(params);
- ensureKeystoreOperationInitialized();
+ resetAll();
+
+ boolean success = false;
+ try {
+ init(opmode, key, random);
+ initAlgorithmSpecificParameters(params);
+ ensureKeystoreOperationInitialized();
+ success = true;
+ } finally {
+ if (!success) {
+ resetAll();
+ }
+ }
}
@Override
protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
- init(opmode, key, random);
- initAlgorithmSpecificParameters(params);
- ensureKeystoreOperationInitialized();
+ resetAll();
+
+ boolean success = false;
+ try {
+ init(opmode, key, random);
+ initAlgorithmSpecificParameters(params);
+ ensureKeystoreOperationInitialized();
+ success = true;
+ } finally {
+ if (!success) {
+ resetAll();
+ }
+ }
}
private void init(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
- resetAll();
if (!(key instanceof KeyStoreSecretKey)) {
throw new InvalidKeyException(
"Unsupported key: " + ((key != null) ? key.getClass().getName() : "null"));
@@ -207,6 +248,7 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
mOperationToken = null;
mOperationHandle = null;
mMainDataStreamer = null;
+ mCachedException = null;
}
private void resetWhilePreservingInitState() {
@@ -218,12 +260,17 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
mOperationHandle = null;
mMainDataStreamer = null;
mAdditionalEntropyForBegin = null;
+ mCachedException = null;
}
- private void ensureKeystoreOperationInitialized() {
+ private void ensureKeystoreOperationInitialized() throws InvalidKeyException,
+ InvalidAlgorithmParameterException {
if (mMainDataStreamer != null) {
return;
}
+ if (mCachedException != null) {
+ return;
+ }
if (mKey == null) {
throw new IllegalStateException("Not initialized");
}
@@ -252,11 +299,15 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
if (opResult == null) {
throw new KeyStoreConnectException();
} else if (opResult.resultCode != KeyStore.NO_ERROR) {
- throw KeyStore.getCryptoOperationException(opResult.resultCode);
+ switch (opResult.resultCode) {
+ case KeymasterDefs.KM_ERROR_INVALID_NONCE:
+ throw new InvalidAlgorithmParameterException("Invalid IV");
+ }
+ throw KeyStore.getInvalidKeyException(opResult.resultCode);
}
if (opResult.token == null) {
- throw new CryptoOperationException("Keystore returned null operation token");
+ throw new IllegalStateException("Keystore returned null operation token");
}
mOperationToken = opResult.token;
mOperationHandle = opResult.operationHandle;
@@ -270,7 +321,15 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
@Override
protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
- ensureKeystoreOperationInitialized();
+ if (mCachedException != null) {
+ return null;
+ }
+ try {
+ ensureKeystoreOperationInitialized();
+ } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
+ mCachedException = e;
+ return null;
+ }
if (inputLen == 0) {
return null;
@@ -280,7 +339,8 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
try {
output = mMainDataStreamer.update(input, inputOffset, inputLen);
} catch (KeyStoreException e) {
- throw KeyStore.getCryptoOperationException(e);
+ mCachedException = e;
+ return null;
}
if (output.length == 0) {
@@ -309,7 +369,16 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
@Override
protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
throws IllegalBlockSizeException, BadPaddingException {
- ensureKeystoreOperationInitialized();
+ if (mCachedException != null) {
+ throw (IllegalBlockSizeException)
+ new IllegalBlockSizeException().initCause(mCachedException);
+ }
+
+ try {
+ ensureKeystoreOperationInitialized();
+ } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
+ throw (IllegalBlockSizeException) new IllegalBlockSizeException().initCause(e);
+ }
byte[] output;
try {
@@ -323,7 +392,7 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
case KeymasterDefs.KM_ERROR_VERIFICATION_FAILED:
throw new AEADBadTagException();
default:
- throw KeyStore.getCryptoOperationException(e);
+ throw (IllegalBlockSizeException) new IllegalBlockSizeException().initCause(e);
}
}
@@ -584,11 +653,11 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
if (mIv == null) {
mIv = returnedIv;
} else if ((returnedIv != null) && (!Arrays.equals(returnedIv, mIv))) {
- throw new CryptoOperationException("IV in use differs from provided IV");
+ throw new IllegalStateException("IV in use differs from provided IV");
}
} else {
if (returnedIv != null) {
- throw new CryptoOperationException(
+ throw new IllegalStateException(
"IV in use despite IV not being used by this transformation");
}
}
diff --git a/keystore/java/android/security/KeyStoreConnectException.java b/keystore/java/android/security/KeyStoreConnectException.java
index 8ed6e04ddfe8..1aa3aecc0b1e 100644
--- a/keystore/java/android/security/KeyStoreConnectException.java
+++ b/keystore/java/android/security/KeyStoreConnectException.java
@@ -21,7 +21,7 @@ package android.security;
*
* @hide
*/
-public class KeyStoreConnectException extends CryptoOperationException {
+public class KeyStoreConnectException extends IllegalStateException {
public KeyStoreConnectException() {
super("Failed to communicate with keystore service");
}
diff --git a/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
index aafd2fa97aff..06191994af62 100644
--- a/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
+++ b/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
@@ -136,7 +136,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
// More input is available, but it wasn't included into the previous chunk
// because the chunk reached its maximum permitted size.
// Shouldn't have happened.
- throw new CryptoOperationException("Nothing consumed from max-sized chunk: "
+ throw new IllegalStateException("Nothing consumed from max-sized chunk: "
+ chunk.length + " bytes");
}
mBuffered = chunk;
@@ -148,7 +148,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
mBufferedOffset = opResult.inputConsumed;
mBufferedLength = chunk.length - opResult.inputConsumed;
} else {
- throw new CryptoOperationException("Consumed more than provided: "
+ throw new IllegalStateException("Consumed more than provided: "
+ opResult.inputConsumed + ", provided: " + chunk.length);
}
@@ -160,7 +160,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
try {
bufferedOutput.write(opResult.output);
} catch (IOException e) {
- throw new CryptoOperationException("Failed to buffer output", e);
+ throw new IllegalStateException("Failed to buffer output", e);
}
}
} else {
@@ -173,7 +173,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
try {
bufferedOutput.write(opResult.output);
} catch (IOException e) {
- throw new CryptoOperationException("Failed to buffer output", e);
+ throw new IllegalStateException("Failed to buffer output", e);
}
return bufferedOutput.toByteArray();
}
@@ -233,10 +233,10 @@ public class KeyStoreCryptoOperationChunkedStreamer {
}
if (opResult.inputConsumed < chunk.length) {
- throw new CryptoOperationException("Keystore failed to consume all input. Provided: "
+ throw new IllegalStateException("Keystore failed to consume all input. Provided: "
+ chunk.length + ", consumed: " + opResult.inputConsumed);
} else if (opResult.inputConsumed > chunk.length) {
- throw new CryptoOperationException("Keystore consumed more input than provided"
+ throw new IllegalStateException("Keystore consumed more input than provided"
+ " . Provided: " + chunk.length + ", consumed: " + opResult.inputConsumed);
}
diff --git a/keystore/java/android/security/KeyStoreHmacSpi.java b/keystore/java/android/security/KeyStoreHmacSpi.java
index a19bbda3b9ec..175369ce91d0 100644
--- a/keystore/java/android/security/KeyStoreHmacSpi.java
+++ b/keystore/java/android/security/KeyStoreHmacSpi.java
@@ -69,9 +69,10 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
private final int mKeymasterDigest;
private final int mMacSizeBytes;
- private String mKeyAliasInKeyStore;
+ // Fields below are populated by engineInit and should be preserved after engineDoFinal.
+ private KeyStoreSecretKey mKey;
- // The fields below are reset by the engineReset operation.
+ // Fields below are reset when engineDoFinal succeeds.
private KeyStoreCryptoOperationChunkedStreamer mChunkedStreamer;
private IBinder mOperationToken;
private Long mOperationHandle;
@@ -89,28 +90,49 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
@Override
protected void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException,
InvalidAlgorithmParameterException {
+ resetAll();
+
+ boolean success = false;
+ try {
+ init(key, params);
+ ensureKeystoreOperationInitialized();
+ success = true;
+ } finally {
+ if (!success) {
+ resetAll();
+ }
+ }
+ }
+
+ private void init(Key key, AlgorithmParameterSpec params) throws InvalidKeyException,
+ InvalidAlgorithmParameterException {
if (key == null) {
throw new InvalidKeyException("key == null");
} else if (!(key instanceof KeyStoreSecretKey)) {
throw new InvalidKeyException(
"Only Android KeyStore secret keys supported. Key: " + key);
}
+ mKey = (KeyStoreSecretKey) key;
if (params != null) {
throw new InvalidAlgorithmParameterException(
"Unsupported algorithm parameters: " + params);
}
- mKeyAliasInKeyStore = ((KeyStoreSecretKey) key).getAlias();
- if (mKeyAliasInKeyStore == null) {
- throw new InvalidKeyException("Key's KeyStore alias not known");
+ }
+
+ private void resetAll() {
+ mKey = null;
+ IBinder operationToken = mOperationToken;
+ if (operationToken != null) {
+ mOperationToken = null;
+ mKeyStore.abort(operationToken);
}
- engineReset();
- ensureKeystoreOperationInitialized();
+ mOperationHandle = null;
+ mChunkedStreamer = null;
}
- @Override
- protected void engineReset() {
+ private void resetWhilePreservingInitState() {
IBinder operationToken = mOperationToken;
if (operationToken != null) {
mOperationToken = null;
@@ -120,11 +142,16 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
mChunkedStreamer = null;
}
- private void ensureKeystoreOperationInitialized() {
+ @Override
+ protected void engineReset() {
+ resetWhilePreservingInitState();
+ }
+
+ private void ensureKeystoreOperationInitialized() throws InvalidKeyException {
if (mChunkedStreamer != null) {
return;
}
- if (mKeyAliasInKeyStore == null) {
+ if (mKey == null) {
throw new IllegalStateException("Not initialized");
}
@@ -132,7 +159,8 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_HMAC);
keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
- OperationResult opResult = mKeyStore.begin(mKeyAliasInKeyStore,
+ OperationResult opResult = mKeyStore.begin(
+ mKey.getAlias(),
KeymasterDefs.KM_PURPOSE_SIGN,
true,
keymasterArgs,
@@ -141,10 +169,10 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
if (opResult == null) {
throw new KeyStoreConnectException();
} else if (opResult.resultCode != KeyStore.NO_ERROR) {
- throw KeyStore.getCryptoOperationException(opResult.resultCode);
+ throw KeyStore.getInvalidKeyException(opResult.resultCode);
}
if (opResult.token == null) {
- throw new CryptoOperationException("Keystore returned null operation token");
+ throw new IllegalStateException("Keystore returned null operation token");
}
mOperationToken = opResult.token;
mOperationHandle = opResult.operationHandle;
@@ -160,31 +188,39 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
@Override
protected void engineUpdate(byte[] input, int offset, int len) {
- ensureKeystoreOperationInitialized();
+ try {
+ ensureKeystoreOperationInitialized();
+ } catch (InvalidKeyException e) {
+ throw new IllegalStateException("Failed to reinitialize MAC", e);
+ }
byte[] output;
try {
output = mChunkedStreamer.update(input, offset, len);
} catch (KeyStoreException e) {
- throw KeyStore.getCryptoOperationException(e);
+ throw new IllegalStateException("Keystore operation failed", e);
}
if ((output != null) && (output.length != 0)) {
- throw new CryptoOperationException("Update operation unexpectedly produced output");
+ throw new IllegalStateException("Update operation unexpectedly produced output");
}
}
@Override
protected byte[] engineDoFinal() {
- ensureKeystoreOperationInitialized();
+ try {
+ ensureKeystoreOperationInitialized();
+ } catch (InvalidKeyException e) {
+ throw new IllegalStateException("Failed to reinitialize MAC", e);
+ }
byte[] result;
try {
result = mChunkedStreamer.doFinal(null, 0, 0);
} catch (KeyStoreException e) {
- throw KeyStore.getCryptoOperationException(e);
+ throw new IllegalStateException("Keystore operation failed", e);
}
- engineReset();
+ resetWhilePreservingInitState();
return result;
}
diff --git a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
index 87e7ee644444..dde3b8fe3771 100644
--- a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
@@ -200,7 +200,8 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
int errorCode = mKeyStore.generateKey(
keyAliasInKeystore, args, additionalEntropy, flags, new KeyCharacteristics());
if (errorCode != KeyStore.NO_ERROR) {
- throw KeyStore.getCryptoOperationException(errorCode);
+ throw new IllegalStateException(
+ "Keystore operation failed", KeyStore.getKeyStoreException(errorCode));
}
String keyAlgorithmJCA =
KeymasterUtils.getJcaSecretKeyAlgorithm(mKeymasterAlgorithm, mKeymasterDigest);
diff --git a/keystore/java/android/security/UserNotAuthenticatedException.java b/keystore/java/android/security/UserNotAuthenticatedException.java
index e6342ef79673..d0410b8f0171 100644
--- a/keystore/java/android/security/UserNotAuthenticatedException.java
+++ b/keystore/java/android/security/UserNotAuthenticatedException.java
@@ -16,13 +16,15 @@
package android.security;
+import java.security.InvalidKeyException;
+
/**
* Indicates that a cryptographic operation could not be performed because the user has not been
* authenticated recently enough.
*
* @hide
*/
-public class UserNotAuthenticatedException extends CryptoOperationException {
+public class UserNotAuthenticatedException extends InvalidKeyException {
/**
* Constructs a new {@code UserNotAuthenticatedException} without detail message and cause.
diff --git a/keystore/tests/src/android/security/AndroidKeyStoreTest.java b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
index 7a88deefa791..a7046dd29cec 100644
--- a/keystore/tests/src/android/security/AndroidKeyStoreTest.java
+++ b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
@@ -18,7 +18,7 @@ package android.security;
import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
-import com.android.org.conscrypt.NativeCrypto;
+import com.android.org.conscrypt.NativeConstants;
import com.android.org.conscrypt.OpenSSLEngine;
import android.test.AndroidTestCase;
@@ -768,7 +768,7 @@ public class AndroidKeyStoreTest extends AndroidTestCase {
assertAliases(new String[] {});
assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
- KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
+ KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
null));
assertAliases(new String[] { TEST_ALIAS_1 });
@@ -797,7 +797,7 @@ public class AndroidKeyStoreTest extends AndroidTestCase {
assertAliases(new String[] {});
assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
- KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
+ KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
null));
assertTrue("Should contain generated private key", mKeyStore.containsAlias(TEST_ALIAS_1));
@@ -1963,7 +1963,7 @@ public class AndroidKeyStoreTest extends AndroidTestCase {
{
final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
- NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
+ NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
@@ -2019,7 +2019,7 @@ public class AndroidKeyStoreTest extends AndroidTestCase {
{
final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
- NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
+ NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
TEST_SERIAL_1, TEST_DN_1, NOW, NOW_PLUS_10_YEARS);
@@ -2032,7 +2032,7 @@ public class AndroidKeyStoreTest extends AndroidTestCase {
{
final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_2;
assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
- NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
+ NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_2,
TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);
@@ -2064,7 +2064,7 @@ public class AndroidKeyStoreTest extends AndroidTestCase {
{
final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
assertTrue(mAndroidKeyStore.generate(privateKeyAlias,
- android.security.KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024,
+ android.security.KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024,
android.security.KeyStore.FLAG_NONE, null));
X509Certificate cert =
@@ -2116,7 +2116,7 @@ public class AndroidKeyStoreTest extends AndroidTestCase {
assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_3,
- KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
+ KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
null));
assertEquals("The keystore size should match expected", 3, mKeyStore.size());
@@ -2184,7 +2184,7 @@ public class AndroidKeyStoreTest extends AndroidTestCase {
private void setupKey() throws Exception {
final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
assertTrue(mAndroidKeyStore
- .generate(privateKeyAlias, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024,
+ .generate(privateKeyAlias, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA, 1024,
KeyStore.FLAG_ENCRYPTED, null));
X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1, TEST_SERIAL_1,
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
index 1a5552a18df8..916b1ba9ac46 100644
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ b/keystore/tests/src/android/security/KeyStoreTest.java
@@ -32,7 +32,7 @@ import android.test.ActivityUnitTestCase;
import android.test.AssertionFailedError;
import android.test.MoreAsserts;
import android.test.suitebuilder.annotation.MediumTest;
-import com.android.org.conscrypt.NativeCrypto;
+import com.android.org.conscrypt.NativeConstants;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Date;
@@ -365,7 +365,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
public void testGenerate_NotInitialized_Fail() throws Exception {
assertFalse("Should fail when keystore is not initialized",
- mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+ mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
}
@@ -373,7 +373,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
mKeyStore.password(TEST_PASSWD);
mKeyStore.lock();
assertFalse("Should fail when keystore is locked",
- mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+ mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
}
@@ -381,7 +381,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
assertTrue(mKeyStore.password(TEST_PASSWD));
assertTrue("Should be able to generate key when unlocked",
- mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+ mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
assertTrue(mKeyStore.contains(TEST_KEYNAME));
assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
@@ -391,7 +391,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
assertTrue(mKeyStore.password(TEST_PASSWD));
assertTrue("Should be able to generate key when unlocked",
- mKeyStore.generate(TEST_KEYNAME, Process.WIFI_UID, NativeCrypto.EVP_PKEY_RSA,
+ mKeyStore.generate(TEST_KEYNAME, Process.WIFI_UID, NativeConstants.EVP_PKEY_RSA,
RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
assertFalse(mKeyStore.contains(TEST_KEYNAME));
@@ -401,7 +401,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
assertTrue(mKeyStore.password(TEST_PASSWD));
assertFalse(mKeyStore.generate(TEST_KEYNAME, Process.BLUETOOTH_UID,
- NativeCrypto.EVP_PKEY_RSA, RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
+ NativeConstants.EVP_PKEY_RSA, RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
assertFalse(mKeyStore.contains(TEST_KEYNAME));
@@ -447,7 +447,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
public void testSign_Success() throws Exception {
mKeyStore.password(TEST_PASSWD);
- assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+ assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
assertTrue(mKeyStore.contains(TEST_KEYNAME));
final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
@@ -458,7 +458,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
public void testVerify_Success() throws Exception {
mKeyStore.password(TEST_PASSWD);
- assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+ assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
assertTrue(mKeyStore.contains(TEST_KEYNAME));
final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
@@ -486,7 +486,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
mKeyStore.password(TEST_PASSWD));
assertTrue("Should be able to generate key for testcase",
- mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+ mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
assertTrue("Should be able to grant key to other user",
@@ -520,7 +520,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
mKeyStore.password(TEST_PASSWD));
assertTrue("Should be able to generate key for testcase",
- mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+ mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
assertTrue("Should be able to grant key to other user",
@@ -554,7 +554,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
mKeyStore.password(TEST_PASSWD));
assertTrue("Should be able to generate key for testcase",
- mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+ mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
assertFalse("Should not be able to revoke not existent grant",
@@ -566,7 +566,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
mKeyStore.password(TEST_PASSWD));
assertTrue("Should be able to generate key for testcase",
- mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+ mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
assertTrue("Should be able to grant key to other user",
@@ -584,7 +584,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
mKeyStore.password(TEST_PASSWD));
assertTrue("Should be able to generate key for testcase",
- mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+ mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
assertTrue("Should be able to grant key to other user",
@@ -605,7 +605,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
assertFalse(mKeyStore.contains(TEST_KEYNAME));
- assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+ assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
assertTrue(mKeyStore.contains(TEST_KEYNAME));
@@ -644,7 +644,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
assertFalse(mKeyStore.contains(TEST_KEYNAME));
- assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+ assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeConstants.EVP_PKEY_RSA,
RSA_KEY_SIZE, KeyStore.FLAG_ENCRYPTED, null));
assertTrue(mKeyStore.contains(TEST_KEYNAME));
diff --git a/libs/androidfw/ObbFile.cpp b/libs/androidfw/ObbFile.cpp
index 195fa9ac00d3..95332a35eb7d 100644
--- a/libs/androidfw/ObbFile.cpp
+++ b/libs/androidfw/ObbFile.cpp
@@ -337,7 +337,9 @@ bool ObbFile::removeFrom(int fd)
return false;
}
- ftruncate(fd, mFooterStart);
+ if (ftruncate(fd, mFooterStart) == -1) {
+ return false;
+ }
return true;
}
diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java
index b2886bb473b1..541d871bd657 100644
--- a/media/java/android/media/MediaHTTPConnection.java
+++ b/media/java/android/media/MediaHTTPConnection.java
@@ -32,6 +32,7 @@ import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.NoRouteToHostException;
import java.net.ProtocolException;
+import java.net.UnknownServiceException;
import java.util.HashMap;
import java.util.Map;
@@ -337,7 +338,10 @@ public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
} catch (NoRouteToHostException e) {
Log.w(TAG, "readAt " + offset + " / " + size + " => " + e);
return MEDIA_ERROR_UNSUPPORTED;
- } catch (IOException e) {
+ } catch (UnknownServiceException e) {
+ Log.w(TAG, "readAt " + offset + " / " + size + " => " + e);
+ return MEDIA_ERROR_UNSUPPORTED;
+ }catch (IOException e) {
if (VERBOSE) {
Log.d(TAG, "readAt " + offset + " / " + size + " => -1");
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 69a4ac02a058..af5025b8d151 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -4120,8 +4120,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
/** {@inheritDoc} */
@Override
public int finishPostLayoutPolicyLw() {
- if (mWinShowWhenLocked != null &&
- mWinShowWhenLocked != mTopFullscreenOpaqueWindowState) {
+ if (mWinShowWhenLocked != null && mTopFullscreenOpaqueWindowState != null &&
+ mWinShowWhenLocked.getAppToken() != mTopFullscreenOpaqueWindowState.getAppToken()
+ && isKeyguardLocked()) {
// A dialog is dismissing the keyguard. Put the wallpaper behind it and hide the
// fullscreen window.
// TODO: Make sure FLAG_SHOW_WALLPAPER is restored when dialog is dismissed. Or not.
diff --git a/preloaded-classes b/preloaded-classes
index 151766f6e249..7a41bb268d80 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -828,6 +828,11 @@ android.hardware.soundtrigger.SoundTriggerModule
android.hardware.usb.UsbDevice
android.hardware.usb.UsbDeviceConnection
android.hardware.usb.UsbRequest
+# Initializing android.icu.impl.ICUBinary loads the ICU data.
+# Opening the files in the Zygote avoids StrictMode violations.
+# It also ensures the ICU data files are mapped on boot and all
+# apps will be consistent (even if files are added to /data).
+android.icu.impl.ICUBinary
android.inputmethodservice.ExtractEditText
android.location.Location
android.location.Location$1
diff --git a/rs/java/android/renderscript/Script.java b/rs/java/android/renderscript/Script.java
index 65056ac5c22d..dda468a0de02 100644
--- a/rs/java/android/renderscript/Script.java
+++ b/rs/java/android/renderscript/Script.java
@@ -66,7 +66,6 @@ public class Script extends BaseObj {
}
/**
- * @hide Pending API review
* InvokeID is an identifier for an invoke function. It is used
* as an identifier for ScriptGroup creation.
*
@@ -86,7 +85,6 @@ public class Script extends BaseObj {
private final SparseArray<InvokeID> mIIDs = new SparseArray<InvokeID>();
/**
- * @hide Pending API review
* Only to be used by generated reflected classes.
*/
protected InvokeID createInvokeID(int slot) {
diff --git a/rs/java/android/renderscript/ScriptGroup.java b/rs/java/android/renderscript/ScriptGroup.java
index 51c838f9ef84..be8b0fd77911 100644
--- a/rs/java/android/renderscript/ScriptGroup.java
+++ b/rs/java/android/renderscript/ScriptGroup.java
@@ -16,32 +16,30 @@
package android.renderscript;
+import android.util.Log;
+import android.util.Pair;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
- * ScriptGroup creates a group of kernels that are executed
- * together with one execution call as if they were a single kernel.
- * The kernels may be connected internally or to an external allocation.
- * The intermediate results for internal connections are not observable
- * after the execution of the script.
+ * A group of kernels that are executed
+ * together with one execution call as if they were a single kernel
* <p>
- * External connections are grouped into inputs and outputs.
- * All outputs are produced by a script kernel and placed into a
- * user-supplied allocation. Inputs provide the input of a kernel.
- * Inputs bound to script globals are set directly upon the script.
+ * In addition to kernels, a script group may contain invocable functions as well.
+ * A script group may take inputs and generate outputs, which are consumed and
+ * produced by its member kernels.
+ * Inside a script group, outputs from one kernel can be passed to another kernel as inputs.
+ * The API disallows cyclic dependencies among kernels in a script group,
+ * effectively making it a directed acyclic graph (DAG) of kernels.
* <p>
- * A ScriptGroup must contain at least one kernel. A ScriptGroup
- * must contain only a single directed acyclic graph (DAG) of
- * script kernels and connections. Attempting to create a
- * ScriptGroup with multiple DAGs or attempting to create
- * a cycle within a ScriptGroup will throw an exception.
- * <p>
- * Currently, all kernels in a ScriptGroup must be from separate
- * Script objects. Attempting to use multiple kernels from the same
- * Script object will result in an {@link android.renderscript.RSInvalidStateException}.
- *
+ * Grouping kernels together allows for more efficient execution. For example,
+ * runtime and compiler optimization can be applied to reduce computation and
+ * communication overhead, and to make better use of the CPU and the GPU.
**/
public final class ScriptGroup extends BaseObj {
+ private static final String TAG = "ScriptGroup";
IO mOutputs[];
IO mInputs[];
@@ -88,15 +86,364 @@ public final class ScriptGroup extends BaseObj {
}
+ /**
+ * An opaque class for closures
+ * <p>
+ * A closure represents a function call to a kernel or invocable function,
+ * combined with arguments and values for global variables. A closure is
+ * created using the {@link android.renderscript.ScriptGroup.Builder2#addKernel} or
+ * {@link android.renderscript.ScriptGroup.Builder2#addInvoke}
+ * method.
+ */
+
+ public static final class Closure extends BaseObj {
+ private Object[] mArgs;
+ private Allocation mReturnValue;
+ private Map<Script.FieldID, Object> mBindings;
+
+ private Future mReturnFuture;
+ private Map<Script.FieldID, Future> mGlobalFuture;
+
+ private FieldPacker mFP;
+
+ private static final String TAG = "Closure";
+
+ Closure(long id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ Closure(RenderScript rs, Script.KernelID kernelID, Type returnType,
+ Object[] args, Map<Script.FieldID, Object> globals) {
+ super(0, rs);
+
+ mArgs = args;
+ mReturnValue = Allocation.createTyped(rs, returnType);
+ mBindings = globals;
+ mGlobalFuture = new HashMap<Script.FieldID, Future>();
+
+ int numValues = args.length + globals.size();
+
+ long[] fieldIDs = new long[numValues];
+ long[] values = new long[numValues];
+ int[] sizes = new int[numValues];
+ long[] depClosures = new long[numValues];
+ long[] depFieldIDs = new long[numValues];
+
+ int i;
+ for (i = 0; i < args.length; i++) {
+ Object obj = args[i];
+ fieldIDs[i] = 0;
+ if (obj instanceof Input) {
+ Input unbound = (Input)obj;
+ unbound.addReference(this, i);
+ } else {
+ retrieveValueAndDependenceInfo(rs, i, args[i], values, sizes,
+ depClosures, depFieldIDs);
+ }
+ }
+
+ for (Map.Entry<Script.FieldID, Object> entry : globals.entrySet()) {
+ Object obj = entry.getValue();
+ Script.FieldID fieldID = entry.getKey();
+ fieldIDs[i] = fieldID.getID(rs);
+ if (obj instanceof Input) {
+ Input unbound = (Input)obj;
+ unbound.addReference(this, fieldID);
+ } else {
+ retrieveValueAndDependenceInfo(rs, i, obj, values,
+ sizes, depClosures, depFieldIDs);
+ }
+ i++;
+ }
+
+ long id = rs.nClosureCreate(kernelID.getID(rs), mReturnValue.getID(rs),
+ fieldIDs, values, sizes, depClosures, depFieldIDs);
+
+ setID(id);
+ }
+
+ Closure(RenderScript rs, Script.InvokeID invokeID,
+ Object[] args, Map<Script.FieldID, Object> globals) {
+ super(0, rs);
+ mFP = FieldPacker.createFromArray(args);
+
+ mArgs = args;
+ mBindings = globals;
+ mGlobalFuture = new HashMap<Script.FieldID, Future>();
+
+ int numValues = globals.size();
+
+ long[] fieldIDs = new long[numValues];
+ long[] values = new long[numValues];
+ int[] sizes = new int[numValues];
+ long[] depClosures = new long[numValues];
+ long[] depFieldIDs = new long[numValues];
+
+ int i = 0;
+ for (Map.Entry<Script.FieldID, Object> entry : globals.entrySet()) {
+ Object obj = entry.getValue();
+ Script.FieldID fieldID = entry.getKey();
+ fieldIDs[i] = fieldID.getID(rs);
+ if (obj instanceof Input) {
+ Input unbound = (Input)obj;
+ unbound.addReference(this, fieldID);
+ } else {
+ retrieveValueAndDependenceInfo(rs, i, obj, values,
+ sizes, depClosures, depFieldIDs);
+ }
+ i++;
+ }
+
+ long id = rs.nInvokeClosureCreate(invokeID.getID(rs), mFP.getData(), fieldIDs,
+ values, sizes);
+
+ setID(id);
+ }
+
+ private static
+ void retrieveValueAndDependenceInfo(RenderScript rs,
+ int index, Object obj,
+ long[] values, int[] sizes,
+ long[] depClosures,
+ long[] depFieldIDs) {
+
+ if (obj instanceof Future) {
+ Future f = (Future)obj;
+ obj = f.getValue();
+ depClosures[index] = f.getClosure().getID(rs);
+ Script.FieldID fieldID = f.getFieldID();
+ depFieldIDs[index] = fieldID != null ? fieldID.getID(rs) : 0;
+ if (obj == null) {
+ // Value is originally created by the owner closure
+ values[index] = 0;
+ sizes[index] = 0;
+ return;
+ }
+ } else {
+ depClosures[index] = 0;
+ depFieldIDs[index] = 0;
+ }
+
+ ValueAndSize vs = new ValueAndSize(rs, obj);
+ values[index] = vs.value;
+ sizes[index] = vs.size;
+ }
+
+ /**
+ * Returns the future for the return value
+ *
+ * @return a future
+ */
+
+ public Future getReturn() {
+ if (mReturnFuture == null) {
+ mReturnFuture = new Future(this, null, mReturnValue);
+ }
+
+ return mReturnFuture;
+ }
+
+ /**
+ * Returns the future for a global variable
+ *
+ * @param field the field ID for the global variable
+ * @return a future
+ */
+
+ public Future getGlobal(Script.FieldID field) {
+ Future f = mGlobalFuture.get(field);
+
+ if (f == null) {
+ // If the field is not bound to this closure, this will return a future
+ // without an associated value (reference). So this is not working for
+ // cross-module (cross-script) linking in this case where a field not
+ // explicitly bound.
+ f = new Future(this, field, mBindings.get(field));
+ mGlobalFuture.put(field, f);
+ }
+
+ return f;
+ }
+
+ void setArg(int index, Object obj) {
+ mArgs[index] = obj;
+ ValueAndSize vs = new ValueAndSize(mRS, obj);
+ mRS.nClosureSetArg(getID(mRS), index, vs.value, vs.size);
+ }
+
+ void setGlobal(Script.FieldID fieldID, Object obj) {
+ mBindings.put(fieldID, obj);
+ ValueAndSize vs = new ValueAndSize(mRS, obj);
+ mRS.nClosureSetGlobal(getID(mRS), fieldID.getID(mRS), vs.value, vs.size);
+ }
+
+ private static final class ValueAndSize {
+ public ValueAndSize(RenderScript rs, Object obj) {
+ if (obj instanceof Allocation) {
+ value = ((Allocation)obj).getID(rs);
+ size = -1;
+ } else if (obj instanceof Boolean) {
+ value = ((Boolean)obj).booleanValue() ? 1 : 0;
+ size = 4;
+ } else if (obj instanceof Integer) {
+ value = ((Integer)obj).longValue();
+ size = 4;
+ } else if (obj instanceof Long) {
+ value = ((Long)obj).longValue();
+ size = 8;
+ } else if (obj instanceof Float) {
+ value = ((Float)obj).longValue();
+ size = 4;
+ } else if (obj instanceof Double) {
+ value = ((Double)obj).longValue();
+ size = 8;
+ }
+ }
+ public long value;
+ public int size;
+ }
+ }
+
+ /**
+ * An opaque class for futures
+ * <p>
+ * A future represents an output of a closure, either the return value of
+ * the function, or the value of a global variable written by the function.
+ * A future is created by calling the {@link Closure#getReturn} or
+ * {@link Closure#getGlobal} method.
+ */
+
+ public static final class Future {
+ Closure mClosure;
+ Script.FieldID mFieldID;
+ Object mValue;
+
+ Future(Closure closure, Script.FieldID fieldID, Object value) {
+ mClosure = closure;
+ mFieldID = fieldID;
+ mValue = value;
+ }
+
+ Closure getClosure() { return mClosure; }
+ Script.FieldID getFieldID() { return mFieldID; }
+ Object getValue() { return mValue; }
+ }
+
+ /**
+ * An opaque class for script group inputs
+ * <p>
+ * Created by calling the {@link Builder2#addInput} method. The value
+ * is assigned in {@link ScriptGroup#execute(Object...)} method as
+ * one of its arguments. Arguments to the execute method should be in
+ * the same order as intputs are added using the addInput method.
+ */
+
+ public static final class Input {
+ // Either mFieldID or mArgIndex should be set but not both.
+ List<Pair<Closure, Script.FieldID>> mFieldID;
+ // -1 means unset. Legal values are 0 .. n-1, where n is the number of
+ // arguments for the referencing closure.
+ List<Pair<Closure, Integer>> mArgIndex;
+
+ Input() {
+ mFieldID = new ArrayList<Pair<Closure, Script.FieldID>>();
+ mArgIndex = new ArrayList<Pair<Closure, Integer>>();
+ }
+
+ void addReference(Closure closure, int index) {
+ mArgIndex.add(Pair.create(closure, Integer.valueOf(index)));
+ }
+
+ void addReference(Closure closure, Script.FieldID fieldID) {
+ mFieldID.add(Pair.create(closure, fieldID));
+ }
+
+ void set(Object value) {
+ for (Pair<Closure, Integer> p : mArgIndex) {
+ Closure closure = p.first;
+ int index = p.second.intValue();
+ closure.setArg(index, value);
+ }
+ for (Pair<Closure, Script.FieldID> p : mFieldID) {
+ Closure closure = p.first;
+ Script.FieldID fieldID = p.second;
+ closure.setGlobal(fieldID, value);
+ }
+ }
+ }
+
+ private String mName;
+ private List<Closure> mClosures;
+ private List<Input> mInputs2;
+ private Future[] mOutputs2;
+
ScriptGroup(long id, RenderScript rs) {
super(id, rs);
}
+ ScriptGroup(RenderScript rs, String name, List<Closure> closures,
+ List<Input> inputs, Future[] outputs) {
+ super(0, rs);
+ mName = name;
+ mClosures = closures;
+ mInputs2 = inputs;
+ mOutputs2 = outputs;
+
+ long[] closureIDs = new long[closures.size()];
+ for (int i = 0; i < closureIDs.length; i++) {
+ closureIDs[i] = closures.get(i).getID(rs);
+ }
+ long id = rs.nScriptGroup2Create(name, ScriptC.mCachePath, closureIDs);
+ setID(id);
+ }
+
+ /**
+ * Executes a script group
+ *
+ * @param inputs inputs to the script group
+ * @return outputs of the script group as an array of objects
+ */
+
+ public Object[] execute(Object... inputs) {
+ if (inputs.length < mInputs2.size()) {
+ Log.e(TAG, this.toString() + " receives " + inputs.length + " inputs, " +
+ "less than expected " + mInputs2.size());
+ return null;
+ }
+
+ if (inputs.length > mInputs2.size()) {
+ Log.i(TAG, this.toString() + " receives " + inputs.length + " inputs, " +
+ "more than expected " + mInputs2.size());
+ }
+
+ for (int i = 0; i < mInputs2.size(); i++) {
+ Object obj = inputs[i];
+ if (obj instanceof Future || obj instanceof Input) {
+ Log.e(TAG, this.toString() + ": input " + i +
+ " is a future or unbound value");
+ return null;
+ }
+ Input unbound = mInputs2.get(i);
+ unbound.set(obj);
+ }
+
+ mRS.nScriptGroup2Execute(getID(mRS));
+
+ Object[] outputObjs = new Object[mOutputs2.length];
+ int i = 0;
+ for (Future f : mOutputs2) {
+ outputObjs[i++] = f.getValue();
+ }
+ return outputObjs;
+ }
+
/**
* Sets an input of the ScriptGroup. This specifies an
* Allocation to be used for kernels that require an input
* Allocation provided from outside of the ScriptGroup.
*
+ * @deprecated Set arguments to {@link #execute(Object...)} instead.
+ *
* @param s The ID of the kernel where the allocation should be
* connected.
* @param a The allocation to connect.
@@ -117,6 +464,8 @@ public final class ScriptGroup extends BaseObj {
* Allocation to be used for the kernels that require an output
* Allocation visible after the ScriptGroup is executed.
*
+ * @deprecated Use return value of {@link #execute(Object...)} instead.
+ *
* @param s The ID of the kernel where the allocation should be
* connected.
* @param a The allocation to connect.
@@ -136,6 +485,9 @@ public final class ScriptGroup extends BaseObj {
* Execute the ScriptGroup. This will run all the kernels in
* the ScriptGroup. No internal connection results will be visible
* after execution of the ScriptGroup.
+ *
+ * @deprecated Use {@link #execute} instead.
+ *
*/
public void execute() {
mRS.nScriptGroupExecute(getID(mRS));
@@ -164,6 +516,8 @@ public final class ScriptGroup extends BaseObj {
* Once all connections are made, a call to {@link #create} will
* return the ScriptGroup object.
*
+ * @deprecated Use {@link Builder2} instead.
+ *
*/
public static final class Builder {
private RenderScript mRS;
@@ -464,7 +818,210 @@ public final class ScriptGroup extends BaseObj {
}
+ /**
+ * Represents a binding of a value to a global variable in a
+ * kernel or invocable function. Used in closure creation.
+ */
-}
+ public static final class Binding {
+ private final Script.FieldID mField;
+ private final Object mValue;
+
+ /**
+ * Returns a Binding object that binds value to field
+ *
+ * @param field the Script.FieldID of the global variable
+ * @param value the value
+ */
+
+ public Binding(Script.FieldID field, Object value) {
+ mField = field;
+ mValue = value;
+ }
+
+ /**
+ * Returns the field ID
+ */
+
+ public Script.FieldID getField() { return mField; }
+
+ /**
+ * Returns the value
+ */
+
+ public Object getValue() { return mValue; }
+ }
+
+ /**
+ * The builder class for creating script groups
+ * <p>
+ * A script group is created using closures (see class {@link Closure}).
+ * A closure is a function call to a kernel or
+ * invocable function. Each function argument or global variable accessed inside
+ * the function is bound to 1) a known value, 2) a script group input
+ * (see class {@link Input}), or 3) a
+ * future (see class {@link Future}).
+ * A future is the output of a closure, either the return value of the
+ * function or a global variable written by that function.
+ * <p>
+ * Closures are created using the {@link #addKernel} or {@link #addInvoke}
+ * methods.
+ * When a closure is created, futures from previously created closures
+ * can be used as its inputs.
+ * External script group inputs can be used as inputs to individual closures as well.
+ * An external script group input is created using the {@link #addInput} method.
+ * A script group is created by a call to the {@link #create} method, which
+ * accepts an array of futures as the outputs for the script group.
+ * <p>
+ * Closures in a script group can be evaluated in any order as long as the
+ * following conditions are met:
+ * 1) a closure must be evaluated before any other closures that take its
+ * futures as inputs;
+ * 2) all closures added before an invoke closure must be evaluated
+ * before it;
+ * and 3) all closures added after an invoke closure must be evaluated after
+ * it.
+ * As a special case, the order that the closures are added is a legal
+ * evaluation order. However, other evaluation orders are possible, including
+ * concurrently evaluating independent closures.
+ */
+
+ public static final class Builder2 {
+ RenderScript mRS;
+ List<Closure> mClosures;
+ List<Input> mInputs;
+ private static final String TAG = "ScriptGroup.Builder2";
+
+ /**
+ * Returns a Builder object
+ *
+ * @param rs the RenderScript context
+ */
+ public Builder2(RenderScript rs) {
+ mRS = rs;
+ mClosures = new ArrayList<Closure>();
+ mInputs = new ArrayList<Input>();
+ }
+ /**
+ * Adds a closure for a kernel
+ *
+ * @param k Kernel ID for the kernel function
+ * @param returnType Allocation type for the return value
+ * @param args arguments to the kernel function
+ * @param globalBindings bindings for global variables
+ * @return a closure
+ */
+ private Closure addKernelInternal(Script.KernelID k, Type returnType, Object[] args,
+ Map<Script.FieldID, Object> globalBindings) {
+ Closure c = new Closure(mRS, k, returnType, args, globalBindings);
+ mClosures.add(c);
+ return c;
+ }
+
+ /**
+ * Adds a closure for an invocable function
+ *
+ * @param invoke Invoke ID for the invocable function
+ * @param args arguments to the invocable function
+ * @param globalBindings bindings for global variables
+ * @return a closure
+ */
+
+ private Closure addInvokeInternal(Script.InvokeID invoke, Object[] args,
+ Map<Script.FieldID, Object> globalBindings) {
+ Closure c = new Closure(mRS, invoke, args, globalBindings);
+ mClosures.add(c);
+ return c;
+ }
+
+ /**
+ * Adds a script group input
+ *
+ * @return a script group input, which can be used as an argument or a value to
+ * a global variable for creating closures
+ */
+ public Input addInput() {
+ Input unbound = new Input();
+ mInputs.add(unbound);
+ return unbound;
+ }
+
+ /**
+ * Adds a closure for a kernel
+ *
+ * @param k Kernel ID for the kernel function
+ * @param argsAndBindings arguments followed by bindings for global variables
+ * @return a closure
+ */
+
+ public Closure addKernel(Script.KernelID k, Type returnType, Object... argsAndBindings) {
+ ArrayList<Object> args = new ArrayList<Object>();
+ Map<Script.FieldID, Object> bindingMap = new HashMap<Script.FieldID, Object>();
+ if (!seperateArgsAndBindings(argsAndBindings, args, bindingMap)) {
+ return null;
+ }
+ return addKernelInternal(k, returnType, args.toArray(), bindingMap);
+ }
+
+ /**
+ * Adds a closure for an invocable function
+ *
+ * @param invoke Invoke ID for the invocable function
+ * @param argsAndBindings arguments followed by bindings for global variables
+ * @return a closure
+ */
+
+ public Closure addInvoke(Script.InvokeID invoke, Object... argsAndBindings) {
+ ArrayList<Object> args = new ArrayList<Object>();
+ Map<Script.FieldID, Object> bindingMap = new HashMap<Script.FieldID, Object>();
+ if (!seperateArgsAndBindings(argsAndBindings, args, bindingMap)) {
+ return null;
+ }
+ return addInvokeInternal(invoke, args.toArray(), bindingMap);
+ }
+
+ /**
+ * Creates a script group
+ *
+ * @param name name for the script group. Legal names can only contain letters, digits,
+ * '-', or '_'. The name can be no longer than 100 characters.
+ * @param outputs futures intended as outputs of the script group
+ * @return a script group
+ */
+
+ public ScriptGroup create(String name, Future... outputs) {
+ if (name == null || name.isEmpty() || name.length() > 100 ||
+ !name.equals(name.replaceAll("[^a-zA-Z0-9-]", "_"))) {
+ throw new RSIllegalArgumentException("invalid script group name");
+ }
+ ScriptGroup ret = new ScriptGroup(mRS, name, mClosures, mInputs, outputs);
+ return ret;
+ }
+
+ private boolean seperateArgsAndBindings(Object[] argsAndBindings,
+ ArrayList<Object> args,
+ Map<Script.FieldID, Object> bindingMap) {
+ int i;
+ for (i = 0; i < argsAndBindings.length; i++) {
+ if (argsAndBindings[i] instanceof Binding) {
+ break;
+ }
+ args.add(argsAndBindings[i]);
+ }
+
+ for (; i < argsAndBindings.length; i++) {
+ if (!(argsAndBindings[i] instanceof Binding)) {
+ return false;
+ }
+ Binding b = (Binding)argsAndBindings[i];
+ bindingMap.put(b.getField(), b.getValue());
+ }
+
+ return true;
+ }
+
+ }
+
+}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 05a4d7e1943d..95a08677bf06 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1287,10 +1287,11 @@ public final class ActivityManagerService extends ActivityManagerNative
final ServiceThread mHandlerThread;
final MainHandler mHandler;
+ final UiHandler mUiHandler;
- final class MainHandler extends Handler {
- public MainHandler(Looper looper) {
- super(looper, null, true);
+ final class UiHandler extends Handler {
+ public UiHandler() {
+ super(com.android.server.UiThread.get().getLooper(), null, true);
}
@Override
@@ -1403,15 +1404,6 @@ public final class ActivityManagerService extends ActivityManagerNative
d.show();
ensureBootCompleted();
} break;
- case UPDATE_CONFIGURATION_MSG: {
- final ContentResolver resolver = mContext.getContentResolver();
- Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
- } break;
- case GC_BACKGROUND_PROCESSES_MSG: {
- synchronized (ActivityManagerService.this) {
- performAppGcsIfAppropriateLocked();
- }
- } break;
case WAIT_FOR_DEBUGGER_MSG: {
synchronized (ActivityManagerService.this) {
ProcessRecord app = (ProcessRecord)msg.obj;
@@ -1432,6 +1424,88 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
} break;
+ case SHOW_UID_ERROR_MSG: {
+ if (mShowDialogs) {
+ AlertDialog d = new BaseErrorDialog(mContext);
+ d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+ d.setCancelable(false);
+ d.setTitle(mContext.getText(R.string.android_system_label));
+ d.setMessage(mContext.getText(R.string.system_error_wipe_data));
+ d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
+ obtainMessage(DISMISS_DIALOG_MSG, d));
+ d.show();
+ }
+ } break;
+ case SHOW_FINGERPRINT_ERROR_MSG: {
+ if (mShowDialogs) {
+ AlertDialog d = new BaseErrorDialog(mContext);
+ d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+ d.setCancelable(false);
+ d.setTitle(mContext.getText(R.string.android_system_label));
+ d.setMessage(mContext.getText(R.string.system_error_manufacturer));
+ d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
+ obtainMessage(DISMISS_DIALOG_MSG, d));
+ d.show();
+ }
+ } break;
+ case SHOW_COMPAT_MODE_DIALOG_MSG: {
+ synchronized (ActivityManagerService.this) {
+ ActivityRecord ar = (ActivityRecord) msg.obj;
+ if (mCompatModeDialog != null) {
+ if (mCompatModeDialog.mAppInfo.packageName.equals(
+ ar.info.applicationInfo.packageName)) {
+ return;
+ }
+ mCompatModeDialog.dismiss();
+ mCompatModeDialog = null;
+ }
+ if (ar != null && false) {
+ if (mCompatModePackages.getPackageAskCompatModeLocked(
+ ar.packageName)) {
+ int mode = mCompatModePackages.computeCompatModeLocked(
+ ar.info.applicationInfo);
+ if (mode == ActivityManager.COMPAT_MODE_DISABLED
+ || mode == ActivityManager.COMPAT_MODE_ENABLED) {
+ mCompatModeDialog = new CompatModeDialog(
+ ActivityManagerService.this, mContext,
+ ar.info.applicationInfo);
+ mCompatModeDialog.show();
+ }
+ }
+ }
+ }
+ break;
+ }
+ case START_USER_SWITCH_MSG: {
+ showUserSwitchDialog(msg.arg1, (String) msg.obj);
+ break;
+ }
+ case DISMISS_DIALOG_MSG: {
+ final Dialog d = (Dialog) msg.obj;
+ d.dismiss();
+ break;
+ }
+ }
+ }
+ }
+
+ final class MainHandler extends Handler {
+ public MainHandler(Looper looper) {
+ super(looper, null, true);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case UPDATE_CONFIGURATION_MSG: {
+ final ContentResolver resolver = mContext.getContentResolver();
+ Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
+ } break;
+ case GC_BACKGROUND_PROCESSES_MSG: {
+ synchronized (ActivityManagerService.this) {
+ performAppGcsIfAppropriateLocked();
+ }
+ } break;
case SERVICE_TIMEOUT_MSG: {
if (mDidDexOpt) {
mDidDexOpt = false;
@@ -1496,30 +1570,6 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
} break;
- case SHOW_UID_ERROR_MSG: {
- if (mShowDialogs) {
- AlertDialog d = new BaseErrorDialog(mContext);
- d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
- d.setCancelable(false);
- d.setTitle(mContext.getText(R.string.android_system_label));
- d.setMessage(mContext.getText(R.string.system_error_wipe_data));
- d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
- mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
- d.show();
- }
- } break;
- case SHOW_FINGERPRINT_ERROR_MSG: {
- if (mShowDialogs) {
- AlertDialog d = new BaseErrorDialog(mContext);
- d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
- d.setCancelable(false);
- d.setTitle(mContext.getText(R.string.android_system_label));
- d.setMessage(mContext.getText(R.string.system_error_manufacturer));
- d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
- mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
- d.show();
- }
- } break;
case PROC_START_TIMEOUT_MSG: {
if (mDidDexOpt) {
mDidDexOpt = false;
@@ -1620,34 +1670,6 @@ public final class ActivityManagerService extends ActivityManagerNative
sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
}
} break;
- case SHOW_COMPAT_MODE_DIALOG_MSG: {
- synchronized (ActivityManagerService.this) {
- ActivityRecord ar = (ActivityRecord)msg.obj;
- if (mCompatModeDialog != null) {
- if (mCompatModeDialog.mAppInfo.packageName.equals(
- ar.info.applicationInfo.packageName)) {
- return;
- }
- mCompatModeDialog.dismiss();
- mCompatModeDialog = null;
- }
- if (ar != null && false) {
- if (mCompatModePackages.getPackageAskCompatModeLocked(
- ar.packageName)) {
- int mode = mCompatModePackages.computeCompatModeLocked(
- ar.info.applicationInfo);
- if (mode == ActivityManager.COMPAT_MODE_DISABLED
- || mode == ActivityManager.COMPAT_MODE_ENABLED) {
- mCompatModeDialog = new CompatModeDialog(
- ActivityManagerService.this, mContext,
- ar.info.applicationInfo);
- mCompatModeDialog.show();
- }
- }
- }
- }
- break;
- }
case DISPATCH_PROCESSES_CHANGED: {
dispatchProcessesChanged();
break;
@@ -1668,10 +1690,6 @@ public final class ActivityManagerService extends ActivityManagerNative
thread.start();
break;
}
- case START_USER_SWITCH_MSG: {
- showUserSwitchDialog(msg.arg1, (String) msg.obj);
- break;
- }
case REPORT_USER_SWITCH_MSG: {
dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
break;
@@ -1779,11 +1797,6 @@ public final class ActivityManagerService extends ActivityManagerNative
}
break;
}
- case DISMISS_DIALOG_MSG: {
- final Dialog d = (Dialog) msg.obj;
- d.dismiss();
- break;
- }
case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
synchronized (ActivityManagerService.this) {
int i = mTaskStackListeners.beginBroadcast();
@@ -2078,6 +2091,7 @@ public final class ActivityManagerService extends ActivityManagerNative
android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
+ mUiHandler = new UiHandler();
mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
"foreground", BROADCAST_FG_TIMEOUT, false);
@@ -2443,7 +2457,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Message msg = Message.obtain();
msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
msg.obj = r.task.askedCompatMode ? null : r;
- mHandler.sendMessage(msg);
+ mUiHandler.sendMessage(msg);
}
private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
@@ -3002,6 +3016,10 @@ public final class ActivityManagerService extends ActivityManagerNative
debugFlags |= Zygote.DEBUG_ENABLE_JIT;
}
}
+ String genCFIDebugProperty = SystemProperties.get("debug.gencfi");
+ if ("true".equals(genCFIDebugProperty)) {
+ debugFlags |= Zygote.DEBUG_GENERATE_CFI;
+ }
if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
}
@@ -5100,20 +5118,20 @@ public final class ActivityManagerService extends ActivityManagerNative
map.put("activity", activity);
}
- mHandler.sendMessage(msg);
+ mUiHandler.sendMessage(msg);
}
}
final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
if (!mLaunchWarningShown) {
mLaunchWarningShown = true;
- mHandler.post(new Runnable() {
+ mUiHandler.post(new Runnable() {
@Override
public void run() {
synchronized (ActivityManagerService.this) {
final Dialog d = new LaunchWarningWindow(mContext, cur, next);
d.show();
- mHandler.postDelayed(new Runnable() {
+ mUiHandler.postDelayed(new Runnable() {
@Override
public void run() {
synchronized (ActivityManagerService.this) {
@@ -5802,17 +5820,20 @@ public final class ActivityManagerService extends ActivityManagerNative
if (app.isolated) {
mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
}
- app.kill(reason, true);
- handleAppDiedLocked(app, true, allowRestart);
- removeLruProcessLocked(app);
-
+ boolean willRestart = false;
if (app.persistent && !app.isolated) {
if (!callerWillRestart) {
- addAppLocked(app.info, false, null /* ABI override */);
+ willRestart = true;
} else {
needRestart = true;
}
}
+ app.kill(reason, true);
+ handleAppDiedLocked(app, willRestart, allowRestart);
+ if (willRestart) {
+ removeLruProcessLocked(app);
+ addAppLocked(app.info, false, null /* ABI override */);
+ }
} else {
mRemovedProcesses.add(app);
}
@@ -8053,7 +8074,7 @@ public final class ActivityManagerService extends ActivityManagerNative
msg.what = WAIT_FOR_DEBUGGER_MSG;
msg.obj = app;
msg.arg1 = waiting ? 1 : 0;
- mHandler.sendMessage(msg);
+ mUiHandler.sendMessage(msg);
}
}
@@ -11359,7 +11380,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Message msg = Message.obtain();
msg.what = SHOW_FACTORY_ERROR_MSG;
msg.getData().putCharSequence("msg", errorMsg);
- mHandler.sendMessage(msg);
+ mUiHandler.sendMessage(msg);
}
}
}
@@ -11409,14 +11430,14 @@ public final class ActivityManagerService extends ActivityManagerNative
if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
+ " data partition or your device will be unstable.");
- mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
+ mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
}
} catch (RemoteException e) {
}
if (!Build.isFingerprintConsistent()) {
Slog.e(TAG, "Build fingerprint is not consistent, warning user");
- mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
+ mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
}
long ident = Binder.clearCallingIdentity();
@@ -11702,7 +11723,7 @@ public final class ActivityManagerService extends ActivityManagerNative
data.put("violationMask", violationMask);
data.put("info", info);
msg.obj = data;
- mHandler.sendMessage(msg);
+ mUiHandler.sendMessage(msg);
Binder.restoreCallingIdentity(origId);
}
@@ -12157,7 +12178,7 @@ public final class ActivityManagerService extends ActivityManagerNative
data.put("result", result);
data.put("app", r);
msg.obj = data;
- mHandler.sendMessage(msg);
+ mUiHandler.sendMessage(msg);
Binder.restoreCallingIdentity(origId);
}
@@ -14891,7 +14912,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- for (int i=0; i<cpr.connections.size(); i++) {
+ for (int i = cpr.connections.size() - 1; i >= 0; i--) {
ContentProviderConnection conn = cpr.connections.get(i);
if (conn.waiting) {
// If this connection is waiting for the provider, then we don't
@@ -14983,10 +15004,11 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean restart = false;
// Remove published content providers.
- for (int i=app.pubProviders.size()-1; i>=0; i--) {
+ for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
ContentProviderRecord cpr = app.pubProviders.valueAt(i);
final boolean always = app.bad || !allowRestart;
- if (removeDyingProviderLocked(app, cpr, always) || always) {
+ boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
+ if ((inLaunching || always) && !cpr.connections.isEmpty()) {
// We left the provider in the launching list, need to
// restart it.
restart = true;
@@ -15004,7 +15026,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// Unregister from connected content providers.
if (!app.conProviders.isEmpty()) {
- for (int i=0; i<app.conProviders.size(); i++) {
+ for (int i = app.conProviders.size() - 1; i >= 0; i--) {
ContentProviderConnection conn = app.conProviders.get(i);
conn.provider.connections.remove(conn);
stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
@@ -15019,9 +15041,8 @@ public final class ActivityManagerService extends ActivityManagerNative
// XXX Commented out for now. Trying to figure out a way to reproduce
// the actual situation to identify what is actually going on.
if (false) {
- for (int i=0; i<mLaunchingProviders.size(); i++) {
- ContentProviderRecord cpr = (ContentProviderRecord)
- mLaunchingProviders.get(i);
+ for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
+ ContentProviderRecord cpr = mLaunchingProviders.get(i);
if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
synchronized (cpr) {
cpr.launchingApp = null;
@@ -15034,7 +15055,7 @@ public final class ActivityManagerService extends ActivityManagerNative
skipCurrentReceiverLocked(app);
// Unregister any receivers.
- for (int i=app.receivers.size()-1; i>=0; i--) {
+ for (int i = app.receivers.size() - 1; i >= 0; i--) {
removeReceiverLocked(app.receivers.valueAt(i));
}
app.receivers.clear();
@@ -15052,7 +15073,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
+ for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
ProcessChangeItem item = mPendingProcessChanges.get(i);
if (item.pid == app.pid) {
mPendingProcessChanges.remove(i);
@@ -15127,18 +15148,14 @@ public final class ActivityManagerService extends ActivityManagerNative
// and if any run in this process then either schedule a restart of
// the process or kill the client waiting for it if this process has
// gone bad.
- int NL = mLaunchingProviders.size();
boolean restart = false;
- for (int i=0; i<NL; i++) {
+ for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
ContentProviderRecord cpr = mLaunchingProviders.get(i);
if (cpr.launchingApp == app) {
- if (!alwaysBad && !app.bad) {
+ if (!alwaysBad && !app.bad && !cpr.connections.isEmpty()) {
restart = true;
} else {
removeDyingProviderLocked(app, cpr, true);
- // cpr should have been removed from mLaunchingProviders
- NL = mLaunchingProviders.size();
- i--;
}
}
}
@@ -18922,8 +18939,8 @@ public final class ActivityManagerService extends ActivityManagerNative
userName = userInfo.name;
mTargetUserId = userId;
}
- mHandler.removeMessages(START_USER_SWITCH_MSG);
- mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
+ mUiHandler.removeMessages(START_USER_SWITCH_MSG);
+ mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
return true;
}
diff --git a/tools/obbtool/pbkdf2gen.cpp b/tools/obbtool/pbkdf2gen.cpp
index 98d67c0b575c..f1d8d04ea01e 100644
--- a/tools/obbtool/pbkdf2gen.cpp
+++ b/tools/obbtool/pbkdf2gen.cpp
@@ -20,6 +20,7 @@
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>