summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/animation/DoubleEvaluator.java42
-rw-r--r--core/java/android/animation/FloatKeyframeSet.java4
-rw-r--r--core/java/android/animation/IntKeyframeSet.java4
-rw-r--r--core/java/android/animation/ObjectAnimator.java92
-rw-r--r--core/java/android/animation/PropertyValuesHolder.java11
-rwxr-xr-xcore/java/android/animation/ValueAnimator.java17
-rw-r--r--core/java/android/app/ActivityManager.java3
-rw-r--r--core/java/android/app/ActivityThread.java7
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java16
-rw-r--r--core/java/android/content/pm/PackageParser.java15
-rwxr-xr-xcore/java/android/content/pm/PackageStats.java69
-rwxr-xr-xcore/java/android/content/res/Resources.java8
-rw-r--r--core/java/android/os/AsyncTask.java79
-rw-r--r--core/java/android/os/Build.java9
-rw-r--r--core/java/android/view/ViewRoot.java2
-rw-r--r--core/java/android/widget/ExpandableListView.java4
-rw-r--r--core/java/android/widget/FastScroller.java6
-rw-r--r--core/java/android/widget/SearchView.java81
-rw-r--r--core/java/android/widget/StackView.java53
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