summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/java/android/app/Activity.java150
-rw-r--r--core/java/android/app/ActivityOptions.java153
-rw-r--r--core/java/android/app/ContextImpl.java2
-rw-r--r--core/java/android/content/Context.java4
-rw-r--r--core/java/android/net/NetworkStats.java11
-rw-r--r--core/java/android/os/BatteryStats.java140
-rw-r--r--core/java/android/transition/Transition.java45
-rw-r--r--core/java/android/transition/TransitionInflater.java43
-rw-r--r--core/java/android/transition/TransitionManager.java150
-rw-r--r--core/java/android/view/SurfaceControl.java7
-rw-r--r--core/java/android/view/SurfaceView.java5
-rw-r--r--core/java/android/view/VideoPlaneView.java53
-rw-r--r--core/java/android/view/View.java29
-rw-r--r--core/java/android/view/ViewGroup.java40
-rw-r--r--core/java/android/view/Window.java38
-rw-r--r--core/java/android/view/WindowManager.java223
-rw-r--r--core/java/android/widget/AbsListView.java33
-rw-r--r--core/java/android/widget/ProgressBar.java15
-rw-r--r--core/java/com/android/internal/app/ActionBarImpl.java5
-rw-r--r--core/java/com/android/internal/os/BatterySipper.java7
-rw-r--r--core/java/com/android/internal/os/BatteryStatsHelper.java79
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java144
-rw-r--r--core/res/res/layout-xlarge/screen_action_bar.xml1
-rw-r--r--core/res/res/layout/screen_action_bar.xml1
-rw-r--r--core/res/res/layout/screen_custom_title.xml1
-rw-r--r--core/res/res/values/attrs.xml8
-rw-r--r--core/res/res/values/public.xml2
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk41
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/AndroidManifest.xml31
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/res/layout/activity_main.xml7
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java29
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java34
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java39
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/Version.java25
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk41
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/AndroidManifest.xml31
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/res/layout/activity_main.xml7
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java29
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java34
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java39
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/Version.java25
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk41
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/AndroidManifest.xml31
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/res/layout/activity_main.xml7
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java29
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java34
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java39
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/Version.java25
48 files changed, 1508 insertions, 499 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index c79a0a5..9a3c290 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -18,10 +18,8 @@ package android.app;
import android.annotation.NonNull;
import android.transition.Scene;
-import android.transition.Transition;
import android.transition.TransitionManager;
import android.util.ArrayMap;
-import android.util.Pair;
import android.util.SuperNotCalledException;
import com.android.internal.app.ActionBarImpl;
import com.android.internal.policy.PolicyManager;
@@ -95,7 +93,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Map;
/**
* An activity is a single, focused thing that the user can do. Almost all
@@ -3449,53 +3446,7 @@ public class Activity extends ContextThemeWrapper
* @see #startActivity
*/
public void startActivityForResult(Intent intent, int requestCode) {
- ArrayMap<String, View> sharedElements = new ArrayMap<String, View>();
-
- if (mActionBar != null) {
- mActionBar.captureSharedElements(sharedElements);
- }
- Bundle opts = mWindow.startExitTransition(sharedElements);
- startActivityForResult(intent, requestCode, opts);
- }
-
- /**
- * Same as {@link #startActivityForResult(android.content.Intent, int)} except that
- * shared element state is passed to the called Activity during the Activity Scene Transition.
- * The Activity must have a TransitionManager with a Transition associated with exiting
- * the current Scene.
- * @param intent The intent to start.
- * @param requestCode If >= 0, this code will be returned in
- * onActivityResult() when the activity exits.
- * @param sharedElements Views to be transitioned to the called Activity and their
- * names as used in the called Activity.
- * Views must not have null shared element name, however, if the
- * Pair has a null name, the shared element name will be reused
- * for the launched Activity's shared element name.
- * @see android.transition.TransitionManager#setExitTransition(android.transition.Scene, android.transition.Transition)
- * @see View#setSharedElementName(String)
- */
- public void startActivityForResult(Intent intent, int requestCode,
- Pair<View, String>... sharedElements) {
- ArrayMap<String, View> sharedElementMap = new ArrayMap<String, View>();
- if (sharedElements != null) {
- for (Pair<View, String> sharedElement: sharedElements) {
- View view = sharedElement.first;
- String sharedElementName = view.getSharedElementName();
- if (sharedElementName == null) {
- throw new IllegalArgumentException("sharedElement must have a non-null "
- + "sharedElementName");
- }
- String name = sharedElement.second == null
- ? sharedElementName : sharedElement.second;
- sharedElementMap.put(name, view);
- }
- }
- if (mActionBar != null) {
- mActionBar.captureSharedElements(sharedElementMap);
- }
-
- Bundle options = mWindow.startExitTransition(sharedElementMap);
- startActivityForResult(intent, requestCode, options);
+ startActivityForResult(intent, requestCode, null);
}
/**
@@ -3533,6 +3484,14 @@ public class Activity extends ContextThemeWrapper
* @see #startActivity
*/
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
+ TransitionManager tm = getContentTransitionManager();
+ if (tm != null && options != null) {
+ ActivityOptions activityOptions = new ActivityOptions(options);
+ if (activityOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
+ getWindow().startExitTransition(activityOptions);
+ options = activityOptions.toBundle();
+ }
+ }
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
@@ -3705,25 +3664,7 @@ public class Activity extends ContextThemeWrapper
*/
@Override
public void startActivity(Intent intent) {
- startActivity(intent, (Pair<View, String>[]) null);
- }
-
- /**
- * Same as {@link #startActivity(android.content.Intent)} except that shared element
- * state is passed to the called Activity during the Activity Scene Transition.
- * The Activity must have a TransitionManager with a Transition associated with exiting
- * the current Scene.
- * @param intent The intent to start.
- * @param sharedElements Views to be transitioned to the called Activity and their
- * names as used in the called Activity.
- * Views must not have null shared element name, however, if the
- * Pair has a null name, the shared element name will be reused
- * for the launched Activity's shared element name.
- * @see android.transition.TransitionManager#setExitTransition(android.transition.Scene, android.transition.Transition)
- * @see View#setSharedElementName(String)
- */
- public void startActivity(Intent intent, Pair<View, String>... sharedElements) {
- startActivityForResult(intent, -1, sharedElements);
+ startActivity(intent, null);
}
/**
@@ -4779,8 +4720,7 @@ public class Activity extends ContextThemeWrapper
*/
public final void setProgressBarIndeterminate(boolean indeterminate) {
getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
- indeterminate ? Window.PROGRESS_INDETERMINATE_ON
- : Window.PROGRESS_INDETERMINATE_OFF);
+ indeterminate ? Window.PROGRESS_INDETERMINATE_ON : Window.PROGRESS_INDETERMINATE_OFF);
}
/**
@@ -5390,6 +5330,12 @@ public class Activity extends ContextThemeWrapper
mTransitionActivityOptions = activityOptions;
sceneTransitionListener = new Window.SceneTransitionListener() {
@Override
+ public void enterSharedElement(Bundle transitionArgs) {
+ startSharedElementTransition(transitionArgs);
+ mTransitionActivityOptions = null;
+ }
+
+ @Override
public void nullPendingTransition() {
overridePendingTransition(0, 0);
}
@@ -5403,16 +5349,6 @@ public class Activity extends ContextThemeWrapper
public void convertToTranslucent() {
Activity.this.convertToTranslucent(null);
}
-
- @Override
- public void sharedElementStart(Transition transition) {
- Activity.this.onCaptureSharedElementStart(transition);
- }
-
- @Override
- public void sharedElementEnd() {
- Activity.this.onCaptureSharedElementEnd();
- }
};
}
@@ -5606,23 +5542,53 @@ public class Activity extends ContextThemeWrapper
}
/**
- * Called when setting up Activity Scene transitions when the start state for shared
- * elements has been captured. Override this method to modify the start position of shared
- * elements for the entry Transition.
+ * Gets the entering Activity transition args. Will be null if
+ * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(android.os.Bundle)} was
+ * not used to pass a Bundle to startActivity. The Bundle passed to that method in the
+ * calling Activity is returned here.
+ * <p>After startSharedElementTransition is called, this method will return null.</p>
*
- * @param transition The <code>Transition</code> being used to change
- * bounds of shared elements in the source Activity to
- * the bounds defined by the entering Scene.
+ * @return The Bundle passed into Bundle parameter of
+ * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(android.os.Bundle)}
+ * in the calling Activity.
*/
- public void onCaptureSharedElementStart(Transition transition) {
+ public Bundle getTransitionArgs() {
+ if (mTransitionActivityOptions == null) {
+ return null;
+ }
+ return mTransitionActivityOptions.getSceneTransitionArgs();
+ }
+
+ /**
+ * Override to transfer a shared element from a calling Activity to this Activity.
+ * Shared elements will be made VISIBLE before this call. The Activity is responsible
+ * for transitioning the shared elements from their location to the eventual destination.
+ * The shared element will be laid out a the destination when this method is called.
+ *
+ * @param transitionArgs The same as returned from {@link #getTransitionArgs()}, this should
+ * contain information from the calling Activity to tell where the
+ * shared element should be placed.
+ */
+ protected void startSharedElementTransition(Bundle transitionArgs) {
}
/**
- * Called when setting up Activity Scene transitions when the final state for
- * shared elements state has been captured. Override this method to modify the destination
- * position of shared elements for the entry Transition.
+ * Controls how the background fade is triggered when there is an entering Activity transition.
+ * If fadeEarly is true, the Window background will fade in as soon as the shared elements are
+ * ready to switch. If fadeEarly is false, the background will fade only after the calling
+ * Activity's exit transition completes. By default, the Window will fade in when the calling
+ * Activity's exit transition completes.
+ *
+ * @param fadeEarly Set to true to fade out the exiting Activity as soon as the shared elements
+ * are transferred. Set to false to fade out the exiting Activity as soon as
+ * the shared element is transferred.
+ * @see android.app.ActivityOptions#makeSceneTransitionAnimation(android.os.Bundle)
*/
- public void onCaptureSharedElementEnd() {
+ public void setEarlyBackgroundTransition(boolean fadeEarly) {
+ if (mTransitionActivityOptions == null) {
+ return;
+ }
+ mWindow.setEarlyBackgroundTransition(fadeEarly);
}
/**
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 32cc30b..3f97c40 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -16,6 +16,7 @@
package android.app;
+import android.animation.Animator;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
@@ -23,10 +24,12 @@ import android.os.Handler;
import android.os.IRemoteCallback;
import android.os.RemoteException;
import android.transition.Transition;
+import android.util.ArrayMap;
import android.util.Log;
import android.view.View;
import java.util.ArrayList;
+import java.util.Map;
/**
* Helper class for building an options Bundle that can be used with
@@ -97,6 +100,12 @@ public class ActivityOptions {
public static final String KEY_ANIM_START_LISTENER = "android:animStartListener";
/**
+ * Arguments for the scene transition about to begin.
+ * @hide
+ */
+ public static final String KEY_SCENE_TRANSITION_ARGS = "android:sceneTransitionArgs";
+
+ /**
* For Activity transitions, the calling Activity's TransitionListener used to
* notify the called Activity when the shared element and the exit transitions
* complete.
@@ -111,10 +120,9 @@ public class ActivityOptions {
private static final String KEY_TRANSITION_TARGET_LISTENER = "android:transitionTargetListener";
/**
- * The names of shared elements that are transitioned to the started Activity.
- * This is also the name of shared elements that the started Activity accepted.
+ * The shared element's texture ID (TODO: not used yet).
*/
- private static final String KEY_SHARED_ELEMENT_NAMES = "android:shared_element_names";
+ private static final String KEY_SHARED_ELEMENT_TEXTURE_ID = "android:sharedElementTextureId";
/** @hide */
public static final int ANIM_NONE = 0;
@@ -138,9 +146,9 @@ public class ActivityOptions {
private int mStartY;
private int mStartWidth;
private int mStartHeight;
+ private Bundle mTransitionArgs;
private IRemoteCallback mAnimationStartedListener;
private IRemoteCallback mTransitionCompleteListener;
- private ArrayList<String> mSharedElementNames;
/**
* Create an ActivityOptions specifying a custom animation to run when
@@ -218,7 +226,7 @@ public class ActivityOptions {
/** @hide */
public interface ActivityTransitionTarget {
- void sharedElementTransitionComplete(Bundle transitionArgs);
+ void sharedElementTransitionComplete();
void exitTransitionComplete();
}
@@ -344,6 +352,8 @@ public class ActivityOptions {
* When visual elements are to carry between Activities, args should be used to tell the called
* Activity about the location and size.
*
+ * TODO: Provide facility to capture layout and bitmap of shared elements.
+ *
* <p>When
* {@link android.app.Activity#startActivities(android.content.Intent[], android.os.Bundle)}
* is used with the {@link #toBundle()} result, the Activity's content scene will automatically
@@ -358,16 +368,15 @@ public class ActivityOptions {
* enabled on the calling Activity to cause an exit transition. The same must be in
* the called Activity to get an entering transition.</p>
*
- * @hide
+ * @param args Contains information for transferring a view between this Activity and the
+ * target Activity. Will be used by the called Activity to transition the
+ * view to its eventual destination
+ * @see android.app.Activity#startSharedElementTransition(android.os.Bundle)
*/
- public static ActivityOptions makeSceneTransitionAnimation(Transition exitTransition,
- ArrayList<String> sharedElementNames, Transition sharedElementTransition,
- SharedElementSource sharedElementSource) {
+ public static ActivityOptions makeSceneTransitionAnimation(Bundle args) {
ActivityOptions opts = new ActivityOptions();
opts.mAnimationType = ANIM_SCENE_TRANSITION;
- opts.mTransitionCompleteListener = new ExitTransitionListener(exitTransition,
- sharedElementTransition, sharedElementSource);
- opts.mSharedElementNames = sharedElementNames;
+ opts.mTransitionArgs = args;
return opts;
}
@@ -403,9 +412,9 @@ public class ActivityOptions {
break;
case ANIM_SCENE_TRANSITION:
+ mTransitionArgs = opts.getBundle(KEY_SCENE_TRANSITION_ARGS);
mTransitionCompleteListener = IRemoteCallback.Stub.asInterface(
opts.getBinder(KEY_TRANSITION_COMPLETE_LISTENER));
- mSharedElementNames = opts.getStringArrayList(KEY_SHARED_ELEMENT_NAMES);
break;
}
}
@@ -456,16 +465,17 @@ public class ActivityOptions {
}
/** @hide */
- public IRemoteCallback getOnAnimationStartListener() {
- return mAnimationStartedListener;
+ public Bundle getSceneTransitionArgs() {
+ return mTransitionArgs;
}
/** @hide */
- public ArrayList<String> getSharedElementNames() { return mSharedElementNames; }
+ public IRemoteCallback getOnAnimationStartListener() {
+ return mAnimationStartedListener;
+ }
/** @hide */
- public void dispatchSceneTransitionStarted(final ActivityTransitionTarget target,
- ArrayList<String> sharedElementNames) {
+ public void dispatchSceneTransitionStarted(final ActivityTransitionTarget target) {
boolean listenerSent = false;
if (mTransitionCompleteListener != null) {
IRemoteCallback callback = new IRemoteCallback.Stub() {
@@ -474,13 +484,13 @@ public class ActivityOptions {
if (data == null) {
target.exitTransitionComplete();
} else {
- target.sharedElementTransitionComplete(data);
+ // TODO: Use texture id
+ target.sharedElementTransitionComplete();
}
}
};
Bundle bundle = new Bundle();
bundle.putBinder(KEY_TRANSITION_TARGET_LISTENER, callback.asBinder());
- bundle.putStringArrayList(KEY_SHARED_ELEMENT_NAMES, sharedElementNames);
try {
mTransitionCompleteListener.sendResult(bundle);
listenerSent = true;
@@ -489,23 +499,12 @@ public class ActivityOptions {
}
}
if (!listenerSent) {
- target.sharedElementTransitionComplete(null);
+ target.sharedElementTransitionComplete();
target.exitTransitionComplete();
}
}
/** @hide */
- public void dispatchSharedElementsReady() {
- if (mTransitionCompleteListener != null) {
- try {
- mTransitionCompleteListener.sendResult(null);
- } catch (RemoteException e) {
- Log.w(TAG, "Couldn't synchronize shared elements", e);
- }
- }
- }
-
- /** @hide */
public void abort() {
if (mAnimationStartedListener != null) {
try {
@@ -531,7 +530,6 @@ public class ActivityOptions {
if (otherOptions.mPackageName != null) {
mPackageName = otherOptions.mPackageName;
}
- mSharedElementNames = null;
switch (otherOptions.mAnimationType) {
case ANIM_CUSTOM:
mAnimationType = otherOptions.mAnimationType;
@@ -546,6 +544,7 @@ public class ActivityOptions {
}
mAnimationStartedListener = otherOptions.mAnimationStartedListener;
mTransitionCompleteListener = null;
+ mTransitionArgs = null;
break;
case ANIM_SCALE_UP:
mAnimationType = otherOptions.mAnimationType;
@@ -561,6 +560,7 @@ public class ActivityOptions {
}
mAnimationStartedListener = null;
mTransitionCompleteListener = null;
+ mTransitionArgs = null;
break;
case ANIM_THUMBNAIL_SCALE_UP:
case ANIM_THUMBNAIL_SCALE_DOWN:
@@ -576,13 +576,14 @@ public class ActivityOptions {
}
mAnimationStartedListener = otherOptions.mAnimationStartedListener;
mTransitionCompleteListener = null;
+ mTransitionArgs = null;
break;
case ANIM_SCENE_TRANSITION:
mAnimationType = otherOptions.mAnimationType;
mTransitionCompleteListener = otherOptions.mTransitionCompleteListener;
+ mTransitionArgs = otherOptions.mTransitionArgs;
mThumbnail = null;
mAnimationStartedListener = null;
- mSharedElementNames = otherOptions.mSharedElementNames;
break;
}
}
@@ -626,11 +627,11 @@ public class ActivityOptions {
break;
case ANIM_SCENE_TRANSITION:
b.putInt(KEY_ANIM_TYPE, mAnimationType);
+ b.putBundle(KEY_SCENE_TRANSITION_ARGS, mTransitionArgs);
if (mTransitionCompleteListener != null) {
b.putBinder(KEY_TRANSITION_COMPLETE_LISTENER,
mTransitionCompleteListener.asBinder());
}
- b.putStringArrayList(KEY_SHARED_ELEMENT_NAMES, mSharedElementNames);
break;
}
return b;
@@ -652,28 +653,31 @@ public class ActivityOptions {
/** @hide */
public interface SharedElementSource {
- Bundle getSharedElementExitState();
- void acceptedSharedElements(ArrayList<String> sharedElementNames);
- void hideSharedElements();
+ int getTextureId();
+ }
+
+ /**
+ * In the calling Activity when transitioning out, sets the Transition to listen for
+ * changes.
+ * @hide
+ */
+ public void setExitTransition(Transition transition, SharedElementSource sharedElementSource) {
+ mTransitionCompleteListener = new ExitTransitionListener(transition, sharedElementSource);
}
private static class ExitTransitionListener extends IRemoteCallback.Stub
- implements Transition.TransitionListener {
+ implements Transition.TransitionListener, Animator.AnimatorListener {
+ private ArrayList<Animator> mSharedElementAnimators = new ArrayList<Animator>();
private boolean mSharedElementNotified;
private Transition mExitTransition;
- private Transition mSharedElementTransition;
private IRemoteCallback mTransitionCompleteCallback;
private boolean mExitComplete;
- private boolean mSharedElementComplete;
private SharedElementSource mSharedElementSource;
- public ExitTransitionListener(Transition exitTransition, Transition sharedElementTransition,
- SharedElementSource sharedElementSource) {
+ public ExitTransitionListener(Transition transition, SharedElementSource sharedElementSource) {
mSharedElementSource = sharedElementSource;
- mExitTransition = exitTransition;
+ mExitTransition = transition;
mExitTransition.addListener(this);
- mSharedElementTransition = sharedElementTransition;
- mSharedElementTransition.addListener(this);
}
@Override
@@ -681,36 +685,36 @@ public class ActivityOptions {
if (data != null) {
mTransitionCompleteCallback = IRemoteCallback.Stub.asInterface(
data.getBinder(KEY_TRANSITION_TARGET_LISTENER));
- ArrayList<String> sharedElementNames
- = data.getStringArrayList(KEY_SHARED_ELEMENT_NAMES);
- mSharedElementSource.acceptedSharedElements(sharedElementNames);
notifySharedElement();
notifyExit();
- } else {
- mSharedElementSource.hideSharedElements();
}
}
@Override
public void onTransitionStart(Transition transition) {
+ ArrayMap<Animator, Transition.AnimationInfo> runningAnimators
+ = Transition.getRunningAnimators();
+ for (Map.Entry<Animator, Transition.AnimationInfo> entry : runningAnimators.entrySet()) {
+ if (entry.getValue().view.getSharedElementName() != null) {
+ mSharedElementAnimators.add(entry.getKey());
+ entry.getKey().addListener(this);
+ }
+ }
+ notifySharedElement();
}
@Override
public void onTransitionEnd(Transition transition) {
- if (transition == mExitTransition) {
- mExitComplete = true;
- notifyExit();
- mExitTransition.removeListener(this);
- } else {
- mSharedElementComplete = true;
- notifySharedElement();
- mSharedElementTransition.removeListener(this);
- }
+ mExitComplete = true;
+ notifyExit();
+ mExitTransition.removeListener(this);
}
@Override
public void onTransitionCancel(Transition transition) {
- onTransitionEnd(transition);
+ mExitComplete = true;
+ notifyExit();
+ mExitTransition.removeListener(this);
}
@Override
@@ -721,13 +725,34 @@ public class ActivityOptions {
public void onTransitionResume(Transition transition) {
}
+ @Override
+ public void onAnimationStart(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mSharedElementAnimators.remove(animation);
+ notifySharedElement();
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mSharedElementAnimators.remove(animation);
+ notifySharedElement();
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ }
+
private void notifySharedElement() {
- if (!mSharedElementNotified && mSharedElementComplete
+ if (!mSharedElementNotified && mSharedElementAnimators.isEmpty()
&& mTransitionCompleteCallback != null) {
mSharedElementNotified = true;
try {
- Bundle sharedElementState = mSharedElementSource.getSharedElementExitState();
- mTransitionCompleteCallback.sendResult(sharedElementState);
+ Bundle bundle = new Bundle();
+ bundle.putInt(KEY_SHARED_ELEMENT_TEXTURE_ID, mSharedElementSource.getTextureId());
+ mTransitionCompleteCallback.sendResult(bundle);
} catch (RemoteException e) {
Log.w(TAG, "Couldn't notify that the transition ended", e);
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 7efb3f1..9b3643c 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -63,7 +63,7 @@ import android.location.ILocationManager;
import android.location.LocationManager;
import android.media.AudioManager;
import android.media.MediaRouter;
-import android.media.MediaSessionManager;
+import android.media.session.MediaSessionManager;
import android.net.ConnectivityManager;
import android.net.IConnectivityManager;
import android.net.INetworkPolicyManager;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index d05d1a1..81a886a 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2352,10 +2352,10 @@ public abstract class Context {
/**
* Use with {@link #getSystemService} to retrieve a
- * {@link android.media.MediaSessionManager} for managing media Sessions.
+ * {@link android.media.session.MediaSessionManager} for managing media Sessions.
*
* @see #getSystemService
- * @see android.media.MediaSessionManager
+ * @see android.media.session.MediaSessionManager
*/
public static final String MEDIA_SESSION_SERVICE = "media_session";
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 25514f4..54d43d3 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -507,6 +507,17 @@ public class NetworkStats implements Parcelable {
}
/**
+ * Fast path for battery stats.
+ */
+ public long getTotalPackets() {
+ long total = 0;
+ for (int i = size-1; i >= 0; i--) {
+ total += rxPackets[i] + txPackets[i];
+ }
+ return total;
+ }
+
+ /**
* Subtract the given {@link NetworkStats}, effectively leaving the delta
* between two snapshots in time. Assumes that statistics rows collect over
* time, and that none of them have disappeared.
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index e91f7d7..bfce0c1 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -326,6 +326,8 @@ public abstract class BatteryStats implements Parcelable {
public abstract boolean hasNetworkActivity();
public abstract long getNetworkActivityBytes(int type, int which);
public abstract long getNetworkActivityPackets(int type, int which);
+ public abstract long getMobileRadioActiveTime(int which);
+ public abstract int getMobileRadioActiveCount(int which);
public static abstract class Sensor {
/*
@@ -899,6 +901,28 @@ public abstract class BatteryStats implements Parcelable {
*/
public abstract long getMobileRadioActiveTime(long batteryRealtime, int which);
+ /**
+ * Returns the number of times that the mobile network has transitioned to the
+ * active state.
+ *
+ * {@hide}
+ */
+ public abstract int getMobileRadioActiveCount(int which);
+
+ /**
+ * Returns the time in microseconds that the mobile network has been active
+ * (in a high power state) but not being able to blame on an app.
+ *
+ * {@hide}
+ */
+ public abstract long getMobileRadioActiveUnknownTime(int which);
+
+ /**
+ * Return count of number of times radio was app that could not be blamed on apps.
+ *
+ * {@hide}
+ */
+ public abstract int getMobileRadioActiveUnknownCount(int which);
public static final int DATA_CONNECTION_NONE = 0;
public static final int DATA_CONNECTION_GPRS = 1;
@@ -1238,6 +1262,13 @@ public abstract class BatteryStats implements Parcelable {
sb.append("ms ");
}
+ private final static void formatTimeMsNoSpace(StringBuilder sb, long time) {
+ long sec = time / 1000;
+ formatTimeRaw(sb, sec);
+ sb.append(time - (sec * 1000));
+ sb.append("ms");
+ }
+
private final String formatRatioLocked(long num, long den) {
if (den == 0L) {
return "--%";
@@ -1590,6 +1621,8 @@ public abstract class BatteryStats implements Parcelable {
long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
+ long mobileActiveTime = u.getMobileRadioActiveTime(which);
+ int mobileActiveCount = u.getMobileRadioActiveCount(which);
long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
@@ -1598,11 +1631,12 @@ public abstract class BatteryStats implements Parcelable {
if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0
|| mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0
- || wifiPacketsTx > 0) {
+ || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0) {
dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx,
wifiBytesRx, wifiBytesTx,
mobilePacketsRx, mobilePacketsTx,
- wifiPacketsRx, wifiPacketsTx);
+ wifiPacketsRx, wifiPacketsTx,
+ mobileActiveTime, mobileActiveCount);
}
if (fullWifiLockOnTime != 0 || wifiScanTime != 0
@@ -1932,9 +1966,9 @@ public abstract class BatteryStats implements Parcelable {
pw.print(", sent "); pw.print(wifiTxTotalPackets); pw.println(")");
sb.setLength(0);
sb.append(prefix);
- sb.append(" Total full wakelock time: "); formatTimeMs(sb,
+ sb.append(" Total full wakelock time: "); formatTimeMsNoSpace(sb,
(fullWakeLockTimeTotalMicros + 500) / 1000);
- sb.append(", Total partial wakelock time: "); formatTimeMs(sb,
+ sb.append(", Total partial wakelock time: "); formatTimeMsNoSpace(sb,
(partialWakeLockTimeTotalMicros + 500) / 1000);
pw.println(sb.toString());
@@ -1964,7 +1998,7 @@ public abstract class BatteryStats implements Parcelable {
sb.setLength(0);
sb.append(prefix);
sb.append(" Signal scanning time: ");
- formatTimeMs(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
+ formatTimeMsNoSpace(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
pw.println(sb.toString());
sb.setLength(0);
@@ -1993,9 +2027,26 @@ public abstract class BatteryStats implements Parcelable {
sb.setLength(0);
sb.append(prefix);
sb.append(" Mobile radio active time: ");
- formatTimeMs(sb, getMobileRadioActiveTime(batteryRealtime, which) / 1000);
+ final long mobileActiveTime = getMobileRadioActiveTime(batteryRealtime, which);
+ formatTimeMs(sb, mobileActiveTime / 1000);
+ sb.append("("); sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime));
+ sb.append(") "); sb.append(getMobileRadioActiveCount(which));
+ sb.append("x");
pw.println(sb.toString());
+ final long mobileActiveUnknownTime = getMobileRadioActiveUnknownTime(which);
+ if (mobileActiveUnknownTime != 0) {
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Mobile radio active unknown time: ");
+ formatTimeMs(sb, mobileActiveUnknownTime / 1000);
+ sb.append("(");
+ sb.append(formatRatioLocked(mobileActiveUnknownTime, whichBatteryRealtime));
+ sb.append(") "); sb.append(getMobileRadioActiveUnknownCount(which));
+ sb.append("x");
+ pw.println(sb.toString());
+ }
+
sb.setLength(0);
sb.append(prefix);
sb.append(" Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
@@ -2132,7 +2183,8 @@ public abstract class BatteryStats implements Parcelable {
pw.println();
break;
case APP:
- pw.print(prefix); pw.print(" Uid "); pw.print(bs.uidObj.getUid());
+ pw.print(prefix); pw.print(" Uid ");
+ UserHandle.formatUid(pw, bs.uidObj.getUid());
pw.print(": "); printmAh(pw, bs.value); pw.println();
break;
case USER:
@@ -2152,6 +2204,23 @@ public abstract class BatteryStats implements Parcelable {
pw.println();
}
+ sippers = helper.getMobilemsppList();
+ if (sippers != null && sippers.size() > 0) {
+ pw.print(prefix); pw.println(" Per-app mobile ms per packet:");
+ for (int i=0; i<sippers.size(); i++) {
+ BatterySipper bs = sippers.get(i);
+ sb.setLength(0);
+ sb.append(prefix); sb.append(" Uid ");
+ UserHandle.formatUid(sb, bs.uidObj.getUid());
+ sb.append(": "); sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp));
+ sb.append(" ("); sb.append(bs.mobileRxPackets+bs.mobileTxPackets);
+ sb.append(" packets over "); formatTimeMsNoSpace(sb, bs.mobileActive);
+ sb.append(")");
+ pw.println(sb.toString());
+ }
+ pw.println();
+ }
+
if (timers.size() > 0) {
Collections.sort(timers, timerComparator);
pw.print(prefix); pw.println(" All partial wake locks:");
@@ -2183,13 +2252,15 @@ public abstract class BatteryStats implements Parcelable {
UserHandle.formatUid(pw, uid);
pw.println(":");
boolean uidActivity = false;
-
+
long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
+ long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
+ int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
@@ -2204,6 +2275,23 @@ public abstract class BatteryStats implements Parcelable {
pw.print(" sent (packets "); pw.print(mobileRxPackets);
pw.print(" received, "); pw.print(mobileTxPackets); pw.println(" sent)");
}
+ if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) {
+ sb.setLength(0);
+ sb.append(prefix); sb.append(" Mobile radio active: ");
+ formatTimeMs(sb, uidMobileActiveTime / 1000);
+ sb.append("(");
+ sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime));
+ sb.append(") "); sb.append(uidMobileActiveCount); sb.append("x");
+ long packets = mobileRxPackets + mobileTxPackets;
+ if (packets == 0) {
+ packets = 1;
+ }
+ sb.append(" @ ");
+ sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double)packets));
+ sb.append(" mspp");
+ pw.println(sb.toString());
+ }
+
if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) {
pw.print(prefix); pw.print(" Wi-Fi network: ");
pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, ");
@@ -2212,6 +2300,24 @@ public abstract class BatteryStats implements Parcelable {
pw.print(" received, "); pw.print(wifiTxPackets); pw.println(" sent)");
}
+ if (fullWifiLockOnTime != 0 || wifiScanTime != 0
+ || uidWifiRunningTime != 0) {
+ sb.setLength(0);
+ sb.append(prefix); sb.append(" Wifi Running: ");
+ formatTimeMs(sb, uidWifiRunningTime / 1000);
+ sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
+ whichBatteryRealtime)); sb.append(")\n");
+ sb.append(prefix); sb.append(" Full Wifi Lock: ");
+ formatTimeMs(sb, fullWifiLockOnTime / 1000);
+ sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
+ whichBatteryRealtime)); sb.append(")\n");
+ sb.append(prefix); sb.append(" Wifi Scan: ");
+ formatTimeMs(sb, wifiScanTime / 1000);
+ sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
+ whichBatteryRealtime)); sb.append(")");
+ pw.println(sb.toString());
+ }
+
if (u.hasUserActivity()) {
boolean hasData = false;
for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
@@ -2233,24 +2339,6 @@ public abstract class BatteryStats implements Parcelable {
pw.println(sb.toString());
}
}
-
- if (fullWifiLockOnTime != 0 || wifiScanTime != 0
- || uidWifiRunningTime != 0) {
- sb.setLength(0);
- sb.append(prefix); sb.append(" Wifi Running: ");
- formatTimeMs(sb, uidWifiRunningTime / 1000);
- sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
- whichBatteryRealtime)); sb.append(")\n");
- sb.append(prefix); sb.append(" Full Wifi Lock: ");
- formatTimeMs(sb, fullWifiLockOnTime / 1000);
- sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
- whichBatteryRealtime)); sb.append(")\n");
- sb.append(prefix); sb.append(" Wifi Scan: ");
- formatTimeMs(sb, wifiScanTime / 1000);
- sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
- whichBatteryRealtime)); sb.append(")");
- pw.println(sb.toString());
- }
Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
if (wakelocks.size() > 0) {
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index 9f1e72d..fd3f9b3 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -552,7 +552,8 @@ public abstract class Transition implements Cloneable {
return false;
}
- private static ArrayMap<Animator, AnimationInfo> getRunningAnimators() {
+ /** @hide */
+ public static ArrayMap<Animator, AnimationInfo> getRunningAnimators() {
ArrayMap<Animator, AnimationInfo> runningAnimators = sRunningAnimators.get();
if (runningAnimators == null) {
runningAnimators = new ArrayMap<Animator, AnimationInfo>();
@@ -1112,32 +1113,30 @@ public abstract class Transition implements Cloneable {
}
}
}
- if (view.getParent() instanceof ViewGroup) {
- TransitionValues values = new TransitionValues();
- values.view = view;
- if (start) {
- captureStartValues(values);
+ TransitionValues values = new TransitionValues();
+ values.view = view;
+ if (start) {
+ captureStartValues(values);
+ } else {
+ captureEndValues(values);
+ }
+ if (start) {
+ if (!isListViewItem) {
+ mStartValues.viewValues.put(view, values);
+ if (id >= 0) {
+ mStartValues.idValues.put((int) id, values);
+ }
} else {
- captureEndValues(values);
+ mStartValues.itemIdValues.put(itemId, values);
}
- if (start) {
- if (!isListViewItem) {
- mStartValues.viewValues.put(view, values);
- if (id >= 0) {
- mStartValues.idValues.put((int) id, values);
- }
- } else {
- mStartValues.itemIdValues.put(itemId, values);
+ } else {
+ if (!isListViewItem) {
+ mEndValues.viewValues.put(view, values);
+ if (id >= 0) {
+ mEndValues.idValues.put((int) id, values);
}
} else {
- if (!isListViewItem) {
- mEndValues.viewValues.put(view, values);
- if (id >= 0) {
- mEndValues.idValues.put((int) id, values);
- }
- } else {
- mEndValues.itemIdValues.put(itemId, values);
- }
+ mEndValues.itemIdValues.put(itemId, values);
}
}
if (view instanceof ViewGroup) {
diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
index 912f2ed..9fa554c 100644
--- a/core/java/android/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -285,27 +285,46 @@ public class TransitionInflater {
com.android.internal.R.styleable.TransitionManager);
int transitionId = a.getResourceId(
com.android.internal.R.styleable.TransitionManager_transition, -1);
+ Scene fromScene = null, toScene = null;
int fromId = a.getResourceId(
com.android.internal.R.styleable.TransitionManager_fromScene, -1);
- Scene fromScene = (fromId < 0) ? null: Scene.getSceneForLayout(sceneRoot, fromId, mContext);
+ if (fromId >= 0) fromScene = Scene.getSceneForLayout(sceneRoot, fromId, mContext);
int toId = a.getResourceId(
com.android.internal.R.styleable.TransitionManager_toScene, -1);
- Scene toScene = (toId < 0) ? null : Scene.getSceneForLayout(sceneRoot, toId, mContext);
-
+ if (toId >= 0) toScene = Scene.getSceneForLayout(sceneRoot, toId, mContext);
+ String fromName = a.getString(
+ com.android.internal.R.styleable.TransitionManager_fromSceneName);
+ String toName = a.getString(
+ com.android.internal.R.styleable.TransitionManager_toSceneName);
if (transitionId >= 0) {
Transition transition = inflateTransition(transitionId);
if (transition != null) {
- if (fromScene == null) {
- if (toScene == null) {
- throw new RuntimeException("No matching fromScene or toScene " +
- "for transition ID " + transitionId);
+ if (fromScene != null) {
+ boolean hasDest = false;
+ if (toScene != null) {
+ transitionManager.setTransition(fromScene, toScene, transition);
+ hasDest = true;
+ }
+
+ if (!TextUtils.isEmpty(toName)) {
+ transitionManager.setTransition(fromScene, toName, transition);
+ hasDest = true;
+ }
+
+ if (!hasDest) {
+ throw new RuntimeException("No matching toScene or toSceneName for given " +
+ "fromScene for transition ID " + transitionId);
+ }
+ } else if (toId >= 0) {
+ transitionManager.setTransition(toScene, transition);
+ }
+ if (fromName != null) {
+ if (toScene != null) {
+ transitionManager.setTransition(fromName, toScene, transition);
} else {
- transitionManager.setTransition(toScene, transition);
+ throw new RuntimeException("No matching toScene for given fromSceneName " +
+ "for transition ID " + transitionId);
}
- } else if (toScene == null) {
- transitionManager.setExitTransition(fromScene, transition);
- } else {
- transitionManager.setTransition(fromScene, toScene, transition);
}
}
}
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index f3abfb0..0106f7f 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -70,9 +70,12 @@ public class TransitionManager {
private static final String[] EMPTY_STRINGS = new String[0];
ArrayMap<Scene, Transition> mSceneTransitions = new ArrayMap<Scene, Transition>();
- ArrayMap<Scene, Transition> mExitSceneTransitions = new ArrayMap<Scene, Transition>();
ArrayMap<Scene, ArrayMap<Scene, Transition>> mScenePairTransitions =
new ArrayMap<Scene, ArrayMap<Scene, Transition>>();
+ ArrayMap<Scene, ArrayMap<String, Transition>> mSceneNameTransitions =
+ new ArrayMap<Scene, ArrayMap<String, Transition>>();
+ ArrayMap<String, ArrayMap<Scene, Transition>> mNameSceneTransitions =
+ new ArrayMap<String, ArrayMap<Scene, Transition>>();
private static ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>>
sRunningTransitions =
new ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>>();
@@ -119,21 +122,6 @@ public class TransitionManager {
}
/**
- * Sets a specific transition to occur when the given scene is exited. This
- * has the lowest priority -- if a Scene-to-Scene transition or
- * Scene enter transition can be applied, it will.
- *
- * @param scene The scene which, when exited, will cause the given
- * transition to run.
- * @param transition The transition that will play when the given scene is
- * exited. A value of null will result in the default behavior of
- * using the default transition instead.
- */
- public void setExitTransition(Scene scene, Transition transition) {
- mExitSceneTransitions.put(scene, transition);
- }
-
- /**
* Sets a specific transition to occur when the given pair of scenes is
* exited/entered.
*
@@ -181,9 +169,6 @@ public class TransitionManager {
}
}
transition = mSceneTransitions.get(scene);
- if (transition == null && sceneRoot != null) {
- transition = mExitSceneTransitions.get(Scene.getCurrentScene(sceneRoot));
- }
return (transition != null) ? transition : sDefaultTransition;
}
@@ -239,31 +224,138 @@ public class TransitionManager {
}
/**
- * Retrieve the transition to a target defined scene if one has been
+ * Retrieve the transition from a named scene to a target defined scene if one has been
* associated with this TransitionManager.
*
+ * <p>A named scene is an indirect link for a transition. Fundamentally a named
+ * scene represents a potentially arbitrary intersection point of two otherwise independent
+ * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
+ * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
+ * In this way applications may define an API for more sophisticated transitions between
+ * caller and called activities very similar to the way that <code>Intent</code> extras
+ * define APIs for arguments and data propagation between activities.</p>
+ *
+ * @param fromName Named scene that this transition corresponds to
* @param toScene Target scene that this transition will move to
- * @return Transition corresponding to the given toScene or null
+ * @return Transition corresponding to the given fromName and toScene or null
* if no association exists in this TransitionManager
*
- * @see #setTransition(Scene, Transition)
- * @hide
+ * @see #setTransition(String, Scene, Transition)
*/
- public Transition getEnterTransition(Scene toScene) {
- return mSceneTransitions.get(toScene);
+ public Transition getNamedTransition(String fromName, Scene toScene) {
+ ArrayMap<Scene, Transition> m = mNameSceneTransitions.get(fromName);
+ if (m != null) {
+ return m.get(toScene);
+ }
+ return null;
}
/**
* Retrieve the transition from a defined scene to a target named scene if one has been
* associated with this TransitionManager.
*
+ * <p>A named scene is an indirect link for a transition. Fundamentally a named
+ * scene represents a potentially arbitrary intersection point of two otherwise independent
+ * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
+ * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
+ * In this way applications may define an API for more sophisticated transitions between
+ * caller and called activities very similar to the way that <code>Intent</code> extras
+ * define APIs for arguments and data propagation between activities.</p>
+ *
* @param fromScene Scene that this transition starts from
- * @return Transition corresponding to the given fromScene or null
+ * @param toName Name of the target scene
+ * @return Transition corresponding to the given fromScene and toName or null
* if no association exists in this TransitionManager
- * @hide
*/
- public Transition getExitTransition(Scene fromScene) {
- return mExitSceneTransitions.get(fromScene);
+ public Transition getNamedTransition(Scene fromScene, String toName) {
+ ArrayMap<String, Transition> m = mSceneNameTransitions.get(fromScene);
+ if (m != null) {
+ return m.get(toName);
+ }
+ return null;
+ }
+
+ /**
+ * Retrieve the supported target named scenes when transitioning away from the given scene.
+ *
+ * <p>A named scene is an indirect link for a transition. Fundamentally a named
+ * scene represents a potentially arbitrary intersection point of two otherwise independent
+ * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
+ * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
+ * In this way applications may define an API for more sophisticated transitions between
+ * caller and called activities very similar to the way that <code>Intent</code> extras
+ * define APIs for arguments and data propagation between activities.</p>
+ *
+ * @param fromScene Scene to transition from
+ * @return An array of Strings naming each supported transition starting from
+ * <code>fromScene</code>. If no transitions to a named scene from the given
+ * scene are supported this function will return a String[] of length 0.
+ *
+ * @see #setTransition(Scene, String, Transition)
+ */
+ public String[] getTargetSceneNames(Scene fromScene) {
+ final ArrayMap<String, Transition> m = mSceneNameTransitions.get(fromScene);
+ if (m == null) {
+ return EMPTY_STRINGS;
+ }
+ final int count = m.size();
+ final String[] result = new String[count];
+ for (int i = 0; i < count; i++) {
+ result[i] = m.keyAt(i);
+ }
+ return result;
+ }
+
+ /**
+ * Set a transition from a specific scene to a named scene.
+ *
+ * <p>A named scene is an indirect link for a transition. Fundamentally a named
+ * scene represents a potentially arbitrary intersection point of two otherwise independent
+ * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
+ * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
+ * In this way applications may define an API for more sophisticated transitions between
+ * caller and called activities very similar to the way that <code>Intent</code> extras
+ * define APIs for arguments and data propagation between activities.</p>
+ *
+ * @param fromScene Scene to transition from
+ * @param toName Named scene to transition to
+ * @param transition Transition to use
+ *
+ * @see #getTargetSceneNames(Scene)
+ */
+ public void setTransition(Scene fromScene, String toName, Transition transition) {
+ ArrayMap<String, Transition> m = mSceneNameTransitions.get(fromScene);
+ if (m == null) {
+ m = new ArrayMap<String, Transition>();
+ mSceneNameTransitions.put(fromScene, m);
+ }
+ m.put(toName, transition);
+ }
+
+ /**
+ * Set a transition from a named scene to a concrete scene.
+ *
+ * <p>A named scene is an indirect link for a transition. Fundamentally a named
+ * scene represents a potentially arbitrary intersection point of two otherwise independent
+ * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
+ * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
+ * In this way applications may define an API for more sophisticated transitions between
+ * caller and called activities very similar to the way that <code>Intent</code> extras
+ * define APIs for arguments and data propagation between activities.</p>
+ *
+ * @param fromName Named scene to transition from
+ * @param toScene Scene to transition to
+ * @param transition Transition to use
+ *
+ * @see #getNamedTransition(String, Scene)
+ */
+ public void setTransition(String fromName, Scene toScene, Transition transition) {
+ ArrayMap<Scene, Transition> m = mNameSceneTransitions.get(fromName);
+ if (m == null) {
+ m = new ArrayMap<Scene, Transition>();
+ mNameSceneTransitions.put(fromName, m);
+ }
+ m.put(toScene, transition);
}
/**
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 5a8d2c8..e693b9e 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -167,6 +167,13 @@ public class SurfaceControl {
public static final int FX_SURFACE_DIM = 0x00020000;
/**
+ * Surface creation flag: Creates a video plane Surface.
+ * This surface is backed by a hardware video plane. It is an error to lock
+ * a video plane surface, since it doesn't have a backing store.
+ */
+ public static final int FX_SURFACE_VIDEO_PLANE = 0x00040000;
+
+ /**
* Mask used for FX values above.
*
*/
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 65d3f6d..9b23b35 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -421,7 +421,10 @@ public class SurfaceView extends View {
mWindowType = type;
}
- private void updateWindow(boolean force, boolean redrawNeeded) {
+ /**
+ * @hide
+ */
+ protected void updateWindow(boolean force, boolean redrawNeeded) {
if (!mHaveFrame) {
return;
}
diff --git a/core/java/android/view/VideoPlaneView.java b/core/java/android/view/VideoPlaneView.java
new file mode 100644
index 0000000..81dcf9d
--- /dev/null
+++ b/core/java/android/view/VideoPlaneView.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+/**
+ * Provides a dedicated surface embedded inside of a view hierarchy much like a
+ * {@link SurfaceView}, but the surface is actually backed by a hardware video
+ * plane.
+ *
+ * TODO: Eventually this should be separate from SurfaceView.
+ *
+ * @hide
+ */
+public class VideoPlaneView extends SurfaceView {
+ public VideoPlaneView(Context context) {
+ super(context);
+ }
+
+ public VideoPlaneView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public VideoPlaneView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public VideoPlaneView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ @Override
+ protected void updateWindow(boolean force, boolean redrawNeeded) {
+ mLayout.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_VIDEO_PLANE;
+ super.updateWindow(force, redrawNeeded);
+ }
+}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 99aee29..e9082c3 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -101,9 +101,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
-import java.util.List;
import java.util.Locale;
-import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
@@ -18844,33 +18842,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
}
- /**
- * Gets the Views in the hierarchy affected by entering and exiting Activity Scene transitions.
- * @param transitioningViews This View will be added to transitioningViews if it is VISIBLE and
- * a normal View or a ViewGroup with
- * {@link android.view.ViewGroup#isTransitionGroup()} true.
- * @hide
- */
- public void captureTransitioningViews(List<View> transitioningViews) {
- if (getVisibility() == View.VISIBLE) {
- transitioningViews.add(this);
- }
- }
-
- /**
- * Adds all Views that have {@link #getSharedElementName()} non-null to sharedElements.
- * @param sharedElements Will contain all Views in the hierarchy having a shared element name.
- * @hide
- */
- public void findSharedElements(Map<String, View> sharedElements) {
- if (getVisibility() == VISIBLE) {
- String sharedElementName = getSharedElementName();
- if (sharedElementName != null) {
- sharedElements.put(sharedElementName, this);
- }
- }
- }
-
//
// Properties
//
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index cf5e8cf..9cd3c9d 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -31,7 +31,6 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.os.Build;
-import android.os.Bundle;
import android.os.Parcelable;
import android.os.SystemClock;
import android.util.AttributeSet;
@@ -51,8 +50,6 @@ import com.android.internal.util.Predicate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
@@ -2303,13 +2300,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* individually during the transition.
* @return True if the ViewGroup should be acted on together during an Activity transition.
* The default value is false when the background is null and true when the background
- * is not null or if {@link #getSharedElementName()} is not null.
+ * is not null.
+ * @see android.app.ActivityOptions#makeSceneTransitionAnimation(android.os.Bundle)
*/
public boolean isTransitionGroup() {
if ((mGroupFlags & FLAG_IS_TRANSITION_GROUP_SET) != 0) {
return ((mGroupFlags & FLAG_IS_TRANSITION_GROUP) != 0);
} else {
- return getBackground() != null || getSharedElementName() != null;
+ return getBackground() != null;
}
}
@@ -2320,6 +2318,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* in Activity transitions. If false, the ViewGroup won't transition,
* only its children. If true, the entire ViewGroup will transition
* together.
+ * @see android.app.ActivityOptions#makeSceneTransitionAnimation(android.os.Bundle)
*/
public void setTransitionGroup(boolean isTransitionGroup) {
mGroupFlags |= FLAG_IS_TRANSITION_GROUP_SET;
@@ -5881,37 +5880,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
protected void onSetLayoutParams(View child, LayoutParams layoutParams) {
}
- /** @hide */
- @Override
- public void captureTransitioningViews(List<View> transitioningViews) {
- if (getVisibility() != View.VISIBLE) {
- return;
- }
- if (isTransitionGroup()) {
- transitioningViews.add(this);
- } else {
- int count = getChildCount();
- for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
- child.captureTransitioningViews(transitioningViews);
- }
- }
- }
-
- /** @hide */
- @Override
- public void findSharedElements(Map<String, View> sharedElements) {
- if (getVisibility() != VISIBLE) {
- return;
- }
- super.findSharedElements(sharedElements);
- int count = getChildCount();
- for (int i = 0; i < count; i++) {
- View child = getChildAt(i);
- child.findSharedElements(sharedElements);
- }
- }
-
/**
* LayoutParams are used by views to tell their parents how they want to be
* laid out. See
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 4943a40..11740ab 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -29,12 +29,9 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.SystemProperties;
import android.transition.Scene;
-import android.transition.Transition;
import android.transition.TransitionManager;
import android.view.accessibility.AccessibilityEvent;
-import java.util.Map;
-
/**
* Abstract base class for a top-level window look and behavior policy. An
* instance of this class should be used as the top-level view added to the
@@ -1389,43 +1386,30 @@ public abstract class Window {
* @hide
*/
public interface SceneTransitionListener {
+ void enterSharedElement(Bundle transitionArgs);
void nullPendingTransition();
void convertFromTranslucent();
void convertToTranslucent();
- void sharedElementStart(Transition transition);
- void sharedElementEnd();
}
/**
- * Controls when the Activity enter scene is triggered and the background is faded in. If
- * triggerEarly is true, the enter scene will begin as soon as possible and the background
- * will fade in when all shared elements are ready to begin transitioning. If triggerEarly is
- * false, the Activity enter scene and background fade will be triggered when the calling
- * Activity's exit transition completes.
+ * Controls how the background fade is triggered. If fadeEarly is true, the Window background
+ * will fade in as soon as the shared elements are ready to switch. If fadeEarly is false,
+ * the background will fade only after the calling Activity's exit transition completes.
+ * By default, the Window will fade in when the calling Activity's exit transition completes.
*
- * @param triggerEarly Set to true to have the Activity enter scene transition in as early as
- * possible or set to false to wait for the calling Activity to exit first.
+ * @param fadeEarly Set to true to fade out the exiting Activity as soon as the shared elements
+ * are transferred. Set to false to fade out the exiting Activity as soon as
+ * the shared element is transferred.
+ * @hide
*/
- public void setTriggerEarlyEnterTransition(boolean triggerEarly) {
+ public void setEarlyBackgroundTransition(boolean fadeEarly) {
}
/**
* Start the exit transition.
* @hide
*/
- public Bundle startExitTransition(Map<String, View> sharedElements) {
- return null;
- }
-
- /**
- * On entering Activity Scene transitions, shared element names may be mapped from a
- * source Activity's specified name to a unique shared element name in the View hierarchy.
- * Under most circumstances, mapping is not necessary - a single View will have the
- * shared element name given by the calling Activity. However, if there are several similar
- * Views (e.g. in a ListView), the correct shared element must be mapped.
- * @param sharedElementNames A mapping from the calling Activity's assigned shared element
- * name to a unique shared element name in the View hierarchy.
- */
- public void mapTransitionTargets(Map<String, String> sharedElementNames) {
+ public void startExitTransition(ActivityOptions activityOptions) {
}
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 53a4c0d0..55956bf 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -98,7 +98,7 @@ public interface WindowManager extends ViewManager {
* the given view hierarchy's {@link View#onDetachedFromWindow()
* View.onDetachedFromWindow()} methods before returning. This is not
* for normal applications; using it correctly requires great care.
- *
+ *
* @param view The view to be removed.
*/
public void removeViewImmediate(View view);
@@ -112,7 +112,7 @@ public interface WindowManager extends ViewManager {
*/
@ViewDebug.ExportedProperty
public int x;
-
+
/**
* Y position for this window. With the default gravity it is ignored.
* When using {@link Gravity#TOP} or {@link Gravity#BOTTOM} it provides
@@ -161,7 +161,7 @@ public interface WindowManager extends ViewManager {
* be used by applications, and a special permission is required
* to use them.
* </ul>
- *
+ *
* @see #TYPE_BASE_APPLICATION
* @see #TYPE_APPLICATION
* @see #TYPE_APPLICATION_STARTING
@@ -223,12 +223,12 @@ public interface WindowManager extends ViewManager {
@ViewDebug.IntToString(from = TYPE_PRIVATE_PRESENTATION, to = "TYPE_PRIVATE_PRESENTATION")
})
public int type;
-
+
/**
* Start of window types that represent normal application windows.
*/
public static final int FIRST_APPLICATION_WINDOW = 1;
-
+
/**
* Window type: an application window that serves as the "base" window
* of the overall application; all other application windows will
@@ -236,14 +236,14 @@ public interface WindowManager extends ViewManager {
* In multiuser systems shows only on the owning user's window.
*/
public static final int TYPE_BASE_APPLICATION = 1;
-
+
/**
* Window type: a normal application window. The {@link #token} must be
* an Activity token identifying who the window belongs to.
* In multiuser systems shows only on the owning user's window.
*/
public static final int TYPE_APPLICATION = 2;
-
+
/**
* Window type: special application window that is displayed while the
* application is starting. Not for use by applications themselves;
@@ -252,12 +252,12 @@ public interface WindowManager extends ViewManager {
* In multiuser systems shows on all users' windows.
*/
public static final int TYPE_APPLICATION_STARTING = 3;
-
+
/**
* End of types of application windows.
*/
public static final int LAST_APPLICATION_WINDOW = 99;
-
+
/**
* Start of types of sub-windows. The {@link #token} of these windows
* must be set to the window they are attached to. These types of
@@ -265,19 +265,19 @@ public interface WindowManager extends ViewManager {
* coordinate space is relative to their attached window.
*/
public static final int FIRST_SUB_WINDOW = 1000;
-
+
/**
* Window type: a panel on top of an application window. These windows
* appear on top of their attached window.
*/
public static final int TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW;
-
+
/**
* Window type: window for showing media (such as video). These windows
* are displayed behind their attached window.
*/
public static final int TYPE_APPLICATION_MEDIA = FIRST_SUB_WINDOW+1;
-
+
/**
* Window type: a sub-panel on top of an application window. These
* windows are displayed on top their attached window and any
@@ -290,7 +290,7 @@ public interface WindowManager extends ViewManager {
* as a child of its container.
*/
public static final int TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW+3;
-
+
/**
* Window type: window for showing overlays on top of media windows.
* These windows are displayed between TYPE_APPLICATION_MEDIA and the
@@ -299,18 +299,18 @@ public interface WindowManager extends ViewManager {
* @hide
*/
public static final int TYPE_APPLICATION_MEDIA_OVERLAY = FIRST_SUB_WINDOW+4;
-
+
/**
* End of types of sub-windows.
*/
public static final int LAST_SUB_WINDOW = 1999;
-
+
/**
* Start of system-specific window types. These are not normally
* created by applications.
*/
public static final int FIRST_SYSTEM_WINDOW = 2000;
-
+
/**
* Window type: the status bar. There can be only one status bar
* window; it is placed at the top of the screen, and all other
@@ -318,14 +318,14 @@ public interface WindowManager extends ViewManager {
* In multiuser systems shows on all users' windows.
*/
public static final int TYPE_STATUS_BAR = FIRST_SYSTEM_WINDOW;
-
+
/**
* Window type: the search bar. There can be only one search bar
* window; it is placed at the top of the screen.
* In multiuser systems shows on all users' windows.
*/
public static final int TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW+1;
-
+
/**
* Window type: phone. These are non-application windows providing
* user interaction with the phone (in particular incoming calls).
@@ -334,26 +334,26 @@ public interface WindowManager extends ViewManager {
* In multiuser systems shows on all users' windows.
*/
public static final int TYPE_PHONE = FIRST_SYSTEM_WINDOW+2;
-
+
/**
* Window type: system window, such as low power alert. These windows
* are always on top of application windows.
* In multiuser systems shows only on the owning user's window.
*/
public static final int TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW+3;
-
+
/**
* Window type: keyguard window.
* In multiuser systems shows on all users' windows.
*/
public static final int TYPE_KEYGUARD = FIRST_SYSTEM_WINDOW+4;
-
+
/**
* Window type: transient notifications.
* In multiuser systems shows only on the owning user's window.
*/
public static final int TYPE_TOAST = FIRST_SYSTEM_WINDOW+5;
-
+
/**
* Window type: system overlay windows, which need to be displayed
* on top of everything else. These windows must not take input
@@ -361,7 +361,7 @@ public interface WindowManager extends ViewManager {
* In multiuser systems shows only on the owning user's window.
*/
public static final int TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+6;
-
+
/**
* Window type: priority phone UI, which needs to be displayed even if
* the keyguard is active. These windows must not take input
@@ -369,26 +369,26 @@ public interface WindowManager extends ViewManager {
* In multiuser systems shows on all users' windows.
*/
public static final int TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW+7;
-
+
/**
* Window type: panel that slides out from the status bar
* In multiuser systems shows on all users' windows.
*/
public static final int TYPE_SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW+8;
-
+
/**
* Window type: dialogs that the keyguard shows
* In multiuser systems shows on all users' windows.
*/
public static final int TYPE_KEYGUARD_DIALOG = FIRST_SYSTEM_WINDOW+9;
-
+
/**
* Window type: internal system error windows, appear on top of
* everything they can.
* In multiuser systems shows only on the owning user's window.
*/
public static final int TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW+10;
-
+
/**
* Window type: internal input methods windows, which appear above
* the normal UI. Application windows may be resized or panned to keep
@@ -559,16 +559,16 @@ public interface WindowManager extends ViewManager {
/** @deprecated this is ignored, this value is set automatically when needed. */
@Deprecated
public static final int MEMORY_TYPE_PUSH_BUFFERS = 3;
-
+
/**
* @deprecated this is ignored
*/
@Deprecated
public int memoryType;
-
+
/** Window flag: as long as this window is visible to the user, allow
- * the lock screen to activate while the screen is on.
- * This can be used independently, or in combination with
+ * the lock screen to activate while the screen is on.
+ * This can be used independently, or in combination with
* {@link #FLAG_KEEP_SCREEN_ON} and/or {@link #FLAG_SHOW_WHEN_LOCKED} */
public static final int FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001;
@@ -586,47 +586,47 @@ public interface WindowManager extends ViewManager {
* instead go to whatever focusable window is behind it. This flag
* will also enable {@link #FLAG_NOT_TOUCH_MODAL} whether or not that
* is explicitly set.
- *
+ *
* <p>Setting this flag also implies that the window will not need to
* interact with
- * a soft input method, so it will be Z-ordered and positioned
+ * a soft input method, so it will be Z-ordered and positioned
* independently of any active input method (typically this means it
* gets Z-ordered on top of the input method, so it can use the full
* screen for its content and cover the input method if needed. You
* can use {@link #FLAG_ALT_FOCUSABLE_IM} to modify this behavior. */
public static final int FLAG_NOT_FOCUSABLE = 0x00000008;
-
+
/** Window flag: this window can never receive touch events. */
public static final int FLAG_NOT_TOUCHABLE = 0x00000010;
-
+
/** Window flag: even when this window is focusable (its
* {@link #FLAG_NOT_FOCUSABLE} is not set), allow any pointer events
* outside of the window to be sent to the windows behind it. Otherwise
* it will consume all pointer events itself, regardless of whether they
* are inside of the window. */
public static final int FLAG_NOT_TOUCH_MODAL = 0x00000020;
-
+
/** Window flag: when set, if the device is asleep when the touch
* screen is pressed, you will receive this first touch event. Usually
* the first touch event is consumed by the system since the user can
* not see what they are pressing on.
*/
public static final int FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040;
-
+
/** Window flag: as long as this window is visible to the user, keep
* the device's screen turned on and bright. */
public static final int FLAG_KEEP_SCREEN_ON = 0x00000080;
-
+
/** Window flag: place the window within the entire screen, ignoring
* decorations around the border (such as the status bar). The
* window must correctly position its contents to take the screen
* decoration into account. This flag is normally set for you
* by Window as described in {@link Window#setFlags}. */
public static final int FLAG_LAYOUT_IN_SCREEN = 0x00000100;
-
+
/** Window flag: allow window to extend outside of the screen. */
public static final int FLAG_LAYOUT_NO_LIMITS = 0x00000200;
-
+
/**
* Window flag: hide all screen decorations (such as the status bar) while
* this window is displayed. This allows the window to use the entire
@@ -648,17 +648,17 @@ public interface WindowManager extends ViewManager {
* {@link android.R.style#Theme_DeviceDefault_Light_NoActionBar_Fullscreen}.</p>
*/
public static final int FLAG_FULLSCREEN = 0x00000400;
-
+
/** Window flag: override {@link #FLAG_FULLSCREEN} and force the
* screen decorations (such as the status bar) to be shown. */
public static final int FLAG_FORCE_NOT_FULLSCREEN = 0x00000800;
-
+
/** Window flag: turn on dithering when compositing this window to
* the screen.
* @deprecated This flag is no longer used. */
@Deprecated
public static final int FLAG_DITHER = 0x00001000;
-
+
/** Window flag: treat the content of the window as secure, preventing
* it from appearing in screenshots or from being viewed on non-secure
* displays.
@@ -667,21 +667,21 @@ public interface WindowManager extends ViewManager {
* secure surfaces and secure displays.
*/
public static final int FLAG_SECURE = 0x00002000;
-
+
/** Window flag: a special mode where the layout parameters are used
* to perform scaling of the surface when it is composited to the
* screen. */
public static final int FLAG_SCALED = 0x00004000;
-
+
/** Window flag: intended for windows that will often be used when the user is
* holding the screen against their face, it will aggressively filter the event
* stream to prevent unintended presses in this situation that may not be
- * desired for a particular window, when such an event stream is detected, the
+ * desired for a particular window, when such an event stream is detected, the
* application will receive a CANCEL motion event to indicate this so applications
- * can handle this accordingly by taking no action on the event
+ * can handle this accordingly by taking no action on the event
* until the finger is released. */
public static final int FLAG_IGNORE_CHEEK_PRESSES = 0x00008000;
-
+
/** Window flag: a special option only for use in combination with
* {@link #FLAG_LAYOUT_IN_SCREEN}. When requesting layout in the
* screen your window may appear on top of or behind screen decorations
@@ -690,7 +690,7 @@ public interface WindowManager extends ViewManager {
* content is not covered by screen decorations. This flag is normally
* set for you by Window as described in {@link Window#setFlags}.*/
public static final int FLAG_LAYOUT_INSET_DECOR = 0x00010000;
-
+
/** Window flag: invert the state of {@link #FLAG_NOT_FOCUSABLE} with
* respect to how this window interacts with the current method. That
* is, if FLAG_NOT_FOCUSABLE is set and this flag is set, then the
@@ -701,7 +701,7 @@ public interface WindowManager extends ViewManager {
* to use more space and cover the input method.
*/
public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000;
-
+
/** Window flag: if you have set {@link #FLAG_NOT_TOUCH_MODAL}, you
* can set this flag to receive a single special MotionEvent with
* the action
@@ -711,7 +711,7 @@ public interface WindowManager extends ViewManager {
* first down as an ACTION_OUTSIDE.
*/
public static final int FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000;
-
+
/** Window flag: special flag to let windows be shown when the screen
* is locked. This will let application windows take precedence over
* key guard or any other lock screens. Can be used with
@@ -741,13 +741,13 @@ public interface WindowManager extends ViewManager {
* {@link android.R.style#Theme_DeviceDefault_Wallpaper_NoTitleBar}.</p>
*/
public static final int FLAG_SHOW_WALLPAPER = 0x00100000;
-
+
/** Window flag: when set as a window is being added or made
* visible, once the window has been shown then the system will
* poke the power manager's user activity (as if the user had woken
* up the device) to turn the screen on. */
public static final int FLAG_TURN_SCREEN_ON = 0x00200000;
-
+
/** Window flag: when set the window will cause the keyguard to
* be dismissed, only if it is not a secure lock keyguard. Because such
* a keyguard is not needed for security, it will never re-appear if
@@ -761,7 +761,7 @@ public interface WindowManager extends ViewManager {
* also been set.
*/
public static final int FLAG_DISMISS_KEYGUARD = 0x00400000;
-
+
/** Window flag: when set the window will accept for touch events
* outside of its bounds to be sent to other windows that also
* support split touch. When this flag is not set, the first pointer
@@ -773,7 +773,7 @@ public interface WindowManager extends ViewManager {
* to be split across multiple windows.
*/
public static final int FLAG_SPLIT_TOUCH = 0x00800000;
-
+
/**
* <p>Indicates whether this window should be hardware accelerated.
* Requesting hardware acceleration does not guarantee it will happen.</p>
@@ -916,7 +916,7 @@ public interface WindowManager extends ViewManager {
/**
* Various behavioral options/flags. Default is none.
- *
+ *
* @see #FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
* @see #FLAG_DIM_BEHIND
* @see #FLAG_NOT_FOCUSABLE
@@ -1014,10 +1014,10 @@ public interface WindowManager extends ViewManager {
* as if it was.
* Like {@link #FLAG_HARDWARE_ACCELERATED} except for trusted system windows
* that need hardware acceleration (e.g. LockScreen), where hardware acceleration
- * is generally disabled. This flag must be specified in addition to
+ * is generally disabled. This flag must be specified in addition to
* {@link #FLAG_HARDWARE_ACCELERATED} to enable hardware acceleration for system
* windows.
- *
+ *
* @hide
*/
public static final int PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED = 0x00000001;
@@ -1028,7 +1028,7 @@ public interface WindowManager extends ViewManager {
* If certain parts of the UI that really do want to use hardware
* acceleration, this flag can be set to force it. This is basically
* for the lock screen. Anyone else using it, you are probably wrong.
- *
+ *
* @hide
*/
public static final int PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED = 0x00000002;
@@ -1086,6 +1086,11 @@ public interface WindowManager extends ViewManager {
* {@hide} */
public static final int PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR = 0x00000200;
+ /** Window flag: the window is backed by a video plane, instead of a
+ * regular surface.
+ * {@hide} */
+ public static final int PRIVATE_FLAG_VIDEO_PLANE = 0x00000400;
+
/**
* Control flags that are private to the platform.
* @hide
@@ -1100,9 +1105,9 @@ public interface WindowManager extends ViewManager {
* flags and returns true if the combination of the two corresponds
* to a window that needs to be behind the input method so that the
* user can type into it.
- *
+ *
* @param flags The current window manager flags.
- *
+ *
* @return Returns true if such a window should be behind/interact
* with an input method, false if not.
*/
@@ -1114,63 +1119,63 @@ public interface WindowManager extends ViewManager {
}
return false;
}
-
+
/**
* Mask for {@link #softInputMode} of the bits that determine the
* desired visibility state of the soft input area for this window.
*/
public static final int SOFT_INPUT_MASK_STATE = 0x0f;
-
+
/**
* Visibility state for {@link #softInputMode}: no state has been specified.
*/
public static final int SOFT_INPUT_STATE_UNSPECIFIED = 0;
-
+
/**
* Visibility state for {@link #softInputMode}: please don't change the state of
* the soft input area.
*/
public static final int SOFT_INPUT_STATE_UNCHANGED = 1;
-
+
/**
* Visibility state for {@link #softInputMode}: please hide any soft input
* area when normally appropriate (when the user is navigating
* forward to your window).
*/
public static final int SOFT_INPUT_STATE_HIDDEN = 2;
-
+
/**
* Visibility state for {@link #softInputMode}: please always hide any
* soft input area when this window receives focus.
*/
public static final int SOFT_INPUT_STATE_ALWAYS_HIDDEN = 3;
-
+
/**
* Visibility state for {@link #softInputMode}: please show the soft
* input area when normally appropriate (when the user is navigating
* forward to your window).
*/
public static final int SOFT_INPUT_STATE_VISIBLE = 4;
-
+
/**
* Visibility state for {@link #softInputMode}: please always make the
* soft input area visible when this window receives input focus.
*/
public static final int SOFT_INPUT_STATE_ALWAYS_VISIBLE = 5;
-
+
/**
* Mask for {@link #softInputMode} of the bits that determine the
* way that the window should be adjusted to accommodate the soft
* input window.
*/
public static final int SOFT_INPUT_MASK_ADJUST = 0xf0;
-
+
/** Adjustment option for {@link #softInputMode}: nothing specified.
* The system will try to pick one or
* the other depending on the contents of the window.
*/
public static final int SOFT_INPUT_ADJUST_UNSPECIFIED = 0x00;
-
+
/** Adjustment option for {@link #softInputMode}: set to allow the
* window to be resized when an input
* method is shown, so that its contents are not covered by the input
@@ -1183,7 +1188,7 @@ public interface WindowManager extends ViewManager {
* not resize, but will stay fullscreen.
*/
public static final int SOFT_INPUT_ADJUST_RESIZE = 0x10;
-
+
/** Adjustment option for {@link #softInputMode}: set to have a window
* pan when an input method is
* shown, so it doesn't need to deal with resizing but just panned
@@ -1193,7 +1198,7 @@ public interface WindowManager extends ViewManager {
* the other depending on the contents of the window.
*/
public static final int SOFT_INPUT_ADJUST_PAN = 0x20;
-
+
/** Adjustment option for {@link #softInputMode}: set to have a window
* not adjust for a shown input method. The window will not be resized,
* and it will not be panned to make its focus visible.
@@ -1212,7 +1217,7 @@ public interface WindowManager extends ViewManager {
/**
* Desired operating mode for any soft input area. May be any combination
* of:
- *
+ *
* <ul>
* <li> One of the visibility states
* {@link #SOFT_INPUT_STATE_UNSPECIFIED}, {@link #SOFT_INPUT_STATE_UNCHANGED},
@@ -1229,7 +1234,7 @@ public interface WindowManager extends ViewManager {
* {@link android.R.attr#windowSoftInputMode} attribute.</p>
*/
public int softInputMode;
-
+
/**
* Placement of window within the screen as per {@link Gravity}. Both
* {@link Gravity#apply(int, int, int, android.graphics.Rect, int, int,
@@ -1246,7 +1251,7 @@ public interface WindowManager extends ViewManager {
* @see Gravity
*/
public int gravity;
-
+
/**
* The horizontal margin, as a percentage of the container's width,
* between the container and the widget. See
@@ -1255,7 +1260,7 @@ public interface WindowManager extends ViewManager {
* field is added with {@link #x} to supply the <var>xAdj</var> parameter.
*/
public float horizontalMargin;
-
+
/**
* The vertical margin, as a percentage of the container's height,
* between the container and the widget. See
@@ -1264,26 +1269,26 @@ public interface WindowManager extends ViewManager {
* field is added with {@link #y} to supply the <var>yAdj</var> parameter.
*/
public float verticalMargin;
-
+
/**
* The desired bitmap format. May be one of the constants in
* {@link android.graphics.PixelFormat}. Default is OPAQUE.
*/
public int format;
-
+
/**
* A style resource defining the animations to use for this window.
* This must be a system resource; it can not be an application resource
* because the window manager does not have access to applications.
*/
public int windowAnimations;
-
+
/**
* An alpha value to apply to this entire window.
* An alpha of 1.0 means fully opaque and 0.0 means fully transparent
*/
public float alpha = 1.0f;
-
+
/**
* When {@link #FLAG_DIM_BEHIND} is set, this is the amount of dimming
* to apply. Range is from 1.0 for completely opaque to 0.0 for no
@@ -1311,7 +1316,7 @@ public interface WindowManager extends ViewManager {
* to the hightest value when this window is in front.
*/
public static final float BRIGHTNESS_OVERRIDE_FULL = 1.0f;
-
+
/**
* This can be used to override the user's preferred brightness of
* the screen. A value of less than 0, the default, means to use the
@@ -1319,7 +1324,7 @@ public interface WindowManager extends ViewManager {
* dark to full bright.
*/
public float screenBrightness = BRIGHTNESS_OVERRIDE_NONE;
-
+
/**
* This can be used to override the standard behavior of the button and
* keyboard backlights. A value of less than 0, the default, means to
@@ -1353,7 +1358,7 @@ public interface WindowManager extends ViewManager {
* opaque windows have the #FLAG_FULLSCREEN bit set and are not covered
* by other windows. All other situations default to the
* {@link #ROTATION_ANIMATION_ROTATE} behavior.
- *
+ *
* @see #ROTATION_ANIMATION_ROTATE
* @see #ROTATION_ANIMATION_CROSSFADE
* @see #ROTATION_ANIMATION_JUMPCUT
@@ -1365,18 +1370,18 @@ public interface WindowManager extends ViewManager {
* you.
*/
public IBinder token = null;
-
+
/**
* Name of the package owning this window.
*/
public String packageName = null;
-
+
/**
* Specific orientation value for a window.
* May be any of the same values allowed
- * for {@link android.content.pm.ActivityInfo#screenOrientation}.
- * If not set, a default value of
- * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED}
+ * for {@link android.content.pm.ActivityInfo#screenOrientation}.
+ * If not set, a default value of
+ * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED}
* will be used.
*/
public int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -1398,7 +1403,7 @@ public interface WindowManager extends ViewManager {
/**
* Get callbacks about the system ui visibility changing.
- *
+ *
* TODO: Maybe there should be a bitfield of optional callbacks that we need.
*
* @hide
@@ -1464,34 +1469,34 @@ public interface WindowManager extends ViewManager {
type = TYPE_APPLICATION;
format = PixelFormat.OPAQUE;
}
-
+
public LayoutParams(int _type) {
super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
type = _type;
format = PixelFormat.OPAQUE;
}
-
+
public LayoutParams(int _type, int _flags) {
super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
type = _type;
flags = _flags;
format = PixelFormat.OPAQUE;
}
-
+
public LayoutParams(int _type, int _flags, int _format) {
super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
type = _type;
flags = _flags;
format = _format;
}
-
+
public LayoutParams(int w, int h, int _type, int _flags, int _format) {
super(w, h);
type = _type;
flags = _flags;
format = _format;
}
-
+
public LayoutParams(int w, int h, int xpos, int ypos, int _type,
int _flags, int _format) {
super(w, h);
@@ -1501,18 +1506,18 @@ public interface WindowManager extends ViewManager {
flags = _flags;
format = _format;
}
-
+
public final void setTitle(CharSequence title) {
if (null == title)
title = "";
-
+
mTitle = TextUtils.stringOrSpannedString(title);
}
-
+
public final CharSequence getTitle() {
return mTitle;
}
-
+
public int describeContents() {
return 0;
}
@@ -1546,19 +1551,19 @@ public interface WindowManager extends ViewManager {
out.writeInt(inputFeatures);
out.writeLong(userActivityTimeout);
}
-
+
public static final Parcelable.Creator<LayoutParams> CREATOR
= new Parcelable.Creator<LayoutParams>() {
public LayoutParams createFromParcel(Parcel in) {
return new LayoutParams(in);
}
-
+
public LayoutParams[] newArray(int size) {
return new LayoutParams[size];
}
};
-
-
+
+
public LayoutParams(Parcel in) {
width = in.readInt();
height = in.readInt();
@@ -1588,7 +1593,7 @@ public interface WindowManager extends ViewManager {
inputFeatures = in.readInt();
userActivityTimeout = in.readLong();
}
-
+
@SuppressWarnings({"PointlessBitwiseExpression"})
public static final int LAYOUT_CHANGED = 1<<0;
public static final int TYPE_CHANGED = 1<<1;
@@ -1622,10 +1627,10 @@ public interface WindowManager extends ViewManager {
// internal buffer to backup/restore parameters under compatibility mode.
private int[] mCompatibilityParamsBackup = null;
-
+
public final int copyFrom(LayoutParams o) {
int changes = 0;
-
+
if (width != o.width) {
width = o.width;
changes |= LAYOUT_CHANGED;
@@ -1724,7 +1729,7 @@ public interface WindowManager extends ViewManager {
rotationAnimation = o.rotationAnimation;
changes |= ROTATION_ANIMATION_CHANGED;
}
-
+
if (screenOrientation != o.screenOrientation) {
screenOrientation = o.screenOrientation;
changes |= SCREEN_ORIENTATION_CHANGED;
@@ -1754,7 +1759,7 @@ public interface WindowManager extends ViewManager {
return changes;
}
-
+
@Override
public String debug(String output) {
output += "Contents of " + this + ":";
@@ -1765,7 +1770,7 @@ public interface WindowManager extends ViewManager {
Log.d("Debug", "WindowManager.LayoutParams={title=" + mTitle + "}");
return "";
}
-
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder(256);
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 0b78e0a..66580f8 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2313,6 +2313,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
// If we failed to re-bind the data, scrap the obtained view.
if (updatedView != transientView) {
+ setItemViewLayoutParams(updatedView, position);
mRecycler.addScrapView(updatedView, position);
}
}
@@ -2343,19 +2344,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
child.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
}
- if (mAdapterHasStableIds) {
- final ViewGroup.LayoutParams vlp = child.getLayoutParams();
- LayoutParams lp;
- if (vlp == null) {
- lp = (LayoutParams) generateDefaultLayoutParams();
- } else if (!checkLayoutParams(vlp)) {
- lp = (LayoutParams) generateLayoutParams(vlp);
- } else {
- lp = (LayoutParams) vlp;
- }
- lp.itemId = mAdapter.getItemId(position);
- child.setLayoutParams(lp);
- }
+ setItemViewLayoutParams(child, position);
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
if (mAccessibilityDelegate == null) {
@@ -2371,6 +2360,24 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
return child;
}
+ private void setItemViewLayoutParams(View child, int position) {
+ final ViewGroup.LayoutParams vlp = child.getLayoutParams();
+ LayoutParams lp;
+ if (vlp == null) {
+ lp = (LayoutParams) generateDefaultLayoutParams();
+ } else if (!checkLayoutParams(vlp)) {
+ lp = (LayoutParams) generateLayoutParams(vlp);
+ } else {
+ lp = (LayoutParams) vlp;
+ }
+
+ if (mAdapterHasStableIds) {
+ lp.itemId = mAdapter.getItemId(position);
+ }
+ lp.viewType = mAdapter.getItemViewType(position);
+ child.setLayoutParams(lp);
+ }
+
class ListItemAccessibilityDelegate extends AccessibilityDelegate {
@Override
public AccessibilityNodeInfo createAccessibilityNodeInfo(View host) {
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index af9e2f0..f7e81b8 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -346,19 +346,24 @@ public class ProgressBar extends View {
return out;
} else if (drawable instanceof BitmapDrawable) {
- final Bitmap tileBitmap = ((BitmapDrawable) drawable).getBitmap();
+ final BitmapDrawable bitmap = (BitmapDrawable) drawable;
+ final Bitmap tileBitmap = bitmap.getBitmap();
if (mSampleTile == null) {
mSampleTile = tileBitmap;
}
-
- final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape());
+ final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape());
final BitmapShader bitmapShader = new BitmapShader(tileBitmap,
Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);
shapeDrawable.getPaint().setShader(bitmapShader);
- return (clip) ? new ClipDrawable(shapeDrawable, Gravity.LEFT,
- ClipDrawable.HORIZONTAL) : shapeDrawable;
+ // Ensure the color filter and tint are propagated.
+ shapeDrawable.setTint(bitmap.getTint());
+ shapeDrawable.setTintMode(bitmap.getTintMode());
+ shapeDrawable.setColorFilter(bitmap.getColorFilter());
+
+ return clip ? new ClipDrawable(
+ shapeDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL) : shapeDrawable;
}
return drawable;
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index cc51a8b..0a80495 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -57,7 +57,6 @@ import android.widget.SpinnerAdapter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.Map;
/**
* ActionBarImpl is the ActionBar implementation used
@@ -356,10 +355,6 @@ public class ActionBarImpl extends ActionBar {
setSubtitle(mContext.getString(resId));
}
- public void captureSharedElements(Map<String, View> sharedElements) {
- mContainerView.findSharedElements(sharedElements);
- }
-
public void setSelectedNavigationItem(int position) {
switch (mActionView.getNavigationMode()) {
case NAVIGATION_MODE_TABS:
diff --git a/core/java/com/android/internal/os/BatterySipper.java b/core/java/com/android/internal/os/BatterySipper.java
index 4eff5ac..565cee4 100644
--- a/core/java/com/android/internal/os/BatterySipper.java
+++ b/core/java/com/android/internal/os/BatterySipper.java
@@ -34,6 +34,8 @@ public class BatterySipper implements Comparable<BatterySipper> {
public long wakeLockTime;
public long mobileRxPackets;
public long mobileTxPackets;
+ public long mobileActive;
+ public double mobilemspp; // milliseconds per packet
public long wifiRxPackets;
public long wifiTxPackets;
public long mobileRxBytes;
@@ -69,6 +71,11 @@ public class BatterySipper implements Comparable<BatterySipper> {
return values;
}
+ public void computeMobilemspp() {
+ long packets = mobileRxPackets+mobileTxPackets;
+ mobilemspp = packets > 0 ? (mobileActive / (double)packets) : 0;
+ }
+
@Override
public int compareTo(BatterySipper other) {
// Return the flipped value because we want the items in descending order
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index e0cf435..755530c 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -43,6 +43,7 @@ import com.android.internal.os.BatterySipper.DrainType;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
import java.util.Map;
@@ -73,6 +74,8 @@ public class BatteryStatsHelper {
= new SparseArray<List<BatterySipper>>();
private final SparseArray<Double> mUserPower = new SparseArray<Double>();
+ private final List<BatterySipper> mMobilemsppList = new ArrayList<BatterySipper>();
+
private int mStatsType = BatteryStats.STATS_SINCE_CHARGED;
private int mAsUser = 0;
@@ -90,6 +93,9 @@ public class BatteryStatsHelper {
private double mMinDrainedPower;
private double mMaxDrainedPower;
+ // How much the apps together have kept the mobile radio active.
+ private long mAppMobileActive;
+
// How much the apps together have left WIFI running.
private long mAppWifiRunning;
@@ -132,7 +138,7 @@ public class BatteryStatsHelper {
}
public static String makemAh(double power) {
- if (power < .0001) return String.format("%.8f", power);
+ if (power < .00001) return String.format("%.8f", power);
else if (power < .0001) return String.format("%.7f", power);
else if (power < .001) return String.format("%.6f", power);
else if (power < .01) return String.format("%.5f", power);
@@ -160,6 +166,7 @@ public class BatteryStatsHelper {
mTotalPower = 0;
mWifiPower = 0;
mBluetoothPower = 0;
+ mAppMobileActive = 0;
mAppWifiRunning = 0;
mUsageList.clear();
@@ -167,6 +174,7 @@ public class BatteryStatsHelper {
mBluetoothSippers.clear();
mUserSippers.clear();
mUserPower.clear();
+ mMobilemsppList.clear();
if (mStats == null) {
return;
@@ -193,6 +201,37 @@ public class BatteryStatsHelper {
* mPowerProfile.getBatteryCapacity()) / 100;
processAppUsage();
+
+ // Before aggregating apps in to users, collect all apps to sort by their ms per packet.
+ for (int i=0; i<mUsageList.size(); i++) {
+ BatterySipper bs = mUsageList.get(i);
+ bs.computeMobilemspp();
+ if (bs.mobilemspp != 0) {
+ mMobilemsppList.add(bs);
+ }
+ }
+ for (int i=0; i<mUserSippers.size(); i++) {
+ List<BatterySipper> user = mUserSippers.valueAt(i);
+ for (int j=0; j<user.size(); j++) {
+ BatterySipper bs = user.get(j);
+ bs.computeMobilemspp();
+ if (bs.mobilemspp != 0) {
+ mMobilemsppList.add(bs);
+ }
+ }
+ }
+ Collections.sort(mMobilemsppList, new Comparator<BatterySipper>() {
+ @Override
+ public int compare(BatterySipper lhs, BatterySipper rhs) {
+ if (lhs.mobilemspp < rhs.mobilemspp) {
+ return 1;
+ } else if (lhs.mobilemspp > rhs.mobilemspp) {
+ return -1;
+ }
+ return 0;
+ }
+ });
+
processMiscUsage();
if (DEBUG) {
@@ -225,6 +264,7 @@ public class BatteryStatsHelper {
powerCpuNormal[p] = mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_ACTIVE, p);
}
final double mobilePowerPerPacket = getMobilePowerPerPacket();
+ final double mobilePowerPerMs = getMobilePowerPerMs();
final double wifiPowerPerPacket = getWifiPowerPerPacket();
long appWakelockTime = 0;
BatterySipper osApp = null;
@@ -320,9 +360,20 @@ public class BatteryStatsHelper {
final long mobileTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, mStatsType);
final long mobileRxB = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, mStatsType);
final long mobileTxB = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, mStatsType);
- p = (mobileRx + mobileTx) * mobilePowerPerPacket;
+ final long mobileActive = u.getMobileRadioActiveTime(mStatsType);
+ if (mobileActive > 0) {
+ // We are tracking when the radio is up, so can use the active time to
+ // determine power use.
+ mAppMobileActive += mobileActive;
+ p = (mobilePowerPerMs * mobileActive) / 1000;
+ } else {
+ // We are not tracking when the radio is up, so must approximate power use
+ // based on the number of packets.
+ p = (mobileRx + mobileTx) * mobilePowerPerPacket;
+ }
if (DEBUG && p != 0) Log.d(TAG, "UID " + u.getUid() + ": mobile packets "
- + (mobileRx+mobileTx) + " power=" + makemAh(p));
+ + (mobileRx+mobileTx) + " active time " + mobileActive
+ + " power=" + makemAh(p));
power += p;
// Add cost of wifi traffic
@@ -406,6 +457,7 @@ public class BatteryStatsHelper {
app.wakeLockTime = wakelockTime;
app.mobileRxPackets = mobileRx;
app.mobileTxPackets = mobileTx;
+ app.mobileActive = mobileActive / 1000;
app.wifiRxPackets = wifiRx;
app.wifiTxPackets = wifiTx;
app.mobileRxBytes = mobileRxB;
@@ -474,7 +526,7 @@ public class BatteryStatsHelper {
double phoneOnPower = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE)
* phoneOnTimeMs / (60*60*1000);
if (phoneOnPower != 0) {
- addEntry(BatterySipper.DrainType.PHONE, phoneOnTimeMs, phoneOnPower);
+ BatterySipper bs = addEntry(BatterySipper.DrainType.PHONE, phoneOnTimeMs, phoneOnPower);
}
}
@@ -531,12 +583,18 @@ public class BatteryStatsHelper {
Log.d(TAG, "Cell radio scanning: time=" + scanningTimeMs + " power=" + makemAh(p));
}
power += p;
+ long radioActiveTimeUs = mStats.getMobileRadioActiveTime(mBatteryRealtime, mStatsType);
+ long remainingActiveTime = (radioActiveTimeUs - mAppMobileActive) / 1000;
+ if (remainingActiveTime > 0) {
+ power += getMobilePowerPerMs() * remainingActiveTime;
+ }
if (power != 0) {
BatterySipper bs =
addEntry(BatterySipper.DrainType.CELL, signalTimeMs, power);
if (signalTimeMs != 0) {
bs.noCoveragePercent = noCoverageTimeMs * 100.0 / signalTimeMs;
}
+ bs.mobileActive = remainingActiveTime;
}
}
@@ -551,6 +609,7 @@ public class BatteryStatsHelper {
bs.wakeLockTime += wbs.wakeLockTime;
bs.mobileRxPackets += wbs.mobileRxPackets;
bs.mobileTxPackets += wbs.mobileTxPackets;
+ bs.mobileActive += wbs.mobileActive;
bs.wifiRxPackets += wbs.wifiRxPackets;
bs.wifiTxPackets += wbs.wifiTxPackets;
bs.mobileRxBytes += wbs.mobileRxBytes;
@@ -558,6 +617,7 @@ public class BatteryStatsHelper {
bs.wifiRxBytes += wbs.wifiRxBytes;
bs.wifiTxBytes += wbs.wifiTxBytes;
}
+ bs.computeMobilemspp();
}
private void addWiFiUsage() {
@@ -650,6 +710,13 @@ public class BatteryStatsHelper {
}
/**
+ * Return estimated power (in mAs) of keeping the radio up
+ */
+ private double getMobilePowerPerMs() {
+ return mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE) / (60*60*1000);
+ }
+
+ /**
* Return estimated power (in mAs) of sending a byte with the Wi-Fi radio.
*/
private double getWifiPowerPerPacket() {
@@ -691,6 +758,10 @@ public class BatteryStatsHelper {
return mUsageList;
}
+ public List<BatterySipper> getMobilemsppList() {
+ return mMobilemsppList;
+ }
+
public long getStatsPeriod() { return mStatsPeriod; }
public int getStatsType() { return mStatsType; };
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 8843500..46983ab 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -87,7 +87,7 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 85 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 90 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -283,6 +283,8 @@ public final class BatteryStatsImpl extends BatteryStats {
boolean mMobileRadioActive;
StopwatchTimer mMobileRadioActiveTimer;
+ LongSamplingCounter mMobileRadioActiveUnknownTime;
+ LongSamplingCounter mMobileRadioActiveUnknownCount;
/** Bluetooth headset object */
BluetoothHeadset mBtHeadset;
@@ -1176,11 +1178,12 @@ public final class BatteryStatsImpl extends BatteryStats {
void startRunningLocked(BatteryStatsImpl stats, long elapsedRealtime) {
if (mNesting++ == 0) {
- mUpdateTime = stats.getBatteryRealtimeLocked(elapsedRealtime * 1000);
+ final long batteryRealtime = stats.getBatteryRealtimeLocked(elapsedRealtime * 1000);
+ mUpdateTime = batteryRealtime;
if (mTimerPool != null) {
// Accumulate time to all currently active timers before adding
// this new one to the pool.
- refreshTimersLocked(stats, mTimerPool);
+ refreshTimersLocked(stats, batteryRealtime, mTimerPool, null);
// Add this timer to the active pool
mTimerPool.add(this);
}
@@ -1199,21 +1202,35 @@ public final class BatteryStatsImpl extends BatteryStats {
return mNesting > 0;
}
+ long checkpointRunningLocked(BatteryStatsImpl stats, long elapsedRealtime) {
+ if (mNesting > 0) {
+ // We are running...
+ final long batteryRealtime = stats.getBatteryRealtimeLocked(elapsedRealtime * 1000);
+ if (mTimerPool != null) {
+ return refreshTimersLocked(stats, batteryRealtime, mTimerPool, this);
+ }
+ final long heldTime = batteryRealtime - mUpdateTime;
+ mUpdateTime = batteryRealtime;
+ mTotalTime += heldTime;
+ return heldTime;
+ }
+ return 0;
+ }
+
void stopRunningLocked(BatteryStatsImpl stats, long elapsedRealtime) {
// Ignore attempt to stop a timer that isn't running
if (mNesting == 0) {
return;
}
if (--mNesting == 0) {
+ final long batteryRealtime = stats.getBatteryRealtimeLocked(elapsedRealtime * 1000);
if (mTimerPool != null) {
// Accumulate time to all active counters, scaled by the total
// active in the pool, before taking this one out of the pool.
- refreshTimersLocked(stats, mTimerPool);
+ refreshTimersLocked(stats, batteryRealtime, mTimerPool, null);
// Remove this timer from the active pool
mTimerPool.remove(this);
} else {
- final long batteryRealtime = stats.getBatteryRealtimeLocked(
- elapsedRealtime * 1000);
mNesting = 1;
mTotalTime = computeRunTimeLocked(batteryRealtime);
mNesting = 0;
@@ -1235,19 +1252,23 @@ public final class BatteryStatsImpl extends BatteryStats {
// Update the total time for all other running Timers with the same type as this Timer
// due to a change in timer count
- private static void refreshTimersLocked(final BatteryStatsImpl stats,
- final ArrayList<StopwatchTimer> pool) {
- final long realtime = SystemClock.elapsedRealtime() * 1000;
- final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
+ private static long refreshTimersLocked(final BatteryStatsImpl stats,
+ long batteryRealtime, final ArrayList<StopwatchTimer> pool, StopwatchTimer self) {
+ long selfTime = 0;
final int N = pool.size();
for (int i=N-1; i>= 0; i--) {
final StopwatchTimer t = pool.get(i);
long heldTime = batteryRealtime - t.mUpdateTime;
if (heldTime > 0) {
- t.mTotalTime += heldTime / N;
+ final long myTime = heldTime / N;
+ if (t == self) {
+ selfTime = myTime;
+ }
+ t.mTotalTime += myTime;
}
t.mUpdateTime = batteryRealtime;
}
+ return selfTime;
}
@Override
@@ -2368,8 +2389,12 @@ public final class BatteryStatsImpl extends BatteryStats {
+ Integer.toHexString(mHistoryCur.states));
addHistoryRecordLocked(elapsedRealtime);
mMobileRadioActive = active;
- if (active) mMobileRadioActiveTimer.startRunningLocked(this, elapsedRealtime);
- else mMobileRadioActiveTimer.stopRunningLocked(this, elapsedRealtime);
+ if (active) {
+ mMobileRadioActiveTimer.startRunningLocked(this, elapsedRealtime);
+ } else {
+ updateNetworkActivityLocked(NET_UPDATE_MOBILE, elapsedRealtime);
+ mMobileRadioActiveTimer.stopRunningLocked(this, elapsedRealtime);
+ }
}
}
} catch (NumberFormatException e) {
@@ -3006,7 +3031,7 @@ public final class BatteryStatsImpl extends BatteryStats {
// During device boot, qtaguid isn't enabled until after the inital
// loading of battery stats. Now that they're enabled, take our initial
// snapshot for future delta calculation.
- updateNetworkActivityLocked();
+ updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
}
@Override public long getScreenOnTime(long batteryRealtime, int which) {
@@ -3057,6 +3082,18 @@ public final class BatteryStatsImpl extends BatteryStats {
return mMobileRadioActiveTimer.getTotalTimeLocked(batteryRealtime, which);
}
+ @Override public int getMobileRadioActiveCount(int which) {
+ return mMobileRadioActiveTimer.getCountLocked(which);
+ }
+
+ @Override public long getMobileRadioActiveUnknownTime(int which) {
+ return mMobileRadioActiveUnknownTime.getCountLocked(which);
+ }
+
+ @Override public int getMobileRadioActiveUnknownCount(int which) {
+ return (int)mMobileRadioActiveUnknownCount.getCountLocked(which);
+ }
+
@Override public long getWifiOnTime(long batteryRealtime, int which) {
return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
}
@@ -3156,6 +3193,8 @@ public final class BatteryStatsImpl extends BatteryStats {
LongSamplingCounter[] mNetworkByteActivityCounters;
LongSamplingCounter[] mNetworkPacketActivityCounters;
+ LongSamplingCounter mMobileRadioActiveTime;
+ LongSamplingCounter mMobileRadioActiveCount;
/**
* The statistics we have collected for this uid's wake locks.
@@ -3556,6 +3595,14 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
+ void noteMobileRadioActiveTimeLocked(long batteryUptime) {
+ if (mNetworkByteActivityCounters == null) {
+ initNetworkActivityLocked();
+ }
+ mMobileRadioActiveTime.addCountLocked(batteryUptime);
+ mMobileRadioActiveCount.addCountLocked(1);
+ }
+
@Override
public boolean hasNetworkActivity() {
return mNetworkByteActivityCounters != null;
@@ -3581,6 +3628,18 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
+ @Override
+ public long getMobileRadioActiveTime(int which) {
+ return mMobileRadioActiveTime != null
+ ? mMobileRadioActiveTime.getCountLocked(which) : 0;
+ }
+
+ @Override
+ public int getMobileRadioActiveCount(int which) {
+ return mMobileRadioActiveCount != null
+ ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0;
+ }
+
void initNetworkActivityLocked() {
mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
@@ -3588,6 +3647,8 @@ public final class BatteryStatsImpl extends BatteryStats {
mNetworkByteActivityCounters[i] = new LongSamplingCounter(mUnpluggables);
mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mUnpluggables);
}
+ mMobileRadioActiveTime = new LongSamplingCounter(mUnpluggables);
+ mMobileRadioActiveCount = new LongSamplingCounter(mUnpluggables);
}
/**
@@ -3652,6 +3713,8 @@ public final class BatteryStatsImpl extends BatteryStats {
mNetworkByteActivityCounters[i].reset(false);
mNetworkPacketActivityCounters[i].reset(false);
}
+ mMobileRadioActiveTime.reset(false);
+ mMobileRadioActiveCount.reset(false);
}
if (mWakelockStats.size() > 0) {
@@ -3859,6 +3922,8 @@ public final class BatteryStatsImpl extends BatteryStats {
mNetworkByteActivityCounters[i].writeToParcel(out);
mNetworkPacketActivityCounters[i].writeToParcel(out);
}
+ mMobileRadioActiveTime.writeToParcel(out);
+ mMobileRadioActiveCount.writeToParcel(out);
} else {
out.writeInt(0);
}
@@ -3982,6 +4047,8 @@ public final class BatteryStatsImpl extends BatteryStats {
mNetworkByteActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in);
mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in);
}
+ mMobileRadioActiveTime = new LongSamplingCounter(mUnpluggables, in);
+ mMobileRadioActiveCount = new LongSamplingCounter(mUnpluggables, in);
} else {
mNetworkByteActivityCounters = null;
mNetworkPacketActivityCounters = null;
@@ -5076,6 +5143,8 @@ public final class BatteryStatsImpl extends BatteryStats {
mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mUnpluggables);
}
mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mUnpluggables);
+ mMobileRadioActiveUnknownTime = new LongSamplingCounter(mUnpluggables);
+ mMobileRadioActiveUnknownCount = new LongSamplingCounter(mUnpluggables);
mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables);
mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables);
for (int i=0; i<NUM_WIFI_STATES; i++) {
@@ -5342,6 +5411,8 @@ public final class BatteryStatsImpl extends BatteryStats {
mNetworkPacketActivityCounters[i].reset(false);
}
mMobileRadioActiveTimer.reset(this, false);
+ mMobileRadioActiveUnknownTime.reset(false);
+ mMobileRadioActiveUnknownCount.reset(false);
mWifiOnTimer.reset(this, false);
mGlobalWifiRunningTimer.reset(this, false);
for (int i=0; i<NUM_WIFI_STATES; i++) {
@@ -5419,7 +5490,7 @@ public final class BatteryStatsImpl extends BatteryStats {
public void pullPendingStateUpdatesLocked() {
updateKernelWakelocksLocked();
- updateNetworkActivityLocked();
+ updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
}
void setOnBatteryLocked(boolean onBattery, int oldStatus, int level) {
@@ -5604,10 +5675,14 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
- private void updateNetworkActivityLocked() {
+ static final int NET_UPDATE_MOBILE = 1<<0;
+ static final int NET_UPDATE_WIFI = 1<<1;
+ static final int NET_UPDATE_ALL = 0xffff;
+
+ private void updateNetworkActivityLocked(int which, long elapsedRealtime) {
if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return;
- if (mMobileIfaces.length > 0) {
+ if ((which&NET_UPDATE_MOBILE) != 0 && mMobileIfaces.length > 0) {
final NetworkStats snapshot;
final NetworkStats last = mCurMobileSnapshot;
try {
@@ -5625,6 +5700,10 @@ public final class BatteryStatsImpl extends BatteryStats {
null, null, mTmpNetworkStats);
mTmpNetworkStats = delta;
+ long radioTime = mMobileRadioActiveTimer.checkpointRunningLocked(this,
+ elapsedRealtime);
+ long totalPackets = delta.getTotalPackets();
+
final int size = delta.size();
for (int i = 0; i < size; i++) {
final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
@@ -5637,6 +5716,17 @@ public final class BatteryStatsImpl extends BatteryStats {
u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
entry.txPackets);
+ if (radioTime > 0) {
+ // Distribute total radio active time in to this app.
+ long appPackets = entry.rxPackets + entry.txPackets;
+ long appRadioTime = (radioTime*appPackets)/totalPackets;
+ u.noteMobileRadioActiveTimeLocked(appRadioTime);
+ // Remove this app from the totals, so that we don't lose any time
+ // due to rounding.
+ radioTime -= appRadioTime;
+ totalPackets -= appPackets;
+ }
+
mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(entry.rxBytes);
mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(entry.txBytes);
mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
@@ -5644,9 +5734,15 @@ public final class BatteryStatsImpl extends BatteryStats {
mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
entry.txPackets);
}
+
+ if (radioTime > 0) {
+ // Whoops, there is some radio time we can't blame on an app!
+ mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
+ mMobileRadioActiveUnknownCount.addCountLocked(1);
+ }
}
- if (mWifiIfaces.length > 0) {
+ if ((which&NET_UPDATE_WIFI) != 0 && mWifiIfaces.length > 0) {
final NetworkStats snapshot;
final NetworkStats last = mCurWifiSnapshot;
try {
@@ -6275,6 +6371,8 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mMobileRadioActive = false;
mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
+ mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in);
+ mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in);
mWifiOn = false;
mWifiOnTimer.readSummaryFromParcelLocked(in);
mGlobalWifiRunning = false;
@@ -6370,6 +6468,8 @@ public final class BatteryStatsImpl extends BatteryStats {
u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
}
+ u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in);
+ u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in);
}
int NW = in.readInt();
@@ -6506,6 +6606,8 @@ public final class BatteryStatsImpl extends BatteryStats {
mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
}
mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+ mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out);
+ mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out);
mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
for (int i=0; i<NUM_WIFI_STATES; i++) {
@@ -6609,6 +6711,8 @@ public final class BatteryStatsImpl extends BatteryStats {
u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
}
+ u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out);
+ u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out);
}
int NW = u.mWakelockStats.size();
@@ -6748,6 +6852,8 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mMobileRadioActive = false;
mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mUnpluggables, in);
+ mMobileRadioActiveUnknownTime = new LongSamplingCounter(mUnpluggables, in);
+ mMobileRadioActiveUnknownCount = new LongSamplingCounter(mUnpluggables, in);
mWifiOn = false;
mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
mGlobalWifiRunning = false;
@@ -6865,6 +6971,8 @@ public final class BatteryStatsImpl extends BatteryStats {
mNetworkPacketActivityCounters[i].writeToParcel(out);
}
mMobileRadioActiveTimer.writeToParcel(out, batteryRealtime);
+ mMobileRadioActiveUnknownTime.writeToParcel(out);
+ mMobileRadioActiveUnknownCount.writeToParcel(out);
mWifiOnTimer.writeToParcel(out, batteryRealtime);
mGlobalWifiRunningTimer.writeToParcel(out, batteryRealtime);
for (int i=0; i<NUM_WIFI_STATES; i++) {
diff --git a/core/res/res/layout-xlarge/screen_action_bar.xml b/core/res/res/layout-xlarge/screen_action_bar.xml
index d2fe9fa..e495e53 100644
--- a/core/res/res/layout-xlarge/screen_action_bar.xml
+++ b/core/res/res/layout-xlarge/screen_action_bar.xml
@@ -34,7 +34,6 @@ the Action Bar enabled overlaying application content.
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
style="?android:attr/actionBarStyle"
- android:sharedElementName="android:action_bar"
android:gravity="top">
<com.android.internal.widget.ActionBarView
android:id="@+id/action_bar"
diff --git a/core/res/res/layout/screen_action_bar.xml b/core/res/res/layout/screen_action_bar.xml
index 7b9a20b..b1889a2 100644
--- a/core/res/res/layout/screen_action_bar.xml
+++ b/core/res/res/layout/screen_action_bar.xml
@@ -33,7 +33,6 @@ This is an optimized layout for a screen with the Action Bar enabled.
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
style="?android:attr/actionBarStyle"
- android:sharedElementName="android:action_bar"
android:gravity="top">
<com.android.internal.widget.ActionBarView
android:id="@+id/action_bar"
diff --git a/core/res/res/layout/screen_custom_title.xml b/core/res/res/layout/screen_custom_title.xml
index d02cc8b..e3364d1 100644
--- a/core/res/res/layout/screen_custom_title.xml
+++ b/core/res/res/layout/screen_custom_title.xml
@@ -31,7 +31,6 @@ This is a custom layout for a screen.
<FrameLayout android:id="@android:id/title_container"
android:layout_width="match_parent"
android:layout_height="?android:attr/windowTitleSize"
- android:sharedElementName="android:title"
style="?android:attr/windowTitleBackgroundStyle">
</FrameLayout>
<FrameLayout android:id="@android:id/content"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 1c5be42..bfd7565 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4760,6 +4760,14 @@
<attr name="fromScene" format="reference" />
<!-- The destination scene in this scene change. -->
<attr name="toScene" format="reference" />
+ <!-- The name of the originating scene in this scene change.
+ Apps should treat this name as an API in the same sense
+ that an Intent action or extra key is. -->
+ <attr name="fromSceneName" format="string" />
+ <!-- The name of the destination scene in this scene change.
+ Apps should treat this name as an API in the same sense
+ that an Intent action or extra key is. -->
+ <attr name="toSceneName" format="string" />
</declare-styleable>
<!-- ========================== -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 3106daa..c814d25 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2103,6 +2103,8 @@
<public type="attr" name="controlY1" />
<public type="attr" name="controlX2" />
<public type="attr" name="controlY2" />
+ <public type="attr" name="fromSceneName" />
+ <public type="attr" name="toSceneName" />
<public type="attr" name="sharedElementName" />
<public type="attr" name="transitionGroup" />
<public type="attr" name="castsShadow" />
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk
new file mode 100644
index 0000000..9f04228
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := 9
+
+LOCAL_PACKAGE_NAME := MultiDexLegacyVersionedTestApp_v1
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-multidex
+
+mainDexList:= \
+ $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
+
+LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
+
+include $(BUILD_PACKAGE)
+
+$(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
+ $(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
+ echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
+
+$(built_dex_intermediate): $(mainDexList)
+
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/AndroidManifest.xml
new file mode 100644
index 0000000..c7b066d
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.framework.multidexlegacyversionedtestapp"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="9"
+ android:targetSdkVersion="18" />
+
+ <application
+ android:name="android.support.multidex.MultiDexApplication"
+ android:allowBackup="true"
+ android:label="MultiDexLegacyVersionedTestApp_v1">
+ <activity
+ android:name="com.android.framework.multidexlegacyversionedtestapp.MainActivity"
+ android:label="MultiDexLegacyVersionedTestApp_v1" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.framework.multidexlegacyversionedtestapp"
+ android:label="Test for MultiDexLegacyVersionedTestApp_v1" />
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/res/layout/activity_main.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/res/layout/activity_main.xml
new file mode 100644
index 0000000..58ae67a
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/res/layout/activity_main.xml
@@ -0,0 +1,7 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".MainActivity" >
+
+</RelativeLayout>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
new file mode 100644
index 0000000..8662562
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+/**
+ * Class directly referenced from Activity, will be kept in main dex. The class is not referenced
+ * by <clinit> or <init>, its direct references are not kept in main dex.
+ */
+public class ClassForMainDex {
+
+ public static int getVersion() {
+ return Version.getVersion();
+ }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
new file mode 100644
index 0000000..351d860
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class MainActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ }
+
+ public int getVersion() {
+ return ClassForMainDex.getVersion();
+ }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
new file mode 100644
index 0000000..24b4d69
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+ * Run the tests with: <code>adb shell am instrument -w
+ com.android.framework.multidexlegacyversionedtestapp/android.test.InstrumentationTestRunner
+</code>
+ */
+public class MultiDexUpdateTest extends ActivityInstrumentationTestCase2<MainActivity>
+{
+ public MultiDexUpdateTest() {
+ super(MainActivity.class);
+ }
+
+ /**
+ * Tests that all classes of the application can be loaded. Verifies also that we load the
+ * correct version of {@link Version} ie the class is the secondary dex file.
+ */
+ public void testAllClassAvailable()
+ {
+ assertEquals(1, getActivity().getVersion());
+ }
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/Version.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
new file mode 100644
index 0000000..eb9827a
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+/* can go in secondary dex */
+public class Version {
+
+ public static int getVersion() {
+ return 1;
+ }
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk
new file mode 100644
index 0000000..1b8da41
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := 9
+
+LOCAL_PACKAGE_NAME := MultiDexLegacyVersionedTestApp_v2
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-multidex
+
+mainDexList:= \
+ $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
+
+LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
+
+include $(BUILD_PACKAGE)
+
+$(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
+ $(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
+ echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
+
+$(built_dex_intermediate): $(mainDexList)
+
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/AndroidManifest.xml
new file mode 100644
index 0000000..4d24793
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.framework.multidexlegacyversionedtestapp"
+ android:versionCode="2"
+ android:versionName="2.0" >
+
+ <uses-sdk
+ android:minSdkVersion="9"
+ android:targetSdkVersion="18" />
+
+ <application
+ android:name="android.support.multidex.MultiDexApplication"
+ android:allowBackup="true"
+ android:label="MultiDexLegacyVersionedTestApp_v2">
+ <activity
+ android:name="com.android.framework.multidexlegacyversionedtestapp.MainActivity"
+ android:label="MultiDexLegacyVersionedTestApp_v2" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.framework.multidexlegacyversionedtestapp"
+ android:label="Test for MultiDexLegacyVersionedTestApp_v2" />
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/res/layout/activity_main.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/res/layout/activity_main.xml
new file mode 100644
index 0000000..58ae67a
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/res/layout/activity_main.xml
@@ -0,0 +1,7 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".MainActivity" >
+
+</RelativeLayout>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
new file mode 100644
index 0000000..8662562
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+/**
+ * Class directly referenced from Activity, will be kept in main dex. The class is not referenced
+ * by <clinit> or <init>, its direct references are not kept in main dex.
+ */
+public class ClassForMainDex {
+
+ public static int getVersion() {
+ return Version.getVersion();
+ }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
new file mode 100644
index 0000000..351d860
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class MainActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ }
+
+ public int getVersion() {
+ return ClassForMainDex.getVersion();
+ }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
new file mode 100644
index 0000000..f130cb2
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+ * Run the tests with: <code>adb shell am instrument -w
+ com.android.framework.multidexlegacyversionedtestapp/android.test.InstrumentationTestRunner
+</code>
+ */
+public class MultiDexUpdateTest extends ActivityInstrumentationTestCase2<MainActivity>
+{
+ public MultiDexUpdateTest() {
+ super(MainActivity.class);
+ }
+
+ /**
+ * Tests that all classes of the application can be loaded. Verifies also that we load the
+ * correct version of {@link Version} ie the class is the secondary dex file.
+ */
+ public void testAllClassAvailable()
+ {
+ assertEquals(2, getActivity().getVersion());
+ }
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/Version.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
new file mode 100644
index 0000000..1f2305f
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+/* can go in secondary dex */
+public class Version {
+
+ public static int getVersion() {
+ return 2;
+ }
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk
new file mode 100644
index 0000000..945bfcc
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := 9
+
+LOCAL_PACKAGE_NAME := MultiDexLegacyVersionedTestApp_v3
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-multidex
+
+mainDexList:= \
+ $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
+
+LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
+
+include $(BUILD_PACKAGE)
+
+$(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
+ $(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
+ echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
+
+$(built_dex_intermediate): $(mainDexList)
+
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/AndroidManifest.xml
new file mode 100644
index 0000000..76c92dd
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.framework.multidexlegacyversionedtestapp"
+ android:versionCode="3"
+ android:versionName="3.0" >
+
+ <uses-sdk
+ android:minSdkVersion="9"
+ android:targetSdkVersion="18" />
+
+ <application
+ android:name="android.support.multidex.MultiDexApplication"
+ android:allowBackup="true"
+ android:label="MultiDexLegacyVersionedTestApp_v3">
+ <activity
+ android:name="com.android.framework.multidexlegacyversionedtestapp.MainActivity"
+ android:label="MultiDexLegacyVersionedTestApp_v3" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.framework.multidexlegacyversionedtestapp"
+ android:label="Test for MultiDexLegacyVersionedTestApp_v3" />
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/res/layout/activity_main.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/res/layout/activity_main.xml
new file mode 100644
index 0000000..58ae67a
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/res/layout/activity_main.xml
@@ -0,0 +1,7 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".MainActivity" >
+
+</RelativeLayout>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
new file mode 100644
index 0000000..8662562
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+/**
+ * Class directly referenced from Activity, will be kept in main dex. The class is not referenced
+ * by <clinit> or <init>, its direct references are not kept in main dex.
+ */
+public class ClassForMainDex {
+
+ public static int getVersion() {
+ return Version.getVersion();
+ }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
new file mode 100644
index 0000000..351d860
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class MainActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ }
+
+ public int getVersion() {
+ return ClassForMainDex.getVersion();
+ }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
new file mode 100644
index 0000000..67aa478
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+ * Run the tests with: <code>adb shell am instrument -w
+ com.android.framework.multidexlegacyversionedtestapp/android.test.InstrumentationTestRunner
+</code>
+ */
+public class MultiDexUpdateTest extends ActivityInstrumentationTestCase2<MainActivity>
+{
+ public MultiDexUpdateTest() {
+ super(MainActivity.class);
+ }
+
+ /**
+ * Tests that all classes of the application can be loaded. Verifies also that we load the
+ * correct version of {@link Version} ie the class is the secondary dex file.
+ */
+ public void testAllClassAvailable()
+ {
+ assertEquals(3, getActivity().getVersion());
+ }
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/Version.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
new file mode 100644
index 0000000..1c8ef3b
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+/* can go in secondary dex */
+public class Version {
+
+ public static int getVersion() {
+ return 3;
+ }
+}