diff options
Diffstat (limited to 'core/java/android')
19 files changed, 321 insertions, 201 deletions
diff --git a/core/java/android/animation/DoubleEvaluator.java b/core/java/android/animation/DoubleEvaluator.java deleted file mode 100644 index e46eb37..0000000 --- a/core/java/android/animation/DoubleEvaluator.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2010 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.animation; - -/** - * This evaluator can be used to perform type interpolation between <code>double</code> values. - */ -public class DoubleEvaluator implements TypeEvaluator { - /** - * This function returns the result of linearly interpolating the start and end values, with - * <code>fraction</code> representing the proportion between the start and end values. The - * calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>, - * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>, - * and <code>t</code> is <code>fraction</code>. - * - * @param fraction The fraction from the starting to the ending values - * @param startValue The start value; should be of type <code>double</code> or - * <code>Double</code> - * @param endValue The end value; should be of type <code>double</code> or - * <code>Double</code> - * @return A linear interpolation between the start and end values, given the - * <code>fraction</code> parameter. - */ - public Object evaluate(float fraction, Object startValue, Object endValue) { - double startDouble = ((Number) startValue).doubleValue(); - return startDouble + fraction * (((Number) endValue).doubleValue() - startDouble); - } -}
\ No newline at end of file diff --git a/core/java/android/animation/FloatKeyframeSet.java b/core/java/android/animation/FloatKeyframeSet.java index 6fad4a68..4009f13 100644 --- a/core/java/android/animation/FloatKeyframeSet.java +++ b/core/java/android/animation/FloatKeyframeSet.java @@ -25,8 +25,8 @@ import java.util.ArrayList; * values between those keyframes for a given animation. The class internal to the animation * package because it is an implementation detail of how Keyframes are stored and used. * - * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclasses for - * int, long, and double, exists to speed up the getValue() method when there is no custom + * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclass for + * int, exists to speed up the getValue() method when there is no custom * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the * Object equivalents of these primitive types.</p> */ diff --git a/core/java/android/animation/IntKeyframeSet.java b/core/java/android/animation/IntKeyframeSet.java index 14a4e3a..5629c5e 100644 --- a/core/java/android/animation/IntKeyframeSet.java +++ b/core/java/android/animation/IntKeyframeSet.java @@ -25,8 +25,8 @@ import java.util.ArrayList; * values between those keyframes for a given animation. The class internal to the animation * package because it is an implementation detail of how Keyframes are stored and used. * - * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclasses for - * float, long, and double, exists to speed up the getValue() method when there is no custom + * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclass for + * float, exists to speed up the getValue() method when there is no custom * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the * Object equivalents of these primitive types.</p> */ diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java index 3212cba..d038cd6 100644 --- a/core/java/android/animation/ObjectAnimator.java +++ b/core/java/android/animation/ObjectAnimator.java @@ -18,7 +18,6 @@ package android.animation; import android.util.Log; -import java.lang.ref.WeakReference; import java.lang.reflect.Method; import java.util.ArrayList; @@ -29,8 +28,6 @@ import java.util.ArrayList; * are then determined internally and the animation will call these functions as necessary to * animate the property. * - * <p class="note"><b>Note:</b> Instances of this class hold only a {@link WeakReference} - * to the target object.</p> * @see #setPropertyName(String) * */ @@ -38,7 +35,7 @@ public final class ObjectAnimator extends ValueAnimator { private static final boolean DBG = false; // The target object on which the property exists, set in the constructor - private WeakReference<Object> mTargetRef; + private Object mTarget; private String mPropertyName; @@ -105,9 +102,6 @@ public final class ObjectAnimator extends ValueAnimator { * @return Method the method associated with mPropertyName. */ private Method getPropertyFunction(String prefix, Class valueType) { - final Object target = mTargetRef == null ? null : mTargetRef.get(); - if (target == null) return null; - // TODO: faster implementation... Method returnVal = null; String firstLetter = mPropertyName.substring(0, 1); @@ -120,7 +114,7 @@ public final class ObjectAnimator extends ValueAnimator { args[0] = valueType; } try { - returnVal = target.getClass().getMethod(setterName, args); + returnVal = mTarget.getClass().getMethod(setterName, args); } catch (NoSuchMethodException e) { Log.e("ObjectAnimator", "Couldn't find setter/getter for property " + mPropertyName + ": " + e); @@ -140,14 +134,13 @@ public final class ObjectAnimator extends ValueAnimator { * A constructor that takes a single property name and set of values. This constructor is * used in the simple case of animating a single property. * - * @param target The object whose property is to be animated. It will be weakly referenced - * from the newly-created ObjectAnimator. This object should have a public method on it called - * <code>setName()</code>, where <code>name</code> is the value of the <code>propertyName</code> - * parameter. + * @param target The object whose property is to be animated. This object should + * have a public method on it called <code>setName()</code>, where <code>name</code> is + * the value of the <code>propertyName</code> parameter. * @param propertyName The name of the property being animated. */ private ObjectAnimator(Object target, String propertyName) { - mTargetRef = new WeakReference<Object>(target); + mTarget = target; setPropertyName(propertyName); } @@ -159,10 +152,9 @@ public final class ObjectAnimator extends ValueAnimator { * from the target object and property being animated). Therefore, there should typically * be two or more values. * - * @param target The object whose property is to be animated. It will be weakly referenced - * from the newly-created ObjectAnimator. This object should have a public method on it called - * <code>setName()</code>, where <code>name</code> is the value of the <code>propertyName</code> - * parameter. + * @param target The object whose property is to be animated. This object should + * have a public method on it called <code>setName()</code>, where <code>name</code> is + * the value of the <code>propertyName</code> parameter. * @param propertyName The name of the property being animated. * @param values A set of values that the animation will animate between over time. * @return A ValueAnimator object that is set up to animate between the given values. @@ -181,10 +173,9 @@ public final class ObjectAnimator extends ValueAnimator { * from the target object and property being animated). Therefore, there should typically * be two or more values. * - * @param target The object whose property is to be animated. It will be weakly referenced - * from the newly-created ObjectAnimator. This object should have a public method on it called - * <code>setName()</code>, where <code>name</code> is the value of the <code>propertyName</code> - * parameter. + * @param target The object whose property is to be animated. This object should + * have a public method on it called <code>setName()</code>, where <code>name</code> is + * the value of the <code>propertyName</code> parameter. * @param propertyName The name of the property being animated. * @param values A set of values that the animation will animate between over time. * @return A ValueAnimator object that is set up to animate between the given values. @@ -201,10 +192,10 @@ public final class ObjectAnimator extends ValueAnimator { * PropertyValuesHolder allows you to associate a set of animation values with a property * name. * - * @param target The object whose property is to be animated. It will be weakly referenced - * from the newly-created ObjectAnimator. This object should have public methods on it called - * <code>setName()</code>, where <code>name</code> is the name of the property passed in as the - * <code>propertyName</code> parameter for each of the PropertyValuesHolder objects. + * @param target The object whose property is to be animated. This object should + * have public methods on it called <code>setName()</code>, where <code>name</code> is + * the name of the property passed in as the <code>propertyName</code> parameter for + * each of the PropertyValuesHolder objects. * @param propertyName The name of the property being animated. * @param evaluator A TypeEvaluator that will be called on each animation frame to * provide the ncessry interpolation between the Object values to derive the animated @@ -227,10 +218,10 @@ public final class ObjectAnimator extends ValueAnimator { * PropertyValuesHolder allows you to associate a set of animation values with a property * name. * - * @param target The object whose property is to be animated. It will be weakly referenced - * from the newly-created ObjectAnimator. This object should have public methods on it called - * <code>setName()</code>, where <code>name</code> is the name of the property passed in as the - * <code>propertyName</code> parameter for each of the PropertyValuesHolder objects. + * @param target The object whose property is to be animated. This object should + * have public methods on it called <code>setName()</code>, where <code>name</code> is + * the name of the property passed in as the <code>propertyName</code> parameter for + * each of the PropertyValuesHolder objects. * @param values A set of PropertyValuesHolder objects whose values will be animated * between over time. * @return A ValueAnimator object that is set up to animate between the given values. @@ -238,7 +229,7 @@ public final class ObjectAnimator extends ValueAnimator { public static ObjectAnimator ofPropertyValuesHolder(Object target, PropertyValuesHolder... values) { ObjectAnimator anim = new ObjectAnimator(); - anim.mTargetRef = new WeakReference<Object>(target); + anim.mTarget = target; anim.setValues(values); return anim; } @@ -279,8 +270,7 @@ public final class ObjectAnimator extends ValueAnimator { @Override public void start() { if (DBG) { - final Object target = mTargetRef == null ? null : mTargetRef.get(); - Log.d("ObjectAnimator", "Anim target, duration" + target + ", " + getDuration()); + Log.d("ObjectAnimator", "Anim target, duration" + mTarget + ", " + getDuration()); for (int i = 0; i < mValues.length; ++i) { PropertyValuesHolder pvh = mValues[i]; ArrayList<Keyframe> keyframes = pvh.mKeyframeSet.mKeyframes; @@ -307,14 +297,11 @@ public final class ObjectAnimator extends ValueAnimator { @Override void initAnimation() { if (!mInitialized) { - final Object target = mTargetRef == null ? null : mTargetRef.get(); - if (target == null) return; - // mValueType may change due to setter/getter setup; do this before calling super.init(), // which uses mValueType to set up the default type evaluator. int numValues = mValues.length; for (int i = 0; i < numValues; ++i) { - mValues[i].setupSetterAndGetter(target); + mValues[i].setupSetterAndGetter(mTarget); } super.initAnimation(); } @@ -339,26 +326,23 @@ public final class ObjectAnimator extends ValueAnimator { /** * The target object whose property will be animated by this animation * - * @return The object being animated, or null if the object has been garbage collected. + * @return The object being animated */ public Object getTarget() { - return mTargetRef == null ? null : mTargetRef.get(); + return mTarget; } /** - * Sets the target object whose property will be animated by this animation. The target - * will be weakly referenced from this object. + * Sets the target object whose property will be animated by this animation * * @param target The object being animated */ @Override public void setTarget(Object target) { - final Object currentTarget = mTargetRef == null ? null : mTargetRef.get(); - - if (currentTarget != target) { - mTargetRef = new WeakReference<Object>(target); - if (currentTarget != null && target != null - && currentTarget.getClass() == target.getClass()) { + if (mTarget != target) { + final Object oldTarget = mTarget; + mTarget = target; + if (oldTarget != null && target != null && oldTarget.getClass() == target.getClass()) { return; } // New target type should cause re-initialization prior to starting @@ -368,25 +352,19 @@ public final class ObjectAnimator extends ValueAnimator { @Override public void setupStartValues() { - final Object target = mTargetRef == null ? null : mTargetRef.get(); - if (target == null) return; - initAnimation(); int numValues = mValues.length; for (int i = 0; i < numValues; ++i) { - mValues[i].setupStartValue(target); + mValues[i].setupStartValue(mTarget); } } @Override public void setupEndValues() { - final Object target = mTargetRef == null ? null : mTargetRef.get(); - if (target == null) return; - initAnimation(); int numValues = mValues.length; for (int i = 0; i < numValues; ++i) { - mValues[i].setupEndValue(target); + mValues[i].setupEndValue(mTarget); } } @@ -405,13 +383,9 @@ public final class ObjectAnimator extends ValueAnimator { @Override void animateValue(float fraction) { super.animateValue(fraction); - - final Object target = mTargetRef == null ? null : mTargetRef.get(); - if (target == null) return; - int numValues = mValues.length; for (int i = 0; i < numValues; ++i) { - mValues[i].setAnimatedValue(target); + mValues[i].setAnimatedValue(mTarget); } } diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java index 0254924..0c30aad 100644 --- a/core/java/android/animation/PropertyValuesHolder.java +++ b/core/java/android/animation/PropertyValuesHolder.java @@ -67,10 +67,9 @@ public class PropertyValuesHolder implements Cloneable { KeyframeSet mKeyframeSet = null; - // type evaluators for the three primitive types handled by this implementation + // type evaluators for the primitive types handled by this implementation private static final TypeEvaluator sIntEvaluator = new IntEvaluator(); private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator(); - private static final TypeEvaluator sDoubleEvaluator = new DoubleEvaluator(); // We try several different types when searching for appropriate setter/getter functions. // The caller may have supplied values in a type that does not match the setter/getter @@ -104,7 +103,7 @@ public class PropertyValuesHolder implements Cloneable { /** * The type evaluator used to calculate the animated values. This evaluator is determined * automatically based on the type of the start/end objects passed into the constructor, - * but the system only knows about the primitive types int, double, and float. Any other + * but the system only knows about the primitive types int and float. Any other * type will need to set the evaluator to a custom evaluator for that type. */ private TypeEvaluator mEvaluator; @@ -501,7 +500,7 @@ public class PropertyValuesHolder implements Cloneable { */ void init() { if (mEvaluator == null) { - // We already handle int, float, long, double automatically, but not their Object + // We already handle int and float automatically, but not their Object // equivalents mEvaluator = (mValueType == Integer.class) ? sIntEvaluator : (mValueType == Float.class) ? sFloatEvaluator : @@ -509,7 +508,7 @@ public class PropertyValuesHolder implements Cloneable { } if (mEvaluator != null) { // KeyframeSet knows how to evaluate the common types - only give it a custom - // evaulator if one has been set on this class + // evaluator if one has been set on this class mKeyframeSet.setEvaluator(mEvaluator); } } @@ -520,7 +519,7 @@ public class PropertyValuesHolder implements Cloneable { * desired. This may be important in cases where either the type of the values supplied * do not match the way that they should be interpolated between, or if the values * are of a custom type or one not currently understood by the animation system. Currently, - * only values of type float, double, and int (and their Object equivalents, Float, Double, + * only values of type float and int (and their Object equivalents: Float * and Integer) are correctly interpolated; all other types require setting a TypeEvaluator. * @param evaluator */ diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index f884473..5705057 100755 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -143,10 +143,9 @@ public class ValueAnimator extends Animator { private static final TimeInterpolator sDefaultInterpolator = new AccelerateDecelerateInterpolator(); - // type evaluators for the three primitive types handled by this implementation + // type evaluators for the primitive types handled by this implementation private static final TypeEvaluator sIntEvaluator = new IntEvaluator(); private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator(); - private static final TypeEvaluator sDoubleEvaluator = new DoubleEvaluator(); /** * Used to indicate whether the animation is currently playing in reverse. This causes the @@ -858,7 +857,7 @@ public class ValueAnimator extends Animator { /** * The type evaluator to be used when calculating the animated values of this animation. - * The system will automatically assign a float, int, or double evaluator based on the type + * The system will automatically assign a float or int evaluator based on the type * of <code>startValue</code> and <code>endValue</code> in the constructor. But if these values * are not one of these primitive types, or if different evaluation is desired (such as is * necessary with int values that represent colors), a custom evaluator needs to be assigned. @@ -1193,4 +1192,16 @@ public class ValueAnimator extends Animator { public static int getCurrentAnimationsCount() { return sAnimations.get().size(); } + + /** + * Clear all animations on this thread, without canceling or ending them. + * This should be used with caution. + * + * @hide + */ + public static void clearAllAnimations() { + sAnimations.get().clear(); + sPendingAnimations.get().clear(); + sDelayedAnims.get().clear(); + } } diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 44db50f..4eae14b 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -77,6 +77,9 @@ public class ActivityManager { * This may be the same size as {@link #getMemoryClass()} on memory * constrained devices, or it may be significantly larger on devices with * a large amount of available RAM. + * + * <p>The is the size of the application's Dalvik heap if it has + * specified <code>android:largeHeap="true"</code> in its manifest. */ public int getLargeMemoryClass() { return staticGetLargeMemoryClass(); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index cc94aa0..db046ef 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -45,7 +45,6 @@ import android.graphics.Canvas; import android.net.IConnectivityManager; import android.net.Proxy; import android.net.ProxyProperties; -import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.Handler; @@ -3463,6 +3462,10 @@ public final class ActivityThread { mInstrumentation = new Instrumentation(); } + if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { + // XXX bump up Dalvik's heap. + } + // If the app is being launched for full backup or restore, bring it up in // a restricted environment with the base application class. Application app = data.info.makeApplication(data.restrictedBackupMode, null); @@ -3471,7 +3474,7 @@ public final class ActivityThread { List<ProviderInfo> providers = data.providers; if (providers != null) { installContentProviders(app, providers); - // For process that contain content providers, we want to + // For process that contains content providers, we want to // ensure that the JIT is enabled "at some point". mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); } diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index bb0ed6a..2d95781 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -270,19 +270,19 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { public static final int FLAG_SUPPORTS_XLARGE_SCREENS = 1<<19; /** - * Value for {@link #flags}: this is true if the application has set - * its android:neverEncrypt to true, false otherwise. It is used to specify - * that this package specifically "opts-out" of a secured file system solution, - * and will always store its data in-the-clear. - * - * {@hide} + * Value for {@link #flags}: true when the application has requested a + * large heap for its processes. Corresponds to + * {@link android.R.styleable#AndroidManifestApplication_largeHeap + * android:largeHeap}. */ - public static final int FLAG_NEVER_ENCRYPT = 1<<30; + public static final int FLAG_LARGE_HEAP = 1<<20; /** * Value for {@link #flags}: Set to true if the application has been * installed using the forward lock option. * + * NOTE: DO NOT CHANGE THIS VALUE! It is saved in packages.xml. + * * {@hide} */ public static final int FLAG_FORWARD_LOCK = 1<<29; @@ -298,7 +298,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { * * {@hide} */ - public static final int FLAG_CANT_SAVE_STATE = 1<<27; + public static final int FLAG_CANT_SAVE_STATE = 1<<28; /** * Flags associated with the application. Any combination of diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index b2937ba..7676258 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -389,11 +389,15 @@ public class PackageParser { XmlResourceParser parser = null; AssetManager assmgr = null; + Resources res = null; boolean assetError = true; try { assmgr = new AssetManager(); int cookie = assmgr.addAssetPath(mArchiveSourcePath); - if(cookie != 0) { + if (cookie != 0) { + res = new Resources(assmgr, metrics, null); + assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + Build.VERSION.RESOURCES_SDK_INT); parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml"); assetError = false; } else { @@ -403,7 +407,7 @@ public class PackageParser { Log.w(TAG, "Unable to read AndroidManifest.xml of " + mArchiveSourcePath, e); } - if(assetError) { + if (assetError) { if (assmgr != null) assmgr.close(); mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST; return null; @@ -413,7 +417,6 @@ public class PackageParser { Exception errorException = null; try { // XXXX todo: need to figure out correct configuration. - Resources res = new Resources(assmgr, metrics, null); pkg = parsePackage(res, parser, flags, errorText); } catch (Exception e) { errorException = e; @@ -593,6 +596,8 @@ public class PackageParser { AssetManager assmgr = null; try { assmgr = new AssetManager(); + assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + Build.VERSION.RESOURCES_SDK_INT); int cookie = assmgr.addAssetPath(packageFilePath); parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml"); } catch (Exception e) { @@ -1574,9 +1579,9 @@ public class PackageParser { } if (sa.getBoolean( - com.android.internal.R.styleable.AndroidManifestApplication_neverEncrypt, + com.android.internal.R.styleable.AndroidManifestApplication_largeHeap, false)) { - ai.flags |= ApplicationInfo.FLAG_NEVER_ENCRYPT; + ai.flags |= ApplicationInfo.FLAG_LARGE_HEAP; } String str; diff --git a/core/java/android/content/pm/PackageStats.java b/core/java/android/content/pm/PackageStats.java index 9464321..28a2886 100755 --- a/core/java/android/content/pm/PackageStats.java +++ b/core/java/android/content/pm/PackageStats.java @@ -19,20 +19,44 @@ package android.content.pm; import android.os.Parcel; import android.os.Parcelable; -import java.util.Arrays; - /** * implementation of PackageStats associated with a * application package. */ public class PackageStats implements Parcelable { + /** Name of the package to which this stats applies. */ public String packageName; + + /** Size of the code (e.g., APK) */ public long codeSize; + + /** + * Size of the internal data size for the application. (e.g., + * /data/data/<app>) + */ public long dataSize; + + /** Size of cache used by the application. (e.g., /data/data/<app>/cache) */ public long cacheSize; - + + /** + * Size of the external data used by the application (e.g., + * <sdcard>/Android/data/<app>) + */ + public long externalDataSize; + + /** + * Size of the external cache used by the application (i.e., on the SD + * card). If this is a subdirectory of the data directory, this size will be + * subtracted out of the external data size. + */ + public long externalCacheSize; + + /** Size of the external media size used by the application. */ + public long externalMediaSize; + public static final Parcelable.Creator<PackageStats> CREATOR - = new Parcelable.Creator<PackageStats>() { + = new Parcelable.Creator<PackageStats>() { public PackageStats createFromParcel(Parcel in) { return new PackageStats(in); } @@ -41,29 +65,49 @@ public class PackageStats implements Parcelable { return new PackageStats[size]; } }; - + public String toString() { - return "PackageStats{" - + Integer.toHexString(System.identityHashCode(this)) - + " " + packageName + "}"; + final StringBuilder sb = new StringBuilder("PackageStats{"); + sb.append(Integer.toHexString(System.identityHashCode(this))); + sb.append(" packageName="); + sb.append(packageName); + sb.append(",codeSize="); + sb.append(codeSize); + sb.append(",dataSize="); + sb.append(dataSize); + sb.append(",cacheSize="); + sb.append(cacheSize); + sb.append(",externalDataSize="); + sb.append(externalDataSize); + sb.append(",externalCacheSize="); + sb.append(externalCacheSize); + sb.append(",externalMediaSize="); + sb.append(externalMediaSize); + return sb.toString(); } - + public PackageStats(String pkgName) { packageName = pkgName; } - + public PackageStats(Parcel source) { packageName = source.readString(); codeSize = source.readLong(); dataSize = source.readLong(); cacheSize = source.readLong(); + externalDataSize = source.readLong(); + externalCacheSize = source.readLong(); + externalMediaSize = source.readLong(); } - + public PackageStats(PackageStats pStats) { packageName = pStats.packageName; codeSize = pStats.codeSize; dataSize = pStats.dataSize; cacheSize = pStats.cacheSize; + externalDataSize = pStats.externalDataSize; + externalCacheSize = pStats.externalCacheSize; + externalMediaSize = pStats.externalMediaSize; } public int describeContents() { @@ -75,5 +119,8 @@ public class PackageStats implements Parcelable { dest.writeLong(codeSize); dest.writeLong(dataSize); dest.writeLong(cacheSize); + dest.writeLong(externalDataSize); + dest.writeLong(externalCacheSize); + dest.writeLong(externalMediaSize); } } diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index b40a226..29bb004 100755 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -56,10 +56,6 @@ public class Resources { private static final int ID_OTHER = 0x01000004; - // Use the current SDK version code. If we are a development build, - // also allow the previous SDK version + 1. - private static final int sSdkVersion = Build.VERSION.SDK_INT - + ("REL".equals(Build.VERSION.CODENAME) ? 0 : 1); private static final Object mSync = new Object(); private static Resources mSystem = null; @@ -1427,14 +1423,14 @@ public class Resources { mConfiguration.touchscreen, (int)(mMetrics.density*160), mConfiguration.keyboard, keyboardHidden, mConfiguration.navigation, width, height, - mConfiguration.screenLayout, mConfiguration.uiMode, sSdkVersion); + mConfiguration.screenLayout, mConfiguration.uiMode, + Build.VERSION.RESOURCES_SDK_INT); clearDrawableCache(mDrawableCache, configChanges); clearDrawableCache(mColorDrawableCache, configChanges); mColorStateListCache.clear(); - flushLayoutCache(); } synchronized (mSync) { diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java index 9f7e31c..5a35eb0 100644 --- a/core/java/android/os/AsyncTask.java +++ b/core/java/android/os/AsyncTask.java @@ -16,9 +16,11 @@ package android.os; +import java.util.ArrayDeque; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; +import java.util.concurrent.Executor; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; import java.util.concurrent.LinkedBlockingQueue; @@ -151,8 +153,6 @@ public abstract class AsyncTask<Params, Progress, Result> { private static final int MAXIMUM_POOL_SIZE = 128; private static final int KEEP_ALIVE = 1; - private static final BlockingQueue<Runnable> sWorkQueue = - new LinkedBlockingQueue<Runnable>(10); private static final ThreadFactory sThreadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); @@ -162,8 +162,17 @@ public abstract class AsyncTask<Params, Progress, Result> { } }; - private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, - MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory); + private static final BlockingQueue<Runnable> sPoolWorkQueue = + new LinkedBlockingQueue<Runnable>(10); + + /** + * A {@link ThreadPoolExecutor} that can be used to execute tasks in parallel. + */ + public static final ThreadPoolExecutor THREAD_POOL_EXECUTOR + = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, + TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); + + private static final SerialExecutor sSerialExecutor = new SerialExecutor(); private static final int MESSAGE_POST_RESULT = 0x1; private static final int MESSAGE_POST_PROGRESS = 0x2; @@ -177,6 +186,32 @@ public abstract class AsyncTask<Params, Progress, Result> { private final AtomicBoolean mTaskInvoked = new AtomicBoolean(); + private static class SerialExecutor implements Executor { + final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); + Runnable mActive; + + public synchronized void execute(final Runnable r) { + mTasks.offer(new Runnable() { + public void run() { + try { + r.run(); + } finally { + scheduleNext(); + } + } + }); + if (mActive == null) { + scheduleNext(); + } + } + + protected synchronized void scheduleNext() { + if ((mActive = mTasks.poll()) != null) { + THREAD_POOL_EXECUTOR.execute(mActive); + } + } + } + /** * Indicates the current status of the task. Each status will be set only once * during the lifetime of a task. @@ -433,7 +468,11 @@ public abstract class AsyncTask<Params, Progress, Result> { /** * Executes the task with the specified parameters. The task returns - * itself (this) so that the caller can keep a reference to it. + * itself (this) so that the caller can keep a reference to it. The tasks + * started by all invocations of this method in a given process are run + * sequentially. Call the executeOnExecutor(Executor,Params...) + * with a custom {@link Executor} to have finer grained control over how the + * tasks are run. * * This method must be invoked on the UI thread. * @@ -445,6 +484,26 @@ public abstract class AsyncTask<Params, Progress, Result> { * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}. */ public final AsyncTask<Params, Progress, Result> execute(Params... params) { + return executeOnExecutor(sSerialExecutor, params); + } + + /** + * Executes the task with the specified parameters. The task returns + * itself (this) so that the caller can keep a reference to it. + * + * This method must be invoked on the UI thread. + * + * @param exec The executor to use. {@link #THREAD_POOL_EXECUTOR} is available as a + * convenient process-wide thread pool for tasks that are loosely coupled. + * @param params The parameters of the task. + * + * @return This instance of AsyncTask. + * + * @throws IllegalStateException If {@link #getStatus()} returns either + * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}. + */ + public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, + Params... params) { if (mStatus != Status.PENDING) { switch (mStatus) { case RUNNING: @@ -462,12 +521,20 @@ public abstract class AsyncTask<Params, Progress, Result> { onPreExecute(); mWorker.mParams = params; - sExecutor.execute(mFuture); + exec.execute(mFuture); return this; } /** + * Schedules the {@link Runnable} in serial with the other AsyncTasks that were started + * with {@link #execute}. + */ + public static void execute(Runnable runnable) { + sSerialExecutor.execute(runnable); + } + + /** * This method can be invoked from {@link #doInBackground} to * publish updates on the UI thread while the background computation is * still running. Each call to this method will trigger the execution of diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 6e50e97..af7b28b 100644 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -100,6 +100,15 @@ public class Build { * a release build. */ public static final String CODENAME = getString("ro.build.version.codename"); + + /** + * The SDK version to use when accessing resources. + * Use the current SDK version code. If we are a development build, + * also allow the previous SDK version + 1. + * @hide + */ + public static final int RESOURCES_SDK_INT = SDK_INT + + ("REL".equals(CODENAME) ? 0 : 1); } /** diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index ad9e6863..e228537 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -1780,7 +1780,7 @@ public final class ViewRoot extends Handler implements ViewParent, } void dispatchDetachedFromWindow() { - if (mView != null) { + if (mView != null && mView.mAttachInfo != null) { mView.dispatchDetachedFromWindow(); } diff --git a/core/java/android/widget/ExpandableListView.java b/core/java/android/widget/ExpandableListView.java index 3d21048..472a335 100644 --- a/core/java/android/widget/ExpandableListView.java +++ b/core/java/android/widget/ExpandableListView.java @@ -22,7 +22,6 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; -import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Parcel; import android.os.Parcelable; @@ -212,6 +211,9 @@ public class ExpandableListView extends ListView { .getDimensionPixelSize(com.android.internal.R.styleable.ExpandableListView_indicatorLeft, 0); mIndicatorRight = a .getDimensionPixelSize(com.android.internal.R.styleable.ExpandableListView_indicatorRight, 0); + if (mIndicatorRight == 0) { + mIndicatorRight = mIndicatorLeft + mGroupIndicator.getIntrinsicWidth(); + } mChildIndicatorLeft = a.getDimensionPixelSize( com.android.internal.R.styleable.ExpandableListView_childIndicatorLeft, CHILD_INDICATOR_INHERIT); mChildIndicatorRight = a.getDimensionPixelSize( diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java index d4ef044..dfa94c7 100644 --- a/core/java/android/widget/FastScroller.java +++ b/core/java/android/widget/FastScroller.java @@ -56,7 +56,7 @@ class FastScroller { private static final int[] DEFAULT_STATES = new int[0]; private static final int[] ATTRS = new int[] { - android.R.attr.textColorPrimary, + android.R.attr.fastScrollTextColor, android.R.attr.fastScrollThumbDrawable, android.R.attr.fastScrollTrackDrawable, android.R.attr.fastScrollPreviewBackgroundLeft, @@ -64,7 +64,7 @@ class FastScroller { android.R.attr.fastScrollOverlayPosition }; - private static final int PRIMARY_TEXT_COLOR = 0; + private static final int TEXT_COLOR = 0; private static final int THUMB_DRAWABLE = 1; private static final int TRACK_DRAWABLE = 2; private static final int PREVIEW_BACKGROUND_LEFT = 3; @@ -247,7 +247,7 @@ class FastScroller { mPaint.setTextAlign(Paint.Align.CENTER); mPaint.setTextSize(mOverlaySize / 2); - ColorStateList textColor = ta.getColorStateList(PRIMARY_TEXT_COLOR); + ColorStateList textColor = ta.getColorStateList(TEXT_COLOR); int textColorNormal = textColor.getDefaultColor(); mPaint.setColor(textColorNormal); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java index 2c96056..585dcf2 100644 --- a/core/java/android/widget/SearchView.java +++ b/core/java/android/widget/SearchView.java @@ -83,6 +83,7 @@ public class SearchView extends LinearLayout { private CursorAdapter mSuggestionsAdapter; private View mSearchButton; private View mSubmitButton; + private View mSubmitArea; private ImageView mCloseButton; private View mSearchEditFrame; private View mVoiceButton; @@ -92,6 +93,7 @@ public class SearchView extends LinearLayout { private boolean mQueryRefinement; private boolean mClearingFocus; private int mMaxWidth; + private boolean mVoiceButtonEnabled; private SearchableInfo mSearchable; @@ -187,6 +189,7 @@ public class SearchView extends LinearLayout { mQueryTextView.setSearchView(this); mSearchEditFrame = findViewById(R.id.search_edit_frame); + mSubmitArea = findViewById(R.id.submit_area); mSubmitButton = findViewById(R.id.search_go_btn); mCloseButton = (ImageView) findViewById(R.id.search_close_btn); mVoiceButton = findViewById(R.id.search_voice_btn); @@ -248,6 +251,8 @@ public class SearchView extends LinearLayout { if (mSearchable != null) { updateSearchAutoComplete(); } + // Cache the voice search capability + mVoiceButtonEnabled = hasVoiceSearch(); updateViewsVisibility(mIconifiedByDefault); } @@ -513,18 +518,55 @@ public class SearchView extends LinearLayout { mIconified = collapsed; // Visibility of views that are visible when collapsed final int visCollapsed = collapsed ? VISIBLE : GONE; - // Visibility of views that are visible when expanded - final int visExpanded = collapsed ? GONE : VISIBLE; // Is there text in the query final boolean hasText = !TextUtils.isEmpty(mQueryTextView.getText()); mSearchButton.setVisibility(visCollapsed); - mSubmitButton.setVisibility(mSubmitButtonEnabled && hasText ? visExpanded : GONE); - mSearchEditFrame.setVisibility(visExpanded); + updateSubmitButton(hasText); + mSearchEditFrame.setVisibility(collapsed ? GONE : VISIBLE); updateCloseButton(); updateVoiceButton(!hasText); + updateSubmitArea(); requestLayout(); - invalidate(); + } + + private boolean hasVoiceSearch() { + if (mSearchable != null && mSearchable.getVoiceSearchEnabled()) { + Intent testIntent = null; + if (mSearchable.getVoiceSearchLaunchWebSearch()) { + testIntent = mVoiceWebSearchIntent; + } else if (mSearchable.getVoiceSearchLaunchRecognizer()) { + testIntent = mVoiceAppSearchIntent; + } + if (testIntent != null) { + ResolveInfo ri = getContext().getPackageManager().resolveActivity(testIntent, + PackageManager.MATCH_DEFAULT_ONLY); + return ri != null; + } + } + return false; + } + + private boolean isSubmitAreaEnabled() { + return (mSubmitButtonEnabled || mVoiceButtonEnabled) && !isIconified(); + } + + private void updateSubmitButton(boolean hasText) { + mSubmitButton.setVisibility( + isSubmitAreaEnabled() ? (hasText ? VISIBLE : INVISIBLE) : GONE); + } + + private void updateSubmitArea() { + int visibility = GONE; + if (isSubmitAreaEnabled()) { + if (mSubmitButton.getVisibility() == VISIBLE + || mVoiceButton.getVisibility() == VISIBLE) { + visibility = VISIBLE; + } else { + visibility = INVISIBLE; + } + } + mSubmitArea.setVisibility(visibility); } private void updateCloseButton() { @@ -790,22 +832,14 @@ public class SearchView extends LinearLayout { * be visible - i.e., if the user has typed a query, remove the voice button. */ private void updateVoiceButton(boolean empty) { - int visibility = View.GONE; - if (mSearchable != null && mSearchable.getVoiceSearchEnabled() && empty - && !isIconified()) { - Intent testIntent = null; - if (mSearchable.getVoiceSearchLaunchWebSearch()) { - testIntent = mVoiceWebSearchIntent; - } else if (mSearchable.getVoiceSearchLaunchRecognizer()) { - testIntent = mVoiceAppSearchIntent; - } - if (testIntent != null) { - ResolveInfo ri = getContext().getPackageManager().resolveActivity(testIntent, - PackageManager.MATCH_DEFAULT_ONLY); - if (ri != null) { - visibility = View.VISIBLE; - } - } + // If the voice button is to be visible, show it + // Else, make it gone if the submit button is enabled, otherwise invisible to + // avoid losing the real-estate + int visibility = mSubmitButtonEnabled ? GONE : INVISIBLE; + + if (mVoiceButtonEnabled && !isIconified() && empty) { + visibility = VISIBLE; + mSubmitButton.setVisibility(GONE); } mVoiceButton.setVisibility(visibility); } @@ -825,12 +859,11 @@ public class SearchView extends LinearLayout { CharSequence text = mQueryTextView.getText(); boolean hasText = !TextUtils.isEmpty(text); if (isSubmitButtonEnabled()) { - mSubmitButton.setVisibility(hasText ? VISIBLE : GONE); - requestLayout(); - invalidate(); + updateSubmitButton(hasText); } updateVoiceButton(!hasText); updateCloseButton(); + updateSubmitArea(); if (mOnQueryChangeListener != null) { mOnQueryChangeListener.onQueryTextChanged(newText.toString()); } diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java index 264af71..2c10077 100644 --- a/core/java/android/widget/StackView.java +++ b/core/java/android/widget/StackView.java @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2010 The Android Open Source Project +/* Copyright (C) 2010 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. @@ -209,22 +208,19 @@ public class StackView extends AdapterViewAnimator { } } - if (fromIndex == -1 && toIndex == NUM_ACTIVE_VIEWS -1) { + if (fromIndex == -1 && toIndex == getNumActiveViews() -1) { // Fade item in if (view.getAlpha() == 1) { view.setAlpha(0); } - view.setScaleX(1 - PERSPECTIVE_SCALE_FACTOR); - view.setScaleY(1 - PERSPECTIVE_SCALE_FACTOR); - view.setTranslationX(mPerspectiveShiftX); - view.setTranslationY(0); + transformViewAtIndex(toIndex, view, false); view.setVisibility(VISIBLE); alphaOa = ObjectAnimator.ofFloat(view, "alpha", view.getAlpha(), 1.0f); alphaOa.setDuration(FADE_IN_ANIMATION_DURATION); if (oldAlphaOa != null) oldAlphaOa.cancel(); alphaOa.start(); - view.setTagInternal(com.android.internal.R.id.viewAlphaAnimation, + view.setTagInternal(com.android.internal.R.id.viewAlphaAnimation, new WeakReference<ObjectAnimator>(alphaOa)); } else if (fromIndex == 0 && toIndex == 1) { // Slide item in @@ -270,7 +266,7 @@ public class StackView extends AdapterViewAnimator { alphaOa.setDuration(STACK_RELAYOUT_DURATION); if (oldAlphaOa != null) oldAlphaOa.cancel(); alphaOa.start(); - view.setTagInternal(com.android.internal.R.id.viewAlphaAnimation, + view.setTagInternal(com.android.internal.R.id.viewAlphaAnimation, new WeakReference<ObjectAnimator>(alphaOa)); } @@ -284,16 +280,20 @@ public class StackView extends AdapterViewAnimator { final float maxPerspectiveShiftY = mPerspectiveShiftY; final float maxPerspectiveShiftX = mPerspectiveShiftX; - index = mMaxNumActiveViews - index - 1; - if (index == mMaxNumActiveViews - 1) index--; + if (mStackMode == ITEMS_SLIDE_DOWN) { + index = mMaxNumActiveViews - index - 1; + if (index == mMaxNumActiveViews - 1) index--; + } else { + index--; + if (index < 0) index++; + } float r = (index * 1.0f) / (mMaxNumActiveViews - 2); final float scale = 1 - PERSPECTIVE_SCALE_FACTOR * (1 - r); - int stackDirection = (mStackMode == ITEMS_SLIDE_UP) ? 1 : -1; - float perspectiveTranslationY = -stackDirection * r * maxPerspectiveShiftY; - float scaleShiftCorrectionY = stackDirection * (1 - scale) * + float perspectiveTranslationY = r * maxPerspectiveShiftY; + float scaleShiftCorrectionY = (scale - 1) * (getMeasuredHeight() * (1 - PERSPECTIVE_SHIFT_FACTOR_Y) / 2.0f); final float transY = perspectiveTranslationY + scaleShiftCorrectionY; @@ -302,7 +302,7 @@ public class StackView extends AdapterViewAnimator { (getMeasuredWidth() * (1 - PERSPECTIVE_SHIFT_FACTOR_X) / 2.0f); final float transX = perspectiveTranslationX + scaleShiftCorrectionX; - // If this view is currently being animated for a certain position, we need to cancel + // If this view is currently being animated for a certain position, we need to cancel // this animation so as not to interfere with the new transformation. Object tag = view.getTag(com.android.internal.R.id.viewAnimation); if (tag instanceof WeakReference<?>) { @@ -515,11 +515,12 @@ public class StackView extends AdapterViewAnimator { private void beginGestureIfNeeded(float deltaY) { if ((int) Math.abs(deltaY) > mTouchSlop && mSwipeGestureType == GESTURE_NONE) { - int swipeGestureType = deltaY < 0 ? GESTURE_SLIDE_UP : GESTURE_SLIDE_DOWN; + final int swipeGestureType = deltaY < 0 ? GESTURE_SLIDE_UP : GESTURE_SLIDE_DOWN; cancelLongPress(); requestDisallowInterceptTouchEvent(true); if (mAdapter == null) return; + final int adapterCount = mAdapter.getCount(); int activeIndex; if (mStackMode == ITEMS_SLIDE_UP) { @@ -528,13 +529,20 @@ public class StackView extends AdapterViewAnimator { activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ? 1 : 0; } + boolean endOfStack = mLoopViews && adapterCount == 1 && + ((mStackMode == ITEMS_SLIDE_UP && swipeGestureType == GESTURE_SLIDE_UP) || + (mStackMode == ITEMS_SLIDE_DOWN && swipeGestureType == GESTURE_SLIDE_DOWN)); + boolean beginningOfStack = mLoopViews && adapterCount == 1 && + ((mStackMode == ITEMS_SLIDE_DOWN && swipeGestureType == GESTURE_SLIDE_UP) || + (mStackMode == ITEMS_SLIDE_UP && swipeGestureType == GESTURE_SLIDE_DOWN)); + int stackMode; - if (mLoopViews) { + if (mLoopViews && !beginningOfStack && !endOfStack) { stackMode = StackSlider.NORMAL_MODE; - } else if (mCurrentWindowStartUnbounded + activeIndex == -1) { + } else if (mCurrentWindowStartUnbounded + activeIndex == -1 || beginningOfStack) { activeIndex++; stackMode = StackSlider.BEGINNING_OF_STACK_MODE; - } else if (mCurrentWindowStartUnbounded + activeIndex == mAdapter.getCount() - 1) { + } else if (mCurrentWindowStartUnbounded + activeIndex == adapterCount - 1 || endOfStack) { stackMode = StackSlider.END_OF_STACK_MODE; } else { stackMode = StackSlider.NORMAL_MODE; @@ -989,6 +997,11 @@ public class StackView extends AdapterViewAnimator { @Override public void advance() { long timeSinceLastInteraction = System.currentTimeMillis() - mLastInteractionTime; + + if (mAdapter == null) return; + final int adapterCount = mAdapter.getCount(); + if (adapterCount == 1 && mLoopViews) return; + if (mSwipeGestureType == GESTURE_NONE && timeSinceLastInteraction > MIN_TIME_BETWEEN_INTERACTION_AND_AUTOADVANCE) { showNext(); @@ -1266,4 +1279,4 @@ public class StackView extends AdapterViewAnimator { mask.recycle(); } } -} +}
\ No newline at end of file |