diff options
68 files changed, 2203 insertions, 1193 deletions
diff --git a/api/current.txt b/api/current.txt index 35423fd..7737487 100644 --- a/api/current.txt +++ b/api/current.txt @@ -547,6 +547,7 @@ package android { field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6 field public static final int exported = 16842768; // 0x1010010 field public static final int extraTension = 16843371; // 0x101026b + field public static final int extractNativeLibs = 16843990; // 0x10104d6 field public static final int factor = 16843219; // 0x10101d3 field public static final int fadeDuration = 16843384; // 0x1010278 field public static final int fadeEnabled = 16843390; // 0x101027e @@ -8366,6 +8367,7 @@ package android.content.pm { field public static final int FLAG_ALLOW_TASK_REPARENTING = 32; // 0x20 field public static final int FLAG_DEBUGGABLE = 2; // 0x2 field public static final int FLAG_EXTERNAL_STORAGE = 262144; // 0x40000 + field public static final int FLAG_EXTRACT_NATIVE_LIBS = 268435456; // 0x10000000 field public static final int FLAG_FACTORY_TEST = 16; // 0x10 field public static final int FLAG_FULL_BACKUP_ONLY = 67108864; // 0x4000000 field public static final int FLAG_HAS_CODE = 4; // 0x4 @@ -16994,6 +16996,7 @@ package android.net { } public final class IpPrefix implements android.os.Parcelable { + method public boolean contains(java.net.InetAddress); method public int describeContents(); method public java.net.InetAddress getAddress(); method public int getPrefixLength(); @@ -17513,7 +17516,7 @@ package android.net.http { method public static android.net.http.HttpResponseCache getInstalled(); method public int getNetworkCount(); method public int getRequestCount(); - method public static android.net.http.HttpResponseCache install(java.io.File, long) throws java.io.IOException; + method public static synchronized android.net.http.HttpResponseCache install(java.io.File, long) throws java.io.IOException; method public long maxSize(); method public java.net.CacheRequest put(java.net.URI, java.net.URLConnection) throws java.io.IOException; method public long size(); @@ -18440,6 +18443,7 @@ package android.nfc { public final class NfcEvent { field public final android.nfc.NfcAdapter nfcAdapter; + field public final byte peerLlcpVersion; } public final class NfcManager { @@ -26514,6 +26518,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); @@ -26554,6 +26559,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 { } @@ -26578,12 +26586,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.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 class ScriptGroup.Builder { + 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); @@ -26591,6 +26606,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 { } @@ -41517,7 +41551,7 @@ package java.lang { method public static double nextUp(double); method public static float nextUp(float); method public static double pow(double, double); - method public static synchronized double random(); + method public static double random(); method public static double rint(double); method public static long round(double); method public static int round(float); diff --git a/api/system-current.txt b/api/system-current.txt index fe0e2e4..1041cb7 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -617,6 +617,7 @@ package android { field public static final int expandableListViewWhiteStyle = 16843446; // 0x10102b6 field public static final int exported = 16842768; // 0x1010010 field public static final int extraTension = 16843371; // 0x101026b + field public static final int extractNativeLibs = 16843990; // 0x10104d6 field public static final int factor = 16843219; // 0x10101d3 field public static final int fadeDuration = 16843384; // 0x1010278 field public static final int fadeEnabled = 16843390; // 0x101027e @@ -8614,6 +8615,7 @@ package android.content.pm { field public static final int FLAG_ALLOW_TASK_REPARENTING = 32; // 0x20 field public static final int FLAG_DEBUGGABLE = 2; // 0x2 field public static final int FLAG_EXTERNAL_STORAGE = 262144; // 0x40000 + field public static final int FLAG_EXTRACT_NATIVE_LIBS = 268435456; // 0x10000000 field public static final int FLAG_FACTORY_TEST = 16; // 0x10 field public static final int FLAG_FULL_BACKUP_ONLY = 67108864; // 0x4000000 field public static final int FLAG_HAS_CODE = 4; // 0x4 @@ -18257,6 +18259,7 @@ package android.net { } public final class IpPrefix implements android.os.Parcelable { + method public boolean contains(java.net.InetAddress); method public int describeContents(); method public java.net.InetAddress getAddress(); method public int getPrefixLength(); @@ -18841,7 +18844,7 @@ package android.net.http { method public static android.net.http.HttpResponseCache getInstalled(); method public int getNetworkCount(); method public int getRequestCount(); - method public static android.net.http.HttpResponseCache install(java.io.File, long) throws java.io.IOException; + method public static synchronized android.net.http.HttpResponseCache install(java.io.File, long) throws java.io.IOException; method public long maxSize(); method public java.net.CacheRequest put(java.net.URI, java.net.URLConnection) throws java.io.IOException; method public long size(); @@ -20024,6 +20027,7 @@ package android.nfc { public final class NfcEvent { field public final android.nfc.NfcAdapter nfcAdapter; + field public final byte peerLlcpVersion; } public final class NfcManager { @@ -28113,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); @@ -28153,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 { } @@ -28177,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.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 class ScriptGroup.Builder { + 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); @@ -28190,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 { } @@ -44055,7 +44089,7 @@ package java.lang { method public static double nextUp(double); method public static float nextUp(float); method public static double pow(double, double); - method public static synchronized double random(); + method public static double random(); method public static double rint(double); method public static long round(double); method public static int round(float); diff --git a/cmds/app_process/Android.mk b/cmds/app_process/Android.mk index dd5e0ea..ce6d7b5 100644 --- a/cmds/app_process/Android.mk +++ b/cmds/app_process/Android.mk @@ -56,6 +56,7 @@ LOCAL_MODULE_TAGS := eng LOCAL_MODULE_PATH := $(TARGET_OUT_EXECUTABLES)/asan LOCAL_MODULE_STEM := app_process LOCAL_ADDRESS_SANITIZER := true +LOCAL_CLANG := true LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java index 92762c3..5055b29 100644 --- a/core/java/android/animation/AnimatorSet.java +++ b/core/java/android/animation/AnimatorSet.java @@ -1082,7 +1082,8 @@ public final class AnimatorSet extends Animator { public Node clone() { try { Node node = (Node) super.clone(); - node.animation = (Animator) animation.clone(); + node.animation = animation.clone(); + node.done = false; return node; } catch (CloneNotSupportedException e) { throw new AssertionError(); diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index 9709555..2be3e23 100644 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -1389,6 +1389,12 @@ public class ValueAnimator extends Animator { anim.mInitialized = false; anim.mPlayingState = STOPPED; anim.mStartedDelay = false; + anim.mStarted = false; + anim.mRunning = false; + anim.mPaused = false; + anim.mResumed = false; + anim.mStartListenersCalled = false; + PropertyValuesHolder[] oldValues = mValues; if (oldValues != null) { int numValues = oldValues.length; diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 6cbfee7..850bc1f 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; @@ -4650,74 +4645,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; @@ -4800,12 +4744,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; @@ -4816,7 +4756,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; @@ -5138,12 +5078,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/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java index 8e86824..7eb4b2f 100644 --- a/core/java/android/appwidget/AppWidgetHost.java +++ b/core/java/android/appwidget/AppWidgetHost.java @@ -221,10 +221,10 @@ public class AppWidgetHost { int appWidgetId, int intentFlags, int requestCode, @Nullable Bundle options) { try { IntentSender intentSender = sService.createAppWidgetConfigIntentSender( - mContextOpPackageName, appWidgetId, intentFlags); + mContextOpPackageName, appWidgetId); if (intentSender != null) { - activity.startIntentSenderForResult(intentSender, requestCode, null, 0, 0, 0, - options); + activity.startIntentSenderForResult(intentSender, requestCode, null, 0, + intentFlags, intentFlags, options); } else { throw new ActivityNotFoundException(); } diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index b3c558b..4a087da 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -346,6 +346,11 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { public static final int FLAG_USES_CLEARTEXT_TRAFFIC = 1<<27; /** + * When set installer extracts native libs from .apk files. + */ + public static final int FLAG_EXTRACT_NATIVE_LIBS = 1<<28; + + /** * Value for {@link #flags}: true if code from this application will need to be * loaded into other applications' processes. On devices that support multiple * instruction sets, this implies the code might be loaded into a process that's diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 5320929..53aa6ff 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -268,6 +268,7 @@ public class PackageParser { public final boolean coreApp; public final boolean multiArch; + public final boolean extractNativeLibs; public PackageLite(String codePath, ApkLite baseApk, String[] splitNames, String[] splitCodePaths, int[] splitRevisionCodes) { @@ -283,6 +284,7 @@ public class PackageParser { this.splitRevisionCodes = splitRevisionCodes; this.coreApp = baseApk.coreApp; this.multiArch = baseApk.multiArch; + this.extractNativeLibs = baseApk.extractNativeLibs; } public List<String> getAllCodePaths() { @@ -309,10 +311,12 @@ public class PackageParser { public final Signature[] signatures; public final boolean coreApp; public final boolean multiArch; + public final boolean extractNativeLibs; public ApkLite(String codePath, String packageName, String splitName, int versionCode, int revisionCode, int installLocation, List<VerifierInfo> verifiers, - Signature[] signatures, boolean coreApp, boolean multiArch) { + Signature[] signatures, boolean coreApp, boolean multiArch, + boolean extractNativeLibs) { this.codePath = codePath; this.packageName = packageName; this.splitName = splitName; @@ -323,6 +327,7 @@ public class PackageParser { this.signatures = signatures; this.coreApp = coreApp; this.multiArch = multiArch; + this.extractNativeLibs = extractNativeLibs; } } @@ -1269,6 +1274,7 @@ public class PackageParser { int revisionCode = 0; boolean coreApp = false; boolean multiArch = false; + boolean extractNativeLibs = true; for (int i = 0; i < attrs.getAttributeCount(); i++) { final String attr = attrs.getAttributeName(i); @@ -1307,14 +1313,17 @@ public class PackageParser { final String attr = attrs.getAttributeName(i); if ("multiArch".equals(attr)) { multiArch = attrs.getAttributeBooleanValue(i, false); - break; + } + if ("extractNativeLibs".equals(attr)) { + extractNativeLibs = attrs.getAttributeBooleanValue(i, true); } } } } return new ApkLite(codePath, packageSplit.first, packageSplit.second, versionCode, - revisionCode, installLocation, verifiers, signatures, coreApp, multiArch); + revisionCode, installLocation, verifiers, signatures, coreApp, multiArch, + extractNativeLibs); } /** @@ -2567,6 +2576,12 @@ public class PackageParser { ai.flags |= ApplicationInfo.FLAG_MULTIARCH; } + if (sa.getBoolean( + com.android.internal.R.styleable.AndroidManifestApplication_extractNativeLibs, + true)) { + ai.flags |= ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS; + } + String str; str = sa.getNonConfigurationString( com.android.internal.R.styleable.AndroidManifestApplication_permission, 0); diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java index 24a7d33..3cda39a 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/IpPrefix.java b/core/java/android/net/IpPrefix.java index b268986..6b4f2d5 100644 --- a/core/java/android/net/IpPrefix.java +++ b/core/java/android/net/IpPrefix.java @@ -170,6 +170,21 @@ public final class IpPrefix implements Parcelable { } /** + * Determines whether the prefix contains the specified address. + * + * @param address An {@link InetAddress} to test. + * @return {@code true} if the prefix covers the given address. + */ + public boolean contains(InetAddress address) { + byte[] addrBytes = (address == null) ? null : address.getAddress(); + if (addrBytes == null || addrBytes.length != this.address.length) { + return false; + } + NetworkUtils.maskRawAddress(addrBytes, prefixLength); + return Arrays.equals(this.address, addrBytes); + } + + /** * Returns a string representation of this {@code IpPrefix}. * * @return a string such as {@code "192.0.2.0/24"} or {@code "2001:db8:1:2::/64"}. diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java index cfd20a0..90a2460 100644 --- a/core/java/android/net/RouteInfo.java +++ b/core/java/android/net/RouteInfo.java @@ -367,13 +367,7 @@ public final class RouteInfo implements Parcelable { * @return {@code true} if the destination and prefix length cover the given address. */ public boolean matches(InetAddress destination) { - if (destination == null) return false; - - // match the route destination and destination with prefix length - InetAddress dstNet = NetworkUtils.getNetworkPart(destination, - mDestination.getPrefixLength()); - - return mDestination.getAddress().equals(dstNet); + return mDestination.contains(destination); } /** diff --git a/core/java/android/nfc/IAppCallback.aidl b/core/java/android/nfc/IAppCallback.aidl index 9599308..c027d54 100644 --- a/core/java/android/nfc/IAppCallback.aidl +++ b/core/java/android/nfc/IAppCallback.aidl @@ -24,7 +24,7 @@ import android.nfc.Tag; */ interface IAppCallback { - BeamShareData createBeamShareData(); - void onNdefPushComplete(); + BeamShareData createBeamShareData(byte peerLlcpVersion); + void onNdefPushComplete(byte peerLlcpVersion); void onTagDiscovered(in Tag tag); } diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java index d009295..76bd0ec 100644 --- a/core/java/android/nfc/NfcActivityManager.java +++ b/core/java/android/nfc/NfcActivityManager.java @@ -46,7 +46,6 @@ public final class NfcActivityManager extends IAppCallback.Stub static final Boolean DBG = false; final NfcAdapter mAdapter; - final NfcEvent mDefaultEvent; // cached NfcEvent (its currently always the same) // All objects in the lists are protected by this final List<NfcApplicationState> mApps; // Application(s) that have NFC state. Usually one @@ -200,7 +199,6 @@ public final class NfcActivityManager extends IAppCallback.Stub mAdapter = adapter; mActivities = new LinkedList<NfcActivityState>(); mApps = new ArrayList<NfcApplicationState>(1); // Android VM usually has 1 app - mDefaultEvent = new NfcEvent(mAdapter); } public void enableReaderMode(Activity activity, ReaderCallback callback, int flags, @@ -354,13 +352,14 @@ public final class NfcActivityManager extends IAppCallback.Stub /** Callback from NFC service, usually on binder thread */ @Override - public BeamShareData createBeamShareData() { + public BeamShareData createBeamShareData(byte peerLlcpVersion) { NfcAdapter.CreateNdefMessageCallback ndefCallback; NfcAdapter.CreateBeamUrisCallback urisCallback; NdefMessage message; Activity activity; Uri[] uris; int flags; + NfcEvent event = new NfcEvent(mAdapter, peerLlcpVersion); synchronized (NfcActivityManager.this) { NfcActivityState state = findResumedActivityState(); if (state == null) return null; @@ -375,10 +374,10 @@ public final class NfcActivityManager extends IAppCallback.Stub // Make callbacks without lock if (ndefCallback != null) { - message = ndefCallback.createNdefMessage(mDefaultEvent); + message = ndefCallback.createNdefMessage(event); } if (urisCallback != null) { - uris = urisCallback.createBeamUris(mDefaultEvent); + uris = urisCallback.createBeamUris(event); if (uris != null) { ArrayList<Uri> validUris = new ArrayList<Uri>(); for (Uri uri : uris) { @@ -412,7 +411,7 @@ public final class NfcActivityManager extends IAppCallback.Stub /** Callback from NFC service, usually on binder thread */ @Override - public void onNdefPushComplete() { + public void onNdefPushComplete(byte peerLlcpVersion) { NfcAdapter.OnNdefPushCompleteCallback callback; synchronized (NfcActivityManager.this) { NfcActivityState state = findResumedActivityState(); @@ -420,10 +419,10 @@ public final class NfcActivityManager extends IAppCallback.Stub callback = state.onNdefPushCompleteCallback; } - + NfcEvent event = new NfcEvent(mAdapter, peerLlcpVersion); // Make callback without lock if (callback != null) { - callback.onNdefPushComplete(mDefaultEvent); + callback.onNdefPushComplete(event); } } diff --git a/core/java/android/nfc/NfcEvent.java b/core/java/android/nfc/NfcEvent.java index 860700a..cf1d71a 100644 --- a/core/java/android/nfc/NfcEvent.java +++ b/core/java/android/nfc/NfcEvent.java @@ -38,7 +38,14 @@ public final class NfcEvent { */ public final NfcAdapter nfcAdapter; - NfcEvent(NfcAdapter nfcAdapter) { + /** + * The LLCP version of the peer associated with the NFC event. + * The major version is in the top nibble, the minor version is in the bottom nibble. + */ + public final byte peerLlcpVersion; + + NfcEvent(NfcAdapter nfcAdapter, byte peerLlcpVersion) { this.nfcAdapter = nfcAdapter; + this.peerLlcpVersion = peerLlcpVersion; } } diff --git a/core/java/android/security/keymaster/KeymasterArgument.java b/core/java/android/security/keymaster/KeymasterArgument.java index 9a1c894..9adde35 100644 --- a/core/java/android/security/keymaster/KeymasterArgument.java +++ b/core/java/android/security/keymaster/KeymasterArgument.java @@ -42,6 +42,7 @@ abstract class KeymasterArgument implements Parcelable { case KeymasterDefs.KM_INT_REP: return new KeymasterIntArgument(tag, in); case KeymasterDefs.KM_LONG: + case KeymasterDefs.KM_LONG_REP: return new KeymasterLongArgument(tag, in); case KeymasterDefs.KM_DATE: return new KeymasterDateArgument(tag, in); diff --git a/core/java/android/security/keymaster/KeymasterArguments.java b/core/java/android/security/keymaster/KeymasterArguments.java index 8ed288c..82f65c7 100644 --- a/core/java/android/security/keymaster/KeymasterArguments.java +++ b/core/java/android/security/keymaster/KeymasterArguments.java @@ -63,6 +63,12 @@ public class KeymasterArguments implements Parcelable { } } + public void addLongs(int tag, long... values) { + for (long value : values) { + addLong(tag, value); + } + } + public void addBoolean(int tag) { mArguments.add(new KeymasterBooleanArgument(tag)); } @@ -111,8 +117,13 @@ public class KeymasterArguments implements Parcelable { } public long getLong(int tag, long defaultValue) { - if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_LONG) { - throw new IllegalArgumentException("Tag is not a long type: " + tag); + switch (KeymasterDefs.getTagType(tag)) { + case KeymasterDefs.KM_LONG: + break; // Accepted type + case KeymasterDefs.KM_LONG_REP: + throw new IllegalArgumentException("Repeatable tags must use getLongs: " + tag); + default: + throw new IllegalArgumentException("Tag is not a long type: " + tag); } KeymasterArgument arg = getArgumentByTag(tag); if (arg == null) { @@ -175,6 +186,19 @@ public class KeymasterArguments implements Parcelable { return values; } + public List<Long> getLongs(int tag) { + if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_LONG_REP) { + throw new IllegalArgumentException("Tag is not a repeating long: " + tag); + } + List<Long> values = new ArrayList<Long>(); + for (KeymasterArgument arg : mArguments) { + if (arg.tag == tag) { + values.add(((KeymasterLongArgument) arg).value); + } + } + return values; + } + public int size() { return mArguments.size(); } diff --git a/core/java/android/security/keymaster/KeymasterLongArgument.java b/core/java/android/security/keymaster/KeymasterLongArgument.java index d51d7e6..e04ce5d 100644 --- a/core/java/android/security/keymaster/KeymasterLongArgument.java +++ b/core/java/android/security/keymaster/KeymasterLongArgument.java @@ -29,6 +29,7 @@ class KeymasterLongArgument extends KeymasterArgument { super(tag); switch (KeymasterDefs.getTagType(tag)) { case KeymasterDefs.KM_LONG: + case KeymasterDefs.KM_LONG_REP: break; // OK. default: throw new IllegalArgumentException("Bad long tag " + tag); diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 1674950..016541f 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -17,6 +17,7 @@ package android.service.wallpaper; import android.content.res.TypedArray; +import android.graphics.Canvas; import android.os.SystemProperties; import android.view.WindowInsets; @@ -185,6 +186,7 @@ public abstract class WallpaperService extends Service { DisplayManager mDisplayManager; Display mDisplay; + private int mDisplayState; final BaseSurfaceHolder mSurfaceHolder = new BaseSurfaceHolder() { { @@ -228,7 +230,19 @@ public abstract class WallpaperService extends Service { throw new UnsupportedOperationException( "Wallpapers do not support keep screen on"); } - + + @Override + public Canvas lockCanvas() { + if (mDisplayState == Display.STATE_DOZE + || mDisplayState == Display.STATE_DOZE_SUSPEND) { + try { + mSession.pokeDrawLock(mWindow); + } catch (RemoteException e) { + // System server died, can be ignored. + } + } + return super.lockCanvas(); + } }; final class WallpaperInputEventReceiver extends InputEventReceiver { @@ -831,9 +845,12 @@ public abstract class WallpaperService extends Service { mWindow.setSession(mSession); + mLayout.packageName = getPackageName(); + mDisplayManager = (DisplayManager)getSystemService(Context.DISPLAY_SERVICE); mDisplayManager.registerDisplayListener(mDisplayListener, mCaller.getHandler()); mDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY); + mDisplayState = mDisplay.getState(); if (DEBUG) Log.v(TAG, "onCreate(): " + this); onCreate(mSurfaceHolder); @@ -873,8 +890,8 @@ public abstract class WallpaperService extends Service { void reportVisibility() { if (!mDestroyed) { - boolean visible = mVisible - & mDisplay != null && mDisplay.getState() != Display.STATE_OFF; + mDisplayState = mDisplay == null ? Display.STATE_UNKNOWN : mDisplay.getState(); + boolean visible = mVisible && mDisplayState != Display.STATE_OFF; if (mReportedVisible != visible) { mReportedVisible = visible; if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + visible diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java index a237afd..27304f5 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/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl index 008d38b..faac392 100644 --- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl +++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl @@ -41,8 +41,7 @@ interface IAppWidgetService { void deleteAllHosts(); RemoteViews getAppWidgetViews(String callingPackage, int appWidgetId); int[] getAppWidgetIdsForHost(String callingPackage, int hostId); - IntentSender createAppWidgetConfigIntentSender(String callingPackage, int appWidgetId, - int intentFlags); + IntentSender createAppWidgetConfigIntentSender(String callingPackage, int appWidgetId); // // for AppWidgetManager diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java index 02f675c..f479f4f 100644 --- a/core/java/com/android/internal/content/NativeLibraryHelper.java +++ b/core/java/com/android/internal/content/NativeLibraryHelper.java @@ -33,6 +33,7 @@ import android.content.pm.PackageParser.PackageLite; import android.content.pm.PackageParser.PackageParserException; import android.os.Build; import android.os.SELinux; +import android.os.SystemProperties; import android.system.ErrnoException; import android.system.Os; import android.util.Slog; @@ -74,6 +75,7 @@ public class NativeLibraryHelper { final long[] apkHandles; final boolean multiArch; + final boolean extractNativeLibs; public static Handle create(File packageFile) throws IOException { try { @@ -86,14 +88,16 @@ public class NativeLibraryHelper { public static Handle create(Package pkg) throws IOException { return create(pkg.getAllCodePaths(), - (pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0); + (pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0, + (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) != 0); } public static Handle create(PackageLite lite) throws IOException { - return create(lite.getAllCodePaths(), lite.multiArch); + return create(lite.getAllCodePaths(), lite.multiArch, lite.extractNativeLibs); } - private static Handle create(List<String> codePaths, boolean multiArch) throws IOException { + private static Handle create(List<String> codePaths, boolean multiArch, + boolean extractNativeLibs) throws IOException { final int size = codePaths.size(); final long[] apkHandles = new long[size]; for (int i = 0; i < size; i++) { @@ -108,12 +112,13 @@ public class NativeLibraryHelper { } } - return new Handle(apkHandles, multiArch); + return new Handle(apkHandles, multiArch, extractNativeLibs); } - Handle(long[] apkHandles, boolean multiArch) { + Handle(long[] apkHandles, boolean multiArch, boolean extractNativeLibs) { this.apkHandles = apkHandles; this.multiArch = multiArch; + this.extractNativeLibs = extractNativeLibs; mGuard.open("close"); } @@ -146,8 +151,8 @@ public class NativeLibraryHelper { private static native long nativeSumNativeBinaries(long handle, String cpuAbi); - private native static int nativeCopyNativeBinaries(long handle, - String sharedLibraryPath, String abiToCopy); + private native static int nativeCopyNativeBinaries(long handle, String sharedLibraryPath, + String abiToCopy, boolean extractNativeLibs, boolean hasNativeBridge); private static long sumNativeBinaries(Handle handle, String abi) { long sum = 0; @@ -167,7 +172,8 @@ public class NativeLibraryHelper { */ public static int copyNativeBinaries(Handle handle, File sharedLibraryDir, String abi) { for (long apkHandle : handle.apkHandles) { - int res = nativeCopyNativeBinaries(apkHandle, sharedLibraryDir.getPath(), abi); + int res = nativeCopyNativeBinaries(apkHandle, sharedLibraryDir.getPath(), abi, + handle.extractNativeLibs, HAS_NATIVE_BRIDGE); if (res != INSTALL_SUCCEEDED) { return res; } @@ -218,7 +224,8 @@ public class NativeLibraryHelper { /** * Remove the native binaries of a given package. This deletes the files */ - public static void removeNativeBinariesFromDirLI(File nativeLibraryRoot, boolean deleteRootDir) { + public static void removeNativeBinariesFromDirLI(File nativeLibraryRoot, + boolean deleteRootDir) { if (DEBUG_NATIVE) { Slog.w(TAG, "Deleting native binaries from: " + nativeLibraryRoot.getPath()); } @@ -247,7 +254,8 @@ public class NativeLibraryHelper { // asked to or this will prevent installation of future updates. if (deleteRootDir) { if (!nativeLibraryRoot.delete()) { - Slog.w(TAG, "Could not delete native binary directory: " + nativeLibraryRoot.getPath()); + Slog.w(TAG, "Could not delete native binary directory: " + + nativeLibraryRoot.getPath()); } } } @@ -416,6 +424,9 @@ public class NativeLibraryHelper { // We don't care about the other return values for now. private static final int BITCODE_PRESENT = 1; + private static final boolean HAS_NATIVE_BRIDGE = + !"0".equals(SystemProperties.get("ro.dalvik.vm.native.bridge", "0")); + private static native int hasRenderscriptBitcode(long apkHandle); public static boolean hasRenderscriptBitcode(Handle handle) throws IOException { diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 50ddbd1..d44959b 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/java/com/android/internal/widget/SwipeDismissLayout.java b/core/java/com/android/internal/widget/SwipeDismissLayout.java index 89990c2..6d4e058 100644 --- a/core/java/com/android/internal/widget/SwipeDismissLayout.java +++ b/core/java/com/android/internal/widget/SwipeDismissLayout.java @@ -111,7 +111,7 @@ public class SwipeDismissLayout extends FrameLayout { } private void init(Context context) { - ViewConfiguration vc = ViewConfiguration.get(getContext()); + ViewConfiguration vc = ViewConfiguration.get(context); mSlop = vc.getScaledTouchSlop(); mMinFlingVelocity = vc.getScaledMinimumFlingVelocity(); mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity(); @@ -216,6 +216,8 @@ public class SwipeDismissLayout extends FrameLayout { if (mVelocityTracker == null) { return super.onTouchEvent(ev); } + // offset because the view is translated during swipe + ev.offsetLocation(mTranslationX, 0); switch (ev.getActionMasked()) { case MotionEvent.ACTION_UP: updateDismiss(ev); @@ -290,7 +292,7 @@ public class SwipeDismissLayout extends FrameLayout { float deltaX = ev.getRawX() - mDownX; float deltaY = ev.getRawY() - mDownY; if ((deltaX * deltaX) + (deltaY * deltaY) > mSlop * mSlop) { - mSwiping = deltaX > mSlop * 2 && Math.abs(deltaY) < mSlop * 2; + mSwiping = deltaX > mSlop * 2 && Math.abs(deltaY) < Math.abs(deltaX); } else { mSwiping = false; } @@ -299,9 +301,9 @@ public class SwipeDismissLayout extends FrameLayout { private void updateDismiss(MotionEvent ev) { float deltaX = ev.getRawX() - mDownX; + mVelocityTracker.addMovement(ev); + mVelocityTracker.computeCurrentVelocity(1000); if (!mDismissed) { - mVelocityTracker.addMovement(ev); - mVelocityTracker.computeCurrentVelocity(1000); if (deltaX > (getWidth() * DISMISS_MIN_DRAG_WIDTH_RATIO) && ev.getRawX() >= mLastX) { @@ -311,7 +313,9 @@ public class SwipeDismissLayout extends FrameLayout { // Check if the user tried to undo this. if (mDismissed && mSwiping) { // Check if the user's finger is actually back - if (deltaX < (getWidth() * DISMISS_MIN_DRAG_WIDTH_RATIO)) { + if (deltaX < (getWidth() * DISMISS_MIN_DRAG_WIDTH_RATIO) || + // or user is flinging back left + mVelocityTracker.getXVelocity() < -mMinFlingVelocity) { mDismissed = false; } } diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 0d83e93..0bfc0c9 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -536,7 +536,6 @@ bool AndroidRuntime::parseCompilerRuntimeOption(const char* property, */ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv) { - int result = -1; JavaVMInitArgs initArgs; char propBuf[PROPERTY_VALUE_MAX]; char stackTraceFileBuf[sizeof("-Xstacktracefile:")-1 + PROPERTY_VALUE_MAX]; @@ -587,6 +586,7 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv) char localeOption[sizeof("-Duser.locale=") + PROPERTY_VALUE_MAX]; char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:")-1 + PROPERTY_VALUE_MAX]; char nativeBridgeLibrary[sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX]; + char cpuAbiListBuf[sizeof("--cpu-abilist=") + PROPERTY_VALUE_MAX]; bool checkJni = false; property_get("dalvik.vm.checkjni", propBuf, ""); @@ -705,7 +705,7 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv) if (!hasFile("/system/etc/preloaded-classes")) { ALOGE("Missing preloaded-classes file, /system/etc/preloaded-classes not found: %s\n", strerror(errno)); - goto bail; + return -1; } addOption("-Ximage-compiler-option"); addOption("--image-classes=/system/etc/preloaded-classes"); @@ -860,6 +860,18 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv) // Dalvik-cache pruning counter. parseRuntimeOption("dalvik.vm.zygote.max-boot-retry", cachePruneBuf, "-Xzygote-max-boot-retry="); +#if defined(__LP64__) + const char* cpu_abilist_property_name = "ro.product.cpu.abilist64"; +#else + const char* cpu_abilist_property_name = "ro.product.cpu.abilist32"; +#endif // defined(__LP64__) + property_get(cpu_abilist_property_name, propBuf, ""); + if (propBuf[0] == '\0') { + ALOGE("%s is not expected to be empty", cpu_abilist_property_name); + return -1; + } + snprintf(cpuAbiListBuf, sizeof(cpuAbiListBuf), "--cpu-abilist=%s", propBuf); + addOption(cpuAbiListBuf); initArgs.version = JNI_VERSION_1_4; initArgs.options = mOptions.editArray(); @@ -875,13 +887,10 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv) */ if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) { ALOGE("JNI_CreateJavaVM failed\n"); - goto bail; + return -1; } - result = 0; - -bail: - return result; + return 0; } char* AndroidRuntime::toSlashClassName(const char* className) diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp index ceec0e3..610bdc8 100755 --- a/core/jni/android/graphics/Bitmap.cpp +++ b/core/jni/android/graphics/Bitmap.cpp @@ -574,24 +574,33 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { return NULL; } - SkBitmap* bitmap = new SkBitmap; + SkAutoTDelete<SkBitmap> bitmap(new SkBitmap); - bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType), rowBytes); + if (!bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType), rowBytes)) { + return NULL; + } SkColorTable* ctable = NULL; if (colorType == kIndex_8_SkColorType) { int count = p->readInt32(); + if (count < 0 || count > 256) { + // The data is corrupt, since SkColorTable enforces a value between 0 and 256, + // inclusive. + return NULL; + } if (count > 0) { size_t size = count * sizeof(SkPMColor); const SkPMColor* src = (const SkPMColor*)p->readInplace(size); + if (src == NULL) { + return NULL; + } ctable = new SkColorTable(src, count); } } - jbyteArray buffer = GraphicsJNI::allocateJavaPixelRef(env, bitmap, ctable); + jbyteArray buffer = GraphicsJNI::allocateJavaPixelRef(env, bitmap.get(), ctable); if (NULL == buffer) { SkSafeUnref(ctable); - delete bitmap; return NULL; } @@ -603,7 +612,6 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { android::status_t status = p->readBlob(size, &blob); if (status) { doThrowRE(env, "Could not read bitmap from parcel blob."); - delete bitmap; return NULL; } @@ -613,8 +621,8 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { blob.release(); - return GraphicsJNI::createBitmap(env, bitmap, buffer, getPremulBitmapCreateFlags(isMutable), - NULL, NULL, density); + return GraphicsJNI::createBitmap(env, bitmap.detach(), buffer, + getPremulBitmapCreateFlags(isMutable), NULL, NULL, density); } static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp index 3c1993e..9307ff9 100644 --- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp +++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp @@ -33,6 +33,7 @@ #include <string.h> #include <time.h> #include <unistd.h> +#include <inttypes.h> #include <sys/stat.h> #include <sys/types.h> @@ -173,7 +174,11 @@ sumFiles(JNIEnv*, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntry, const char static install_status_t copyFileIfChanged(JNIEnv *env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntry, const char* fileName) { - jstring* javaNativeLibPath = (jstring*) arg; + void** args = reinterpret_cast<void**>(arg); + jstring* javaNativeLibPath = (jstring*) args[0]; + jboolean extractNativeLibs = *(jboolean*) args[1]; + jboolean hasNativeBridge = *(jboolean*) args[2]; + ScopedUtfChars nativeLibPath(env, *javaNativeLibPath); size_t uncompLen; @@ -181,13 +186,31 @@ copyFileIfChanged(JNIEnv *env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntr long crc; time_t modTime; - if (!zipFile->getEntryInfo(zipEntry, NULL, &uncompLen, NULL, NULL, &when, &crc)) { + int method; + off64_t offset; + + if (!zipFile->getEntryInfo(zipEntry, &method, &uncompLen, NULL, &offset, &when, &crc)) { ALOGD("Couldn't read zip entry info\n"); return INSTALL_FAILED_INVALID_APK; - } else { - struct tm t; - ZipUtils::zipTimeToTimespec(when, &t); - modTime = mktime(&t); + } + + if (!extractNativeLibs) { + // check if library is uncompressed and page-aligned + if (method != ZipFileRO::kCompressStored) { + ALOGD("Library '%s' is compressed - will not be able to open it directly from apk.\n", + fileName); + return INSTALL_FAILED_INVALID_APK; + } + + if (offset % PAGE_SIZE != 0) { + ALOGD("Library '%s' is not page-aligned - will not be able to open it directly from" + " apk.\n", fileName); + return INSTALL_FAILED_INVALID_APK; + } + + if (!hasNativeBridge) { + return INSTALL_SUCCEEDED; + } } // Build local file path @@ -208,6 +231,9 @@ copyFileIfChanged(JNIEnv *env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntr } // Only copy out the native file if it's different. + struct tm t; + ZipUtils::zipTimeToTimespec(when, &t); + modTime = mktime(&t); struct stat64 st; if (!isFileDifferent(localFileName, uncompLen, modTime, crc, &st)) { return INSTALL_SUCCEEDED; @@ -465,10 +491,12 @@ static int findSupportedAbi(JNIEnv *env, jlong apkHandle, jobjectArray supported static jint com_android_internal_content_NativeLibraryHelper_copyNativeBinaries(JNIEnv *env, jclass clazz, - jlong apkHandle, jstring javaNativeLibPath, jstring javaCpuAbi) + jlong apkHandle, jstring javaNativeLibPath, jstring javaCpuAbi, + jboolean extractNativeLibs, jboolean hasNativeBridge) { + void* args[] = { &javaNativeLibPath, &extractNativeLibs, &hasNativeBridge }; return (jint) iterateOverNativeFiles(env, apkHandle, javaCpuAbi, - copyFileIfChanged, &javaNativeLibPath); + copyFileIfChanged, reinterpret_cast<void*>(args)); } static jlong @@ -548,7 +576,7 @@ static JNINativeMethod gMethods[] = { "(J)V", (void *)com_android_internal_content_NativeLibraryHelper_close}, {"nativeCopyNativeBinaries", - "(JLjava/lang/String;Ljava/lang/String;)I", + "(JLjava/lang/String;Ljava/lang/String;ZZ)I", (void *)com_android_internal_content_NativeLibraryHelper_copyNativeBinaries}, {"nativeSumNativeBinaries", "(JLjava/lang/String;)J", diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index ea592cf..f69772a 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1021,6 +1021,10 @@ <p>The default value of this attribute is <code>false</code>. --> <attr name="resumeWhilePausing" format="boolean" /> + <!-- When set installer will extract native libraries. If set to false + libraries in the apk must be stored and page-aligned. --> + <attr name="extractNativeLibs" format="boolean"/> + <!-- The <code>manifest</code> tag is the root of an <code>AndroidManifest.xml</code> file, describing the contents of an Android package (.apk) file. One @@ -1151,8 +1155,8 @@ @hide --> <attr name="usesCleartextTraffic" /> <attr name="multiArch" /> + <attr name="extractNativeLibs" /> </declare-styleable> - <!-- The <code>permission</code> tag declares a security permission that can be used to control access from other packages to specific components or features in your package (or other packages). See the diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 9a33ef9..37247b0 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -437,6 +437,9 @@ point on the move. A value of 0 means no periodic scans will be used in the framework. --> <integer translatable="false" name="config_wifi_framework_scan_interval">300000</integer> + <!-- Integer indicating disconnect mode scan interval in milliseconds --> + <integer translatable="false" name="config_wifi_disconnected_scan_interval">10000</integer> + <!-- Integer indicating associated partial scan interval in milliseconds --> <integer translatable="false" name="config_wifi_framework_associated_scan_interval">20000</integer> @@ -2096,4 +2099,10 @@ <!-- Keyguard component --> <string name="config_keyguardComponent" translatable="false">com.android.systemui/com.android.systemui.keyguard.KeyguardService</string> + + <!-- This config is used to force VoiceInteractionService to start on certain low ram devices. --> + <bool name="config_forceEnableVoiceInteractionService">false</bool> + + <!-- This config is ued to determine whether animations are allowed in low power mode. --> + <bool name="config_allowAnimationsInLowPowerMode">false</bool> </resources> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 2bb9aa8..bfd0d26 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2598,4 +2598,5 @@ <public type="style" name="Theme.DeviceDefault.Dialog.Alert" /> <public type="style" name="Theme.DeviceDefault.Light.Dialog.Alert" /> + <public type="attr" name="extractNativeLibs" /> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index da0a5c1..afa67b7 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -281,6 +281,8 @@ <java-symbol type="bool" name="config_enableScreenshotChord" /> <java-symbol type="bool" name="config_bluetooth_default_profiles" /> <java-symbol type="bool" name="config_enableWifiDisplay" /> + <java-symbol type="bool" name="config_forceEnableVoiceInteractionService" /> + <java-symbol type="bool" name="config_allowAnimationsInLowPowerMode" /> <java-symbol type="bool" name="config_useDevInputEventForAudioJack" /> <java-symbol type="bool" name="config_safe_media_volume_enabled" /> <java-symbol type="bool" name="config_camera_sound_forced" /> @@ -371,6 +373,7 @@ <java-symbol type="integer" name="config_shortPressOnSleepBehavior" /> <java-symbol type="integer" name="config_wifi_framework_scan_interval" /> <java-symbol type="integer" name="config_wifi_supplicant_scan_interval" /> + <java-symbol type="integer" name="config_wifi_disconnected_scan_interval" /> <java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" /> <java-symbol type="integer" name="db_connection_pool_size" /> <java-symbol type="integer" name="db_journal_size_limit" /> diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java index e04c214..4b82c3d 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java @@ -184,10 +184,10 @@ public class WifiStressTest extends ConnectivityManagerTestBase { result.putInt("ap-discovered", ssidAppearInScanResultsCount); getInstrumentation().sendStatus(Activity.RESULT_FIRST_USER, result); if (i == mScanIterations + 1) { - writeOutput(String.format("iteration %d out of %d", i, mScanIterations)); + writeOutput(String.format("iteration %d out of %d", i - 1, mScanIterations)); writeOutput(String.format("average scanning time is %d", scanTimeSum / (i - 1))); writeOutput(String.format("ssid appear %d out of %d scan iterations", - ssidAppearInScanResultsCount, i)); + ssidAppearInScanResultsCount, i - 1)); } } @@ -289,7 +289,7 @@ public class WifiStressTest extends ConnectivityManagerTestBase { getInstrumentation().sendStatus(Activity.RESULT_FIRST_USER, result); if (i == mReconnectIterations + 1) { writeOutput(String.format("iteration %d out of %d", - i, mReconnectIterations)); + i - 1, mReconnectIterations)); } } } diff --git a/core/tests/coretests/apks/install_jni_lib/Android.mk b/core/tests/coretests/apks/install_jni_lib/Android.mk index b61ea8e..7322e8d 100644 --- a/core/tests/coretests/apks/install_jni_lib/Android.mk +++ b/core/tests/coretests/apks/install_jni_lib/Android.mk @@ -23,6 +23,14 @@ LOCAL_SHARED_LIBRARIES := \ libnativehelper LOCAL_MODULE := libframeworks_coretests_jni + +# this does not prevent build system +# from installing library to /system/lib LOCAL_MODULE_TAGS := tests +# .. we want to avoid that... so we put it somewhere +# bionic linker cant find it without outside help (nativetests): +LOCAL_MODULE_PATH_32 := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE) +LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE) + include $(BUILD_SHARED_LIBRARY) diff --git a/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp b/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp index 957fc4a..e0b616c 100644 --- a/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp +++ b/core/tests/coretests/apks/install_jni_lib/com_android_frameworks_coretests_JNITest.cpp @@ -27,8 +27,8 @@ static JNINativeMethod sMethods[] = { { "checkFunction", "()I", (void*) checkFunction }, }; -int register_com_android_framework_coretests_JNITests(JNIEnv* env) { - return jniRegisterNativeMethods(env, "com/android/framework/coretests/JNITests", sMethods, +int register_com_android_frameworks_coretests_JNITests(JNIEnv* env) { + return jniRegisterNativeMethods(env, "com/android/frameworks/coretests/JNITests", sMethods, NELEM(sMethods)); } @@ -46,7 +46,7 @@ jint JNI_OnLoad(JavaVM *jvm, void *reserved) { return JNI_ERR; } - if ((status = android::register_com_android_framework_coretests_JNITests(e)) < 0) { + if ((status = android::register_com_android_frameworks_coretests_JNITests(e)) < 0) { return JNI_ERR; } diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk b/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk new file mode 100644 index 0000000..6ee6ffa --- /dev/null +++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/Android.mk @@ -0,0 +1,10 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := install_jni_lib_open_from_apk + +LOCAL_PAGE_ALIGN_JNI_SHARED_LIBRARIES := true + +include $(FrameworkCoreTests_BUILD_PACKAGE) diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/AndroidManifest.xml b/core/tests/coretests/apks/install_jni_lib_open_from_apk/AndroidManifest.xml new file mode 100644 index 0000000..190f894 --- /dev/null +++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/AndroidManifest.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.frameworks.coretests.install_jni_lib_open_from_apk"> + + <application android:hasCode="true" android:label="@string/app_name" android:extractNativeLibs="false"> + <activity android:name="com.android.frameworks.coretests.OpenFromApkActivity" + android:label="@string/app_name"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/res/values/strings.xml b/core/tests/coretests/apks/install_jni_lib_open_from_apk/res/values/strings.xml new file mode 100644 index 0000000..8c2a0bf --- /dev/null +++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/res/values/strings.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_name">Load From Apk Test</string> +</resources> diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/JNITests.java b/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/JNITests.java new file mode 100644 index 0000000..4f9176c --- /dev/null +++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/JNITests.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.android.frameworks.coretests; + +public class JNITests { + static { + System.loadLibrary("frameworks_coretests_jni"); + } + + public static native int checkFunction(); +} diff --git a/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/OpenFromApkActivity.java b/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/OpenFromApkActivity.java new file mode 100644 index 0000000..524cad7 --- /dev/null +++ b/core/tests/coretests/apks/install_jni_lib_open_from_apk/src/com/android/frameworks/coretests/OpenFromApkActivity.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.android.frameworks.coretests; + +import android.app.Activity; +import android.widget.TextView; +import android.os.Bundle; + +public class OpenFromApkActivity extends Activity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + TextView tv = new TextView(this); + + int i = JNITests.checkFunction(); + + tv.setText("All is well: i=" + i); + + setContentView(tv); + } + +} diff --git a/core/tests/coretests/src/android/net/IpPrefixTest.java b/core/tests/coretests/src/android/net/IpPrefixTest.java index cf278fb..fcc6389 100644 --- a/core/tests/coretests/src/android/net/IpPrefixTest.java +++ b/core/tests/coretests/src/android/net/IpPrefixTest.java @@ -29,6 +29,10 @@ import junit.framework.TestCase; public class IpPrefixTest extends TestCase { + private static InetAddress Address(String addr) { + return InetAddress.parseNumericAddress(addr); + } + // Explicitly cast everything to byte because "error: possible loss of precision". private static final byte[] IPV4_BYTES = { (byte) 192, (byte) 0, (byte) 2, (byte) 4}; private static final byte[] IPV6_BYTES = { @@ -209,6 +213,34 @@ public class IpPrefixTest extends TestCase { } @SmallTest + public void testContains() { + IpPrefix p = new IpPrefix("2001:db8:f00::ace:d00d/127"); + assertTrue(p.contains(Address("2001:db8:f00::ace:d00c"))); + assertTrue(p.contains(Address("2001:db8:f00::ace:d00d"))); + assertFalse(p.contains(Address("2001:db8:f00::ace:d00e"))); + assertFalse(p.contains(Address("2001:db8:f00::bad:d00d"))); + assertFalse(p.contains(Address("2001:4868:4860::8888"))); + assertFalse(p.contains(null)); + assertFalse(p.contains(Address("8.8.8.8"))); + + p = new IpPrefix("192.0.2.0/23"); + assertTrue(p.contains(Address("192.0.2.43"))); + assertTrue(p.contains(Address("192.0.3.21"))); + assertFalse(p.contains(Address("192.0.0.21"))); + assertFalse(p.contains(Address("8.8.8.8"))); + assertFalse(p.contains(Address("2001:4868:4860::8888"))); + + IpPrefix ipv6Default = new IpPrefix("::/0"); + assertTrue(ipv6Default.contains(Address("2001:db8::f00"))); + assertFalse(ipv6Default.contains(Address("192.0.2.1"))); + + IpPrefix ipv4Default = new IpPrefix("0.0.0.0/0"); + assertTrue(ipv4Default.contains(Address("255.255.255.255"))); + assertTrue(ipv4Default.contains(Address("192.0.2.1"))); + assertFalse(ipv4Default.contains(Address("2001:db8::f00"))); + } + + @SmallTest public void testHashCode() { IpPrefix p; int oldCode = -1; diff --git a/core/tests/coretests/src/android/net/RouteInfoTest.java b/core/tests/coretests/src/android/net/RouteInfoTest.java index 0b88bc7..831fefd 100644 --- a/core/tests/coretests/src/android/net/RouteInfoTest.java +++ b/core/tests/coretests/src/android/net/RouteInfoTest.java @@ -90,6 +90,7 @@ public class RouteInfoTest extends TestCase { assertFalse(r.matches(Address("2001:db8:f00::ace:d00e"))); assertFalse(r.matches(Address("2001:db8:f00::bad:d00d"))); assertFalse(r.matches(Address("2001:4868:4860::8888"))); + assertFalse(r.matches(Address("8.8.8.8"))); r = new PatchedRouteInfo(Prefix("192.0.2.0/23"), null, "wlan0"); assertTrue(r.matches(Address("192.0.2.43"))); diff --git a/docs/html/reference/com/google/android/gms/fitness/data/Field.html b/docs/html/reference/com/google/android/gms/fitness/data/Field.html index 91bf861..0f97e7e 100644 --- a/docs/html/reference/com/google/android/gms/fitness/data/Field.html +++ b/docs/html/reference/com/google/android/gms/fitness/data/Field.html @@ -151,7 +151,7 @@ href="//fonts.googleapis.com/css?family=Roboto+Condensed"> <a name="top"></a> -<!-- dialog to prompt lang pref change when loaded from hardcoded URL +<!-- dialog to prompt lang pref change when loaded from hardcoded URL <div id="langMessage" style="display:none"> <div> <div class="lang en"> @@ -201,7 +201,7 @@ href="//fonts.googleapis.com/css?family=Roboto+Condensed"> <div id="header-wrapper"> <div id="header"> - + <div class="wrap" id="header-wrap"> @@ -245,8 +245,8 @@ href="//fonts.googleapis.com/css?family=Roboto+Condensed"> </ul> - - + + <div class="menu-container"> <div class="moremenu"> <div id="more-btn"></div> @@ -267,8 +267,8 @@ href="//fonts.googleapis.com/css?family=Roboto+Condensed"> <li><a href="http://source.android.com">Android Open Source Project</a></li> </ul> - - + + <div class="header">Language</div> <div id="language" class="locales"> <select name="language" onChange="changeLangPref(this.value, true)"> @@ -286,8 +286,8 @@ href="//fonts.googleapis.com/css?family=Roboto+Condensed"> loadLangPref(); //--> </script> - - + + <br class="clearfix" /> </div><!-- end 'mid' --> <div class="bottom"></div> @@ -401,10 +401,10 @@ href="//fonts.googleapis.com/css?family=Roboto+Condensed"> </li> <li><a href="/google/index.html">Google Services</a> </li> - + <li><a href="/samples/index.html">Samples</a> </li> - + </ul> </li> <li class="distribute last"> @@ -424,14 +424,14 @@ href="//fonts.googleapis.com/css?family=Roboto+Condensed"> </div><!-- end header-wrap.wrap --> </div><!-- end header --> - + <!-- Secondary x-nav --> <div id="nav-x"> <div class="wrap" style="position:relative;z-index:1"> - - - + + + <ul class="nav-x col-9 develop" style="width:100%"> <li class="training"><a href="/training/index.html" @@ -469,17 +469,17 @@ href="//fonts.googleapis.com/css?family=Roboto+Condensed"> <li class="google"><a href="/google/index.html" >Google Services</a> </li> - + <li class="samples"><a href="/samples/index.html" >Samples</a> </li> - + </ul> </div> </div> <!-- /Sendondary x-nav DEVELOP --> - + <div id="searchResults" class="wrap" style="display:none;"> <h2 id="searchTitle">Results</h2> @@ -492,7 +492,7 @@ href="//fonts.googleapis.com/css?family=Roboto+Condensed"> <a class="logo" href="#top"></a> <a class="top" href="#top"></a> <ul class="breadcrumb"> - + <li class="current">Field</li> </ul> </div> @@ -502,7 +502,7 @@ href="//fonts.googleapis.com/css?family=Roboto+Condensed"> - + <div class="wrap clearfix" id="body-content"> <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement"> <div id="devdoc-nav" class="scroll-pane"> @@ -759,12 +759,12 @@ href="//fonts.googleapis.com/css?family=Roboto+Condensed"> </script> - + </div> <script type="text/javascript"> showGoogleRefTree(); - + </script> </div> <!-- end side-nav --> <script> @@ -774,7 +774,7 @@ href="//fonts.googleapis.com/css?family=Roboto+Condensed"> </script> - + @@ -784,21 +784,21 @@ href="//fonts.googleapis.com/css?family=Roboto+Condensed"> - - - - - - - - - - - - - - + + + + + + + + + + + + + + <div class="sum-details-links"> @@ -810,22 +810,22 @@ Summary: <a href="#constants">Constants</a> - + | <a href="#inhconstants">Inherited Constants</a> - + | <a href="#lfields">Fields</a> - + | <a href="#pubmethods">Methods</a> - + @@ -835,9 +835,9 @@ Summary: </div><!-- end sum-details-links --> <div class="api-level"> - - - + + + </div> </div><!-- end api-info-block --> @@ -847,31 +847,31 @@ Summary: <div id="jd-header"> public - - final - + + final + class <h1 itemprop="name">Field</h1> - + extends Object<br/> - - - - - - implements - - Parcelable - - - - + + + + implements + + Parcelable + + + + + + </div><!-- end header --> @@ -883,18 +883,18 @@ Summary: <tr> - + <td colspan="2" class="jd-inheritance-class-cell">java.lang.Object</td> </tr> - + <tr> - + <td class="jd-inheritance-space"> ↳</td> - + <td colspan="1" class="jd-inheritance-class-cell">com.google.android.gms.fitness.data.Field</td> </tr> - + </table> @@ -962,31 +962,31 @@ Summary: <table id="constants" class="jd-sumtable"><tr><th colspan="12">Constants</th></tr> - + <tr class="alt-color api apilevel-" > <td class="jd-typecol">int</td> <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FORMAT_FLOAT">FORMAT_FLOAT</a></td> <td class="jd-descrcol" width="100%"> Format constant indicating the field holds float values. - - + + </td> </tr> - - + + <tr class=" api apilevel-" > <td class="jd-typecol">int</td> <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FORMAT_INT32">FORMAT_INT32</a></td> <td class="jd-descrcol" width="100%"> Format constant indicating the field holds integer values. - - + + </td> </tr> - - + + <tr class="alt-color api apilevel-" > <td class="jd-typecol">int</td> <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FORMAT_MAP">FORMAT_MAP</a></td> @@ -1305,33 +1305,33 @@ android.os.Parcelable </div> <div id="inherited-constants-android.os.Parcelable-summary" style="display: none;"> <table class="jd-sumtable-expando"> - - + + <tr class="alt-color api apilevel-" > <td class="jd-typecol">int</td> <td class="jd-linkcol">CONTENTS_FILE_DESCRIPTOR</td> <td class="jd-descrcol" width="100%"> - - - + + + </td> </tr> - - + + <tr class=" api apilevel-" > <td class="jd-typecol">int</td> <td class="jd-linkcol">PARCELABLE_WRITE_RETURN_VALUE</td> <td class="jd-descrcol" width="100%"> - - - + + + </td> </tr> - - + + </table> </div> </div> @@ -1347,7 +1347,7 @@ android.os.Parcelable <table id="lfields" class="jd-sumtable"><tr><th colspan="12">Fields</th></tr> - + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1357,13 +1357,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_ACCURACY">FIELD_ACCURACY</a></td> <td class="jd-descrcol" width="100%"> The accuracy of an accompanied value (such as location). - - + + </td> </tr> - - + + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1373,13 +1373,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_ACTIVITY">FIELD_ACTIVITY</a></td> <td class="jd-descrcol" width="100%"> An activity type of <code><a href="/reference/com/google/android/gms/fitness/FitnessActivities.html">FitnessActivities</a></code>, encoded as an integer for efficiency. - - + + </td> </tr> - - + + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1389,13 +1389,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_ALTITUDE">FIELD_ALTITUDE</a></td> <td class="jd-descrcol" width="100%"> An altitude of a location represented as a float, in meters above sea level. - - + + </td> </tr> - - + + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1405,13 +1405,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_AVERAGE">FIELD_AVERAGE</a></td> <td class="jd-descrcol" width="100%"> An average value. - - + + </td> </tr> - - + + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1421,13 +1421,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_BPM">FIELD_BPM</a></td> <td class="jd-descrcol" width="100%"> A heart rate in beats per minute. - - + + </td> </tr> - - + + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1437,13 +1437,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_CALORIES">FIELD_CALORIES</a></td> <td class="jd-descrcol" width="100%"> Calories in kcal. - - + + </td> </tr> - - + + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1469,13 +1469,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_CONFIDENCE">FIELD_CONFIDENCE</a></td> <td class="jd-descrcol" width="100%"> The confidence of an accompanied value, specified as a value between 0.0 and 100.0. - - + + </td> </tr> - - + + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1485,13 +1485,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_DISTANCE">FIELD_DISTANCE</a></td> <td class="jd-descrcol" width="100%"> A distance in meters. - - + + </td> </tr> - - + + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1501,13 +1501,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_DURATION">FIELD_DURATION</a></td> <td class="jd-descrcol" width="100%"> A duration in milliseconds. - - + + </td> </tr> - - + + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1533,13 +1533,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_HEIGHT">FIELD_HEIGHT</a></td> <td class="jd-descrcol" width="100%"> A height in meters. - - + + </td> </tr> - - + + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1549,13 +1549,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_HIGH_LATITUDE">FIELD_HIGH_LATITUDE</a></td> <td class="jd-descrcol" width="100%"> A high latitude of a location bounding box represented as a float, in degrees. - - + + </td> </tr> - - + + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1565,13 +1565,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_HIGH_LONGITUDE">FIELD_HIGH_LONGITUDE</a></td> <td class="jd-descrcol" width="100%"> A high longitude of a location bounding box represented as a float, in degrees. - - + + </td> </tr> - - + + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1581,13 +1581,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_LATITUDE">FIELD_LATITUDE</a></td> <td class="jd-descrcol" width="100%"> A latitude of a location represented as a float, in degrees. - - + + </td> </tr> - - + + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1597,13 +1597,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_LONGITUDE">FIELD_LONGITUDE</a></td> <td class="jd-descrcol" width="100%"> A longitude of a location represented as a float, in degrees. - - + + </td> </tr> - - + + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1613,13 +1613,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_LOW_LATITUDE">FIELD_LOW_LATITUDE</a></td> <td class="jd-descrcol" width="100%"> A low latitude of a location bounding box represented as a float, in degrees. - - + + </td> </tr> - - + + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1629,13 +1629,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_LOW_LONGITUDE">FIELD_LOW_LONGITUDE</a></td> <td class="jd-descrcol" width="100%"> A low longitude of a location bounding box represented as a float, in degrees. - - + + </td> </tr> - - + + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1645,13 +1645,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_MAX">FIELD_MAX</a></td> <td class="jd-descrcol" width="100%"> A maximum value. - - + + </td> </tr> - - + + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1677,13 +1677,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_MIN">FIELD_MIN</a></td> <td class="jd-descrcol" width="100%"> A minimum value. - - + + </td> </tr> - - + + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1725,13 +1725,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_PERCENTAGE">FIELD_PERCENTAGE</a></td> <td class="jd-descrcol" width="100%"> A percentage value, between 0 and 100. - - + + </td> </tr> - - + + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1741,13 +1741,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_REVOLUTIONS">FIELD_REVOLUTIONS</a></td> <td class="jd-descrcol" width="100%"> A count of revolutions. - - + + </td> </tr> - - + + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1757,13 +1757,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_RPM">FIELD_RPM</a></td> <td class="jd-descrcol" width="100%"> Revolutions per minute or rate per minute. - - + + </td> </tr> - - + + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1773,13 +1773,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_SPEED">FIELD_SPEED</a></td> <td class="jd-descrcol" width="100%"> A speed in meter/sec. - - + + </td> </tr> - - + + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1789,13 +1789,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_STEPS">FIELD_STEPS</a></td> <td class="jd-descrcol" width="100%"> A count of steps. - - + + </td> </tr> - - + + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1805,13 +1805,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_WATTS">FIELD_WATTS</a></td> <td class="jd-descrcol" width="100%"> Power in watts. - - + + </td> </tr> - - + + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> public @@ -1821,13 +1821,13 @@ android.os.Parcelable <td class="jd-linkcol"><a href="/reference/com/google/android/gms/fitness/data/Field.html#FIELD_WEIGHT">FIELD_WEIGHT</a></td> <td class="jd-descrcol" width="100%"> A weight in kilograms. - - + + </td> </tr> - - + + </table> @@ -1846,129 +1846,129 @@ android.os.Parcelable - + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> - - - - - + + + + + int</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#describeContents()">describeContents</a></span>()</nobr> - + </td></tr> - + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> - - - - - + + + + + boolean</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#equals(java.lang.Object)">equals</a></span>(Object that)</nobr> - + </td></tr> - + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> - - - - - + + + + + int</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#getFormat()">getFormat</a></span>()</nobr> - + <div class="jd-descrdiv"> Returns the format of the field, as one of the format constant values. - - + + </div> - + </td></tr> - + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> - - - - - + + + + + String</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#getName()">getName</a></span>()</nobr> - + <div class="jd-descrdiv"> Returns the name of the field. - - + + </div> - + </td></tr> - + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> - - - - - + + + + + int</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#hashCode()">hashCode</a></span>()</nobr> - + </td></tr> - + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> - - - - - + + + + + String</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#toString()">toString</a></span>()</nobr> - + </td></tr> - + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> - - - - - + + + + + void</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad"><a href="/reference/com/google/android/gms/fitness/data/Field.html#writeToParcel(android.os.Parcel, int)">writeToParcel</a></span>(Parcel dest, int flags)</nobr> - + </td></tr> @@ -2003,182 +2003,182 @@ From class </div> <div id="inherited-methods-java.lang.Object-summary" style="display: none;"> <table class="jd-sumtable-expando"> - - + + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> - - - - - + + + + + Object</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad">clone</span>()</nobr> - + </td></tr> - + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> - - - - - + + + + + boolean</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad">equals</span>(Object arg0)</nobr> - + </td></tr> - + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> - - - - - + + + + + void</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad">finalize</span>()</nobr> - + </td></tr> - + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> - - + + final - - + + Class<?></nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad">getClass</span>()</nobr> - + </td></tr> - + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> - - - - - + + + + + int</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad">hashCode</span>()</nobr> - + </td></tr> - + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> - - + + final - - + + void</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad">notify</span>()</nobr> - + </td></tr> - + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> - - + + final - - + + void</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad">notifyAll</span>()</nobr> - + </td></tr> - + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> - - - - - + + + + + String</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad">toString</span>()</nobr> - + </td></tr> - + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> - - + + final - - + + void</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad">wait</span>()</nobr> - + </td></tr> - + <tr class=" api apilevel-" > <td class="jd-typecol"><nobr> - - + + final - - + + void</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad">wait</span>(long arg0, int arg1)</nobr> - + </td></tr> - + <tr class="alt-color api apilevel-" > <td class="jd-typecol"><nobr> - - + + final - - + + void</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> <span class="sympad">wait</span>(long arg0)</nobr> - + </td></tr> @@ -2205,7 +2205,7 @@ From interface </div> <div id="inherited-methods-android.os.Parcelable-summary" style="display: none;"> <table class="jd-sumtable-expando"> - + @@ -2232,6 +2232,7 @@ From interface + void</nobr> </td> <td class="jd-linkcol" width="100%"><nobr> @@ -3196,40 +3197,40 @@ From interface <A NAME="NUTRIENT_TOTAL_FAT"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final String </span> NUTRIENT_TOTAL_FAT </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>Total fat in grams. </p></div> - + <div class="jd-tagdata"> <span class="jd-tagtitle">Constant Value: </span> <span> - + "fat.total" - + </span> </div> - + </div> </div> @@ -3237,40 +3238,40 @@ From interface <A NAME="NUTRIENT_TRANS_FAT"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final String </span> NUTRIENT_TRANS_FAT </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>Trans fat in grams. </p></div> - + <div class="jd-tagdata"> <span class="jd-tagtitle">Constant Value: </span> <span> - + "fat.trans" - + </span> </div> - + </div> </div> @@ -3321,31 +3322,31 @@ From interface <A NAME="NUTRIENT_VITAMIN_C"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final String </span> NUTRIENT_VITAMIN_C </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>Vitamin C amount in milligrams. </p></div> - + <div class="jd-tagdata"> <span class="jd-tagtitle">Constant Value: </span> <span> @@ -3372,31 +3373,31 @@ From interface <A NAME="FIELD_ACCURACY"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_ACCURACY </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>The accuracy of an accompanied value (such as location). </p></div> - + </div> </div> @@ -3404,33 +3405,33 @@ From interface <A NAME="FIELD_ACTIVITY"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_ACTIVITY </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>An activity type of <code><a href="/reference/com/google/android/gms/fitness/FitnessActivities.html">FitnessActivities</a></code>, encoded as an integer for efficiency. The activity value should be stored using <code><a href="/reference/com/google/android/gms/fitness/data/Value.html#setActivity(java.lang.String)">setActivity(String)</a></code>, and read using <code><a href="/reference/com/google/android/gms/fitness/data/Value.html#asActivity()">asActivity()</a></code> </p></div> - + </div> </div> @@ -3438,32 +3439,32 @@ From interface <A NAME="FIELD_ALTITUDE"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_ALTITUDE </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>An altitude of a location represented as a float, in meters above sea level. Some location samples don't have an altitude value so this field might not be set. </p></div> - + </div> </div> @@ -3471,31 +3472,31 @@ From interface <A NAME="FIELD_AVERAGE"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_AVERAGE </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>An average value. </p></div> - + </div> </div> @@ -3503,31 +3504,31 @@ From interface <A NAME="FIELD_BPM"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_BPM </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A heart rate in beats per minute. </p></div> - + </div> </div> @@ -3535,31 +3536,31 @@ From interface <A NAME="FIELD_CALORIES"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_CALORIES </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>Calories in kcal. </p></div> - + </div> </div> @@ -3599,31 +3600,31 @@ From interface <A NAME="FIELD_CONFIDENCE"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_CONFIDENCE </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>The confidence of an accompanied value, specified as a value between 0.0 and 100.0. </p></div> - + </div> </div> @@ -3631,31 +3632,31 @@ From interface <A NAME="FIELD_DISTANCE"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_DISTANCE </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A distance in meters. </p></div> - + </div> </div> @@ -3663,31 +3664,31 @@ From interface <A NAME="FIELD_DURATION"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_DURATION </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A duration in milliseconds. </p></div> - + </div> </div> @@ -3727,31 +3728,31 @@ From interface <A NAME="FIELD_HEIGHT"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_HEIGHT </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A height in meters. </p></div> - + </div> </div> @@ -3759,31 +3760,31 @@ From interface <A NAME="FIELD_HIGH_LATITUDE"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_HIGH_LATITUDE </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A high latitude of a location bounding box represented as a float, in degrees. </p></div> - + </div> </div> @@ -3791,31 +3792,31 @@ From interface <A NAME="FIELD_HIGH_LONGITUDE"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_HIGH_LONGITUDE </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A high longitude of a location bounding box represented as a float, in degrees. </p></div> - + </div> </div> @@ -3823,31 +3824,31 @@ From interface <A NAME="FIELD_LATITUDE"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_LATITUDE </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A latitude of a location represented as a float, in degrees. </p></div> - + </div> </div> @@ -3855,31 +3856,31 @@ From interface <A NAME="FIELD_LONGITUDE"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_LONGITUDE </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A longitude of a location represented as a float, in degrees. </p></div> - + </div> </div> @@ -3887,31 +3888,31 @@ From interface <A NAME="FIELD_LOW_LATITUDE"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_LOW_LATITUDE </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A low latitude of a location bounding box represented as a float, in degrees. </p></div> - + </div> </div> @@ -3919,31 +3920,31 @@ From interface <A NAME="FIELD_LOW_LONGITUDE"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_LOW_LONGITUDE </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A low longitude of a location bounding box represented as a float, in degrees. </p></div> - + </div> </div> @@ -3951,31 +3952,31 @@ From interface <A NAME="FIELD_MAX"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_MAX </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A maximum value. </p></div> - + </div> </div> @@ -4015,31 +4016,31 @@ From interface <A NAME="FIELD_MIN"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_MIN </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A minimum value. </p></div> - + </div> </div> @@ -4113,31 +4114,31 @@ From interface <A NAME="FIELD_PERCENTAGE"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_PERCENTAGE </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A percentage value, between 0 and 100. </p></div> - + </div> </div> @@ -4145,31 +4146,31 @@ From interface <A NAME="FIELD_REVOLUTIONS"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_REVOLUTIONS </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A count of revolutions. </p></div> - + </div> </div> @@ -4177,31 +4178,31 @@ From interface <A NAME="FIELD_RPM"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_RPM </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>Revolutions per minute or rate per minute. </p></div> - + </div> </div> @@ -4209,31 +4210,31 @@ From interface <A NAME="FIELD_SPEED"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_SPEED </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A speed in meter/sec. </p></div> - + </div> </div> @@ -4241,31 +4242,31 @@ From interface <A NAME="FIELD_STEPS"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_STEPS </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A count of steps. </p></div> - + </div> </div> @@ -4273,31 +4274,31 @@ From interface <A NAME="FIELD_WATTS"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_WATTS </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>Power in watts. </p></div> - + </div> </div> @@ -4305,31 +4306,31 @@ From interface <A NAME="FIELD_WEIGHT"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - static - final + public + static + final <a href="/reference/com/google/android/gms/fitness/data/Field.html">Field</a> </span> FIELD_WEIGHT </h4> <div class="api-level"> - - - + + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>A weight in kilograms. </p></div> - + </div> </div> @@ -4354,14 +4355,14 @@ From interface <A NAME="describeContents()"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - - - - + public + + + + int </span> <span class="sympad">describeContents</span> @@ -4369,15 +4370,15 @@ From interface </h4> <div class="api-level"> <div></div> - - + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p></p></div> </div> @@ -4386,14 +4387,14 @@ From interface <A NAME="equals(java.lang.Object)"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - - - - + public + + + + boolean </span> <span class="sympad">equals</span> @@ -4401,15 +4402,15 @@ From interface </h4> <div class="api-level"> <div></div> - - + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p></p></div> </div> @@ -4418,14 +4419,14 @@ From interface <A NAME="getFormat()"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - - - - + public + + + + int </span> <span class="sympad">getFormat</span> @@ -4433,15 +4434,15 @@ From interface </h4> <div class="api-level"> <div></div> - - + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>Returns the format of the field, as one of the format constant values. </p></div> @@ -4451,14 +4452,14 @@ From interface <A NAME="getName()"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - - - - + public + + + + String </span> <span class="sympad">getName</span> @@ -4466,15 +4467,15 @@ From interface </h4> <div class="api-level"> <div></div> - - + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p>Returns the name of the field. </p></div> @@ -4484,14 +4485,14 @@ From interface <A NAME="hashCode()"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - - - - + public + + + + int </span> <span class="sympad">hashCode</span> @@ -4499,15 +4500,15 @@ From interface </h4> <div class="api-level"> <div></div> - - + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p></p></div> </div> @@ -4516,14 +4517,14 @@ From interface <A NAME="toString()"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - - - - + public + + + + String </span> <span class="sympad">toString</span> @@ -4531,15 +4532,15 @@ From interface </h4> <div class="api-level"> <div></div> - - + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p></p></div> </div> @@ -4548,14 +4549,14 @@ From interface <A NAME="writeToParcel(android.os.Parcel, int)"></A> -<div class="jd-details api apilevel-"> +<div class="jd-details api apilevel-"> <h4 class="jd-details-title"> <span class="normal"> - public - - - - + public + + + + void </span> <span class="sympad">writeToParcel</span> @@ -4563,15 +4564,15 @@ From interface </h4> <div class="api-level"> <div></div> - - + + </div> <div class="jd-details-descr"> - - - + + + <div class="jd-tagdata jd-tagdescr"><p></p></div> </div> @@ -4589,17 +4590,17 @@ From interface <A NAME="navbar_top"></A> <div id="footer" class="wrap" > - + <div id="copyright"> - + Except as noted, this content is licensed under <a - href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. + href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. For details and restrictions, see the <a href="/license.html"> Content License</a>. </div> <div id="build_info"> - + <script src="/timestamp.js" type="text/javascript"></script> <script>document.write(BUILD_TIMESTAMP)</script> @@ -4607,7 +4608,7 @@ From interface <div id="footerlinks"> - + <p> <a href="/about/index.html">About Android</a> | <a href="/legal.html">Legal</a> | @@ -4620,7 +4621,7 @@ From interface </div><!-- end doc-content --> -</div> <!-- end body-content --> +</div> <!-- end body-content --> diff --git a/keystore/java/android/security/AndroidKeyPairGenerator.java b/keystore/java/android/security/AndroidKeyPairGenerator.java index 5fae831..3b25ba6 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 00c142f..0000000 --- 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 35a5acc..e64bffa 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 f1c2cac..d36d80c 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 84a664e..3bc1b17 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 37e00b2..3b13e83 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 8ed6e04..1aa3aec 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 aafd2fa..0619199 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 a19bbda..175369c 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 87e7ee6..dde3b8f 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 e6342ef..d0410b8 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 7a88dee..a7046dd 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 1a5552a..916b1ba 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 195fa9a..95332a3 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 b2886bb..541d871 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/packages/PrintSpooler/Android.mk b/packages/PrintSpooler/Android.mk index 27d1b23..19e44e3 100644 --- a/packages/PrintSpooler/Android.mk +++ b/packages/PrintSpooler/Android.mk @@ -18,6 +18,8 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res frameworks/support/v7/recyclerview/res +LOCAL_AAPT_FLAGS := --auto-add-overlay --extra-packages android.support.v7.recyclerview LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_SRC_FILES += \ src/com/android/printspooler/renderer/IPdfRenderer.aidl \ @@ -30,4 +32,4 @@ LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 android-support-v7-recyclervie include $(BUILD_PACKAGE) -include $(call all-makefiles-under, $(LOCAL_PATH))
\ No newline at end of file +include $(call all-makefiles-under, $(LOCAL_PATH)) diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 1ca772f..ecbdcb7 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -4225,8 +4225,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 151766f..7a41bb2 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 65056ac..dda468a 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 51c838f..be8b0fd 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/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index 7623514..1545557 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -673,8 +673,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } @Override - public IntentSender createAppWidgetConfigIntentSender(String callingPackage, int appWidgetId, - int intentFlags) { + public IntentSender createAppWidgetConfigIntentSender(String callingPackage, int appWidgetId) { final int userId = UserHandle.getCallingUserId(); if (DEBUG) { @@ -704,7 +703,6 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); intent.setComponent(provider.info.configure); - intent.setFlags(intentFlags); // All right, create the sender. final long identity = Binder.clearCallingIdentity(); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index dbfb8fb..41d784c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1288,10 +1288,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 @@ -1404,15 +1405,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; @@ -1433,6 +1425,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; @@ -1497,30 +1571,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; @@ -1621,34 +1671,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; @@ -1669,10 +1691,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; @@ -1780,11 +1798,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(); @@ -2079,6 +2092,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); @@ -2444,7 +2458,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, @@ -5101,20 +5115,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) { @@ -5803,17 +5817,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); } @@ -8054,7 +8071,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 +11376,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 +11426,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 +11719,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 +12174,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 +14908,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 +15000,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 +15022,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 +15037,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 +15051,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 +15069,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 +15144,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 +18935,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/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index ada16e7..d89fa15 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -780,8 +780,14 @@ final class ActivityStack { final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming, boolean dontWait) { if (mPausingActivity != null) { - Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity); - completePauseLocked(false); + Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity + + " state=" + mPausingActivity.state); + if (!mService.isSleeping()) { + // Avoid recursion among check for sleep and complete pause during sleeping. + // Because activity will be paused immediately after resume, just let pause + // be completed by the order of activity paused from clients. + completePauseLocked(false); + } } ActivityRecord prev = mResumedActivity; if (prev == null) { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index aef9067..e9df96b 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -340,6 +340,7 @@ public class WindowManagerService extends IWindowManager.Stub final boolean mHasPermanentDpad; final long mDrawLockTimeoutMillis; + final boolean mAllowAnimationsInLowPowerMode; final boolean mAllowBootMessages; @@ -844,6 +845,8 @@ public class WindowManagerService extends IWindowManager.Stub com.android.internal.R.bool.config_defaultInTouchMode); mDrawLockTimeoutMillis = context.getResources().getInteger( com.android.internal.R.integer.config_drawLockTimeoutMillis); + mAllowAnimationsInLowPowerMode = context.getResources().getBoolean( + com.android.internal.R.bool.config_allowAnimationsInLowPowerMode); mInputManager = inputManager; // Must be before createDisplayContentLocked. mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); mDisplaySettings = new DisplaySettings(); @@ -869,7 +872,7 @@ public class WindowManagerService extends IWindowManager.Stub @Override public void onLowPowerModeChanged(boolean enabled) { synchronized (mWindowMap) { - if (mAnimationsDisabled != enabled) { + if (mAnimationsDisabled != enabled && !mAllowAnimationsInLowPowerMode) { mAnimationsDisabled = enabled; dispatchNewAnimatorScaleLocked(null); } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index f5d4867..e8cdc55 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -28,6 +28,8 @@ import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; +import android.content.res.Configuration; +import android.content.res.Resources; import android.database.ContentObserver; import android.hardware.soundtrigger.IRecognitionStatusCallback; import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel; @@ -79,6 +81,7 @@ public class VoiceInteractionManagerService extends SystemService { mResolver = context.getContentResolver(); mDbHelper = new DatabaseHelper(context); mSoundTriggerHelper = new SoundTriggerHelper(context); + mServiceStub = new VoiceInteractionManagerServiceStub(); } @Override @@ -104,8 +107,7 @@ public class VoiceInteractionManagerService extends SystemService { } // implementation entry point and binder service - private final VoiceInteractionManagerServiceStub mServiceStub - = new VoiceInteractionManagerServiceStub(); + private final VoiceInteractionManagerServiceStub mServiceStub; class VoiceInteractionManagerServiceStub extends IVoiceInteractionManagerService.Stub { @@ -113,6 +115,11 @@ public class VoiceInteractionManagerService extends SystemService { private boolean mSafeMode; private int mCurUser; + private final boolean mEnableService; + + VoiceInteractionManagerServiceStub() { + mEnableService = shouldEnableService(mContext.getResources()); + } @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) @@ -136,8 +143,7 @@ public class VoiceInteractionManagerService extends SystemService { Settings.Secure.VOICE_INTERACTION_SERVICE, userHandle); ComponentName curRecognizer = getCurRecognizer(userHandle); VoiceInteractionServiceInfo curInteractorInfo = null; - if (curInteractorStr == null && curRecognizer != null - && !ActivityManager.isLowRamDeviceStatic()) { + if (curInteractorStr == null && curRecognizer != null && mEnableService) { // If there is no interactor setting, that means we are upgrading // from an older platform version. If the current recognizer is not // set or matches the preferred recognizer, then we want to upgrade @@ -155,7 +161,7 @@ public class VoiceInteractionManagerService extends SystemService { // If we are on a svelte device, make sure an interactor is not currently // enabled; if it is, turn it off. - if (ActivityManager.isLowRamDeviceStatic() && curInteractorStr != null) { + if (!mEnableService && curInteractorStr != null) { if (!TextUtils.isEmpty(curInteractorStr)) { setCurInteractor(null, userHandle); curInteractorStr = ""; @@ -184,7 +190,7 @@ public class VoiceInteractionManagerService extends SystemService { } // Initializing settings, look for an interactor first (but only on non-svelte). - if (curInteractorInfo == null && !ActivityManager.isLowRamDeviceStatic()) { + if (curInteractorInfo == null && mEnableService) { curInteractorInfo = findAvailInteractor(userHandle, null); } @@ -210,6 +216,12 @@ public class VoiceInteractionManagerService extends SystemService { } } + private boolean shouldEnableService(Resources res) { + // VoiceInteractionService should not be enabled on low ram devices unless it has the config flag. + return !ActivityManager.isLowRamDeviceStatic() + || res.getBoolean(com.android.internal.R.bool.config_forceEnableVoiceInteractionService); + } + public void systemRunning(boolean safeMode) { mSafeMode = safeMode; @@ -659,6 +671,7 @@ public class VoiceInteractionManagerService extends SystemService { } synchronized (this) { pw.println("VOICE INTERACTION MANAGER (dumpsys voiceinteraction)\n"); + pw.println(" mEnableService: " + mEnableService); if (mImpl == null) { pw.println(" (No active implementation)"); return; diff --git a/tools/obbtool/pbkdf2gen.cpp b/tools/obbtool/pbkdf2gen.cpp index 98d67c0..f1d8d04 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> |