diff options
92 files changed, 2423 insertions, 1035 deletions
@@ -261,23 +261,23 @@ LOCAL_SRC_FILES += \ media/java/android/media/IAudioService.aidl \ media/java/android/media/IAudioFocusDispatcher.aidl \ media/java/android/media/IAudioRoutesObserver.aidl \ - media/java/android/media/IMediaController.aidl \ - media/java/android/media/IMediaControllerCallback.aidl \ media/java/android/media/IMediaHTTPConnection.aidl \ media/java/android/media/IMediaHTTPService.aidl \ media/java/android/media/IMediaRouterClient.aidl \ media/java/android/media/IMediaRouterService.aidl \ media/java/android/media/IMediaScannerListener.aidl \ media/java/android/media/IMediaScannerService.aidl \ - media/java/android/media/IMediaSession.aidl \ - media/java/android/media/IMediaSessionCallback.aidl \ - media/java/android/media/IMediaSessionManager.aidl \ media/java/android/media/IRemoteControlClient.aidl \ media/java/android/media/IRemoteControlDisplay.aidl \ media/java/android/media/IRemoteDisplayCallback.aidl \ media/java/android/media/IRemoteDisplayProvider.aidl \ media/java/android/media/IRemoteVolumeObserver.aidl \ media/java/android/media/IRingtonePlayer.aidl \ + media/java/android/media/session/IMediaController.aidl \ + media/java/android/media/session/IMediaControllerCallback.aidl \ + media/java/android/media/session/IMediaSession.aidl \ + media/java/android/media/session/IMediaSessionCallback.aidl \ + media/java/android/media/session/IMediaSessionManager.aidl \ telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl \ telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \ telephony/java/com/android/internal/telephony/ITelephony.aidl \ diff --git a/CleanSpec.mk b/CleanSpec.mk index 1e49fcb..448b03d 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -186,6 +186,7 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/effects/) $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/framework-res_intermediates) $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/IPrintClient.*) $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/services_intermediates) +$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/media/java/android/media/IMedia*) # ************************************************ # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST # ************************************************ diff --git a/api/current.txt b/api/current.txt index 53655fa..8340265 100644 --- a/api/current.txt +++ b/api/current.txt @@ -345,7 +345,7 @@ package android { field public static final int canRetrieveWindowContent = 16843653; // 0x1010385 field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230 field public static final deprecated int capitalize = 16843113; // 0x1010169 - field public static final int castsShadow = 16843775; // 0x10103ff + field public static final int castsShadow = 16843777; // 0x1010401 field public static final int category = 16843752; // 0x10103e8 field public static final int centerBright = 16842956; // 0x10100cc field public static final int centerColor = 16843275; // 0x101020b @@ -542,6 +542,7 @@ package android { field public static final int fromAlpha = 16843210; // 0x10101ca field public static final int fromDegrees = 16843187; // 0x10101b3 field public static final int fromScene = 16843741; // 0x10103dd + field public static final int fromSceneName = 16843773; // 0x10103fd field public static final int fromXDelta = 16843206; // 0x10101c6 field public static final int fromXScale = 16843202; // 0x10101c2 field public static final int fromYDelta = 16843208; // 0x10101c8 @@ -889,7 +890,7 @@ package android { field public static final int required = 16843406; // 0x101028e field public static final int requiredAccountType = 16843734; // 0x10103d6 field public static final int requiredForAllUsers = 16843728; // 0x10103d0 - field public static final int requiredForProfile = 16843776; // 0x1010400 + field public static final int requiredForProfile = 16843778; // 0x1010402 field public static final int requiresFadingEdge = 16843685; // 0x10103a5 field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364 field public static final int resizeMode = 16843619; // 0x1010363 @@ -960,7 +961,7 @@ package android { field public static final int shadowRadius = 16843108; // 0x1010164 field public static final int shape = 16843162; // 0x101019a field public static final int shareInterpolator = 16843195; // 0x10101bb - field public static final int sharedElementName = 16843773; // 0x10103fd + field public static final int sharedElementName = 16843775; // 0x10103ff field public static final int sharedUserId = 16842763; // 0x101000b field public static final int sharedUserLabel = 16843361; // 0x1010261 field public static final int shouldDisableView = 16843246; // 0x10101ee @@ -1144,6 +1145,7 @@ package android { field public static final int toAlpha = 16843211; // 0x10101cb field public static final int toDegrees = 16843188; // 0x10101b4 field public static final int toScene = 16843742; // 0x10103de + field public static final int toSceneName = 16843774; // 0x10103fe field public static final int toXDelta = 16843207; // 0x10101c7 field public static final int toXScale = 16843203; // 0x10101c3 field public static final int toYDelta = 16843209; // 0x10101c9 @@ -1159,7 +1161,7 @@ package android { field public static final int transformPivotX = 16843552; // 0x1010320 field public static final int transformPivotY = 16843553; // 0x1010321 field public static final int transition = 16843743; // 0x10103df - field public static final int transitionGroup = 16843774; // 0x10103fe + field public static final int transitionGroup = 16843776; // 0x1010400 field public static final int transitionOrdering = 16843744; // 0x10103e0 field public static final int translationX = 16843554; // 0x1010322 field public static final int translationY = 16843555; // 0x1010323 @@ -3039,6 +3041,7 @@ package android.app { method public int getTaskId(); method public final java.lang.CharSequence getTitle(); method public final int getTitleColor(); + method public android.os.Bundle getTransitionArgs(); method public final int getVolumeControlStream(); method public android.view.Window getWindow(); method public android.view.WindowManager getWindowManager(); @@ -3060,8 +3063,6 @@ package android.app { method public void onAttachFragment(android.app.Fragment); method public void onAttachedToWindow(); method public void onBackPressed(); - method public void onCaptureSharedElementEnd(); - method public void onCaptureSharedElementStart(android.transition.Transition); method protected void onChildTitleChanged(android.app.Activity, java.lang.CharSequence); method public void onConfigurationChanged(android.content.res.Configuration); method public void onContentChanged(); @@ -3136,6 +3137,7 @@ package android.app { method public void setContentView(android.view.View); method public void setContentView(android.view.View, android.view.ViewGroup.LayoutParams); method public final void setDefaultKeyMode(int); + method public void setEarlyBackgroundTransition(boolean); method public final void setFeatureDrawable(int, android.graphics.drawable.Drawable); method public final void setFeatureDrawableAlpha(int, int); method public final void setFeatureDrawableResource(int, int); @@ -3160,9 +3162,7 @@ package android.app { method public final deprecated void showDialog(int); method public final deprecated boolean showDialog(int, android.os.Bundle); method public android.view.ActionMode startActionMode(android.view.ActionMode.Callback); - method public void startActivity(android.content.Intent, android.util.Pair<android.view.View, java.lang.String>...); method public void startActivityForResult(android.content.Intent, int); - method public void startActivityForResult(android.content.Intent, int, android.util.Pair<android.view.View, java.lang.String>...); method public void startActivityForResult(android.content.Intent, int, android.os.Bundle); method public void startActivityFromChild(android.app.Activity, android.content.Intent, int); method public void startActivityFromChild(android.app.Activity, android.content.Intent, int, android.os.Bundle); @@ -3178,6 +3178,7 @@ package android.app { method public boolean startNextMatchingActivity(android.content.Intent); method public boolean startNextMatchingActivity(android.content.Intent, android.os.Bundle); method public void startSearch(java.lang.String, boolean, android.os.Bundle, boolean); + method protected void startSharedElementTransition(android.os.Bundle); method public deprecated void stopManagingCursor(android.database.Cursor); method public void takeKeyEvents(boolean); method public void triggerSearch(java.lang.String, android.os.Bundle); @@ -3348,6 +3349,7 @@ package android.app { public class ActivityOptions { method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int); method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int); + method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.os.Bundle); method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int); method public android.os.Bundle toBundle(); method public void update(android.app.ActivityOptions); @@ -10385,6 +10387,7 @@ package android.graphics.drawable { method public final android.graphics.Paint getPaint(); method public android.graphics.Shader.TileMode getTileModeX(); method public android.graphics.Shader.TileMode getTileModeY(); + method public android.content.res.ColorStateList getTint(); method public boolean hasAntiAlias(); method public boolean hasMipMap(); method public final boolean isAutoMirrored(); @@ -10400,7 +10403,6 @@ package android.graphics.drawable { method public void setTileModeXY(android.graphics.Shader.TileMode, android.graphics.Shader.TileMode); method public final void setTileModeY(android.graphics.Shader.TileMode); method public void setTint(android.content.res.ColorStateList); - method public void setTintMode(android.graphics.PorterDuff.Mode); } public class ClipDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback { @@ -10443,6 +10445,7 @@ package android.graphics.drawable { method public final android.graphics.Rect getBounds(); method public android.graphics.drawable.Drawable.Callback getCallback(); method public int getChangingConfigurations(); + method public android.graphics.ColorFilter getColorFilter(); method public android.graphics.drawable.Drawable.ConstantState getConstantState(); method public android.graphics.drawable.Drawable getCurrent(); method public int getIntrinsicHeight(); @@ -10631,13 +10634,13 @@ package android.graphics.drawable { method public void draw(android.graphics.Canvas); method public int getOpacity(); method public android.graphics.Paint getPaint(); + method public android.content.res.ColorStateList getTint(); method public void setAlpha(int); method public void setColorFilter(android.graphics.ColorFilter); method public void setTargetDensity(android.graphics.Canvas); method public void setTargetDensity(android.util.DisplayMetrics); method public void setTargetDensity(int); method public void setTint(android.content.res.ColorStateList); - method public void setTintMode(android.graphics.PorterDuff.Mode); } public class PaintDrawable extends android.graphics.drawable.ShapeDrawable { @@ -10706,6 +10709,7 @@ package android.graphics.drawable { method public android.graphics.Paint getPaint(); method public android.graphics.drawable.ShapeDrawable.ShaderFactory getShaderFactory(); method public android.graphics.drawable.shapes.Shape getShape(); + method public android.content.res.ColorStateList getTint(); method protected boolean inflateTag(java.lang.String, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet); method protected void onDraw(android.graphics.drawable.shapes.Shape, android.graphics.Canvas, android.graphics.Paint); method public void setAlpha(int); @@ -10716,6 +10720,7 @@ package android.graphics.drawable { method public void setPadding(android.graphics.Rect); method public void setShaderFactory(android.graphics.drawable.ShapeDrawable.ShaderFactory); method public void setShape(android.graphics.drawable.shapes.Shape); + method public void setTint(android.content.res.ColorStateList); } public static abstract class ShapeDrawable.ShaderFactory { @@ -13172,23 +13177,6 @@ package android.media { method public static final android.media.MediaCodecInfo getCodecInfoAt(int); } - public final class MediaController { - ctor public MediaController(android.media.MediaSessionToken); - method public void addCallback(android.media.MediaController.Callback); - method public void addCallback(android.media.MediaController.Callback, android.os.Handler); - method public void removeCallback(android.media.MediaController.Callback); - method public void sendCommand(java.lang.String, android.os.Bundle); - method public void sendMediaButton(int); - } - - public static abstract class MediaController.Callback { - ctor public MediaController.Callback(); - method public void onEvent(java.lang.String, android.os.Bundle); - method public void onMetadataUpdate(android.os.Bundle); - method public void onPlaybackStateChange(int); - method public void onRouteChanged(android.os.Bundle); - } - public final class MediaCrypto { ctor public MediaCrypto(java.util.UUID, byte[]) throws android.media.MediaCryptoException; method public static final boolean isCryptoSchemeSupported(java.util.UUID); @@ -13755,33 +13743,6 @@ package android.media { method public abstract void onScanCompleted(java.lang.String, android.net.Uri); } - public final class MediaSession { - method public void addCallback(android.media.MediaSession.Callback); - method public void addCallback(android.media.MediaSession.Callback, android.os.Handler); - method public android.media.MediaSessionToken getSessionToken(); - method public void release(); - method public void removeCallback(android.media.MediaSession.Callback); - method public void setPlaybackState(int); - } - - public static abstract class MediaSession.Callback { - ctor public MediaSession.Callback(); - method public void onCommand(java.lang.String, android.os.Bundle); - method public void onMediaButton(android.content.Intent); - method public void onRequestRouteChange(android.os.Bundle); - } - - public final class MediaSessionManager { - method public android.media.MediaSession createSession(java.lang.String); - method public java.util.List<android.media.MediaController> getActiveSessions(); - } - - public class MediaSessionToken implements android.os.Parcelable { - method public int describeContents(); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator CREATOR; - } - public class MediaSyncEvent { method public static android.media.MediaSyncEvent createEvent(int) throws java.lang.IllegalArgumentException; method public int getAudioSessionId(); @@ -14451,6 +14412,54 @@ package android.media.effect { } +package android.media.session { + + public final class MediaController { + ctor public MediaController(android.media.session.MediaSessionToken); + method public void addCallback(android.media.session.MediaController.Callback); + method public void addCallback(android.media.session.MediaController.Callback, android.os.Handler); + method public void removeCallback(android.media.session.MediaController.Callback); + method public void sendCommand(java.lang.String, android.os.Bundle); + method public void sendMediaButton(int); + } + + public static abstract class MediaController.Callback { + ctor public MediaController.Callback(); + method public void onEvent(java.lang.String, android.os.Bundle); + method public void onMetadataUpdate(android.os.Bundle); + method public void onPlaybackStateChange(int); + method public void onRouteChanged(android.os.Bundle); + } + + public final class MediaSession { + method public void addCallback(android.media.session.MediaSession.Callback); + method public void addCallback(android.media.session.MediaSession.Callback, android.os.Handler); + method public android.media.session.MediaSessionToken getSessionToken(); + method public void release(); + method public void removeCallback(android.media.session.MediaSession.Callback); + method public void setPlaybackState(int); + } + + public static abstract class MediaSession.Callback { + ctor public MediaSession.Callback(); + method public void onCommand(java.lang.String, android.os.Bundle); + method public void onMediaButton(android.content.Intent); + method public void onRequestRouteChange(android.os.Bundle); + } + + public final class MediaSessionManager { + method public android.media.session.MediaSession createSession(java.lang.String); + method public java.util.List<android.media.session.MediaController> getActiveSessions(); + } + + public class MediaSessionToken implements android.os.Parcelable { + method public int describeContents(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator CREATOR; + } + +} + package android.mtp { public final class MtpConstants { @@ -15510,6 +15519,7 @@ package android.net.wifi { method public int describeContents(); method public java.lang.String getBSSID(); method public static android.net.NetworkInfo.DetailedState getDetailedStateOf(android.net.wifi.SupplicantState); + method public int getFrequency(); method public boolean getHiddenSSID(); method public int getIpAddress(); method public int getLinkSpeed(); @@ -15519,6 +15529,7 @@ package android.net.wifi { method public java.lang.String getSSID(); method public android.net.wifi.SupplicantState getSupplicantState(); method public void writeToParcel(android.os.Parcel, int); + field public static final java.lang.String FREQUENCY_UNITS = "MHz"; field public static final java.lang.String LINK_SPEED_UNITS = "Mbps"; } @@ -26818,11 +26829,15 @@ package android.transition { ctor public TransitionManager(); method public static void beginDelayedTransition(android.view.ViewGroup); method public static void beginDelayedTransition(android.view.ViewGroup, android.transition.Transition); + method public android.transition.Transition getNamedTransition(java.lang.String, android.transition.Scene); + method public android.transition.Transition getNamedTransition(android.transition.Scene, java.lang.String); + method public java.lang.String[] getTargetSceneNames(android.transition.Scene); method public static void go(android.transition.Scene); method public static void go(android.transition.Scene, android.transition.Transition); - method public void setExitTransition(android.transition.Scene, android.transition.Transition); method public void setTransition(android.transition.Scene, android.transition.Transition); method public void setTransition(android.transition.Scene, android.transition.Scene, android.transition.Transition); + method public void setTransition(android.transition.Scene, java.lang.String, android.transition.Transition); + method public void setTransition(java.lang.String, android.transition.Scene, android.transition.Transition); method public void transitionTo(android.transition.Scene); } @@ -29793,7 +29808,6 @@ package android.view { method public abstract boolean isFloating(); method public abstract boolean isShortcutKey(int, android.view.KeyEvent); method public final void makeActive(); - method public void mapTransitionTargets(java.util.Map<java.lang.String, java.lang.String>); method protected abstract void onActive(); method public abstract void onConfigurationChanged(android.content.res.Configuration); method public abstract void openPanel(int, android.view.KeyEvent); @@ -29832,7 +29846,6 @@ package android.view { method public abstract void setTitle(java.lang.CharSequence); method public abstract deprecated void setTitleColor(int); method public void setTransitionManager(android.transition.TransitionManager); - method public void setTriggerEarlyEnterTransition(boolean); method public void setType(int); method public void setUiOptions(int); method public void setUiOptions(int, int); 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; + } +} diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index 2f4196a..fe08f4b 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -27,10 +27,8 @@ import android.graphics.ColorFilter; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PixelFormat; -import android.graphics.PorterDuff; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffColorFilter; -import android.graphics.drawable.GradientDrawable.GradientState; import android.graphics.Rect; import android.graphics.Shader; import android.graphics.Xfermode; @@ -558,6 +556,11 @@ public class BitmapDrawable extends Drawable { invalidateSelf(); } + @Override + public ColorFilter getColorFilter() { + return mBitmapState.mPaint.getColorFilter(); + } + /** * Specifies a tint for this drawable. * <p> @@ -568,31 +571,63 @@ public class BitmapDrawable extends Drawable { * clear the tint */ public void setTint(ColorStateList tint) { - mBitmapState.mTint = tint; - if (mTintFilter == null) { - if (tint != null) { - final int color = tint.getColorForState(getState(), 0); - mTintFilter = new PorterDuffColorFilter(color, mBitmapState.mTintMode); - } - } else { - if (tint == null) { - mTintFilter = null; - } + if (mBitmapState.mTint != tint) { + mBitmapState.mTint = tint; + updateTintFilter(); + invalidateSelf(); } - invalidateSelf(); + } + + /** + * Returns the tint color for this drawable. + * + * @return Color state list to use for tinting this drawable, or null if + * none set + */ + public ColorStateList getTint() { + return mBitmapState.mTint; } /** * Specifies the blending mode used to apply tint. * * @param tintMode A Porter-Duff blending mode + * @hide Pending finalization of supported Modes */ public void setTintMode(Mode tintMode) { - mBitmapState.mTintMode = tintMode; - if (mTintFilter != null) { - mTintFilter.setMode(tintMode); + if (mBitmapState.mTintMode != tintMode) { + mBitmapState.mTintMode = tintMode; + updateTintFilter(); + invalidateSelf(); + } + } + + /** + * Returns the tint mode for this drawable, or {@code null} if none set. + * + * @return the tint mode for this drawable, or {@code null} if none set + * @hide + */ + public Mode getTintMode() { + return mBitmapState.mTintMode; + } + + /** + * Ensures the tint filter is consistent with the current tint color and + * mode. + */ + private void updateTintFilter() { + final ColorStateList tint = mBitmapState.mTint; + final Mode tintMode = mBitmapState.mTintMode; + if (tint != null && tintMode != null) { + if (mTintFilter == null) { + mTintFilter = new PorterDuffColorFilter(0, tintMode); + } else { + mTintFilter.setMode(tintMode); + } + } else { + mTintFilter = null; } - invalidateSelf(); } /** @@ -730,7 +765,7 @@ public class BitmapDrawable extends Drawable { final static class BitmapState extends ConstantState { Bitmap mBitmap; ColorStateList mTint; - Mode mTintMode; + Mode mTintMode = Mode.SRC_IN; int mChangingConfigurations; int mGravity = Gravity.FILL; Paint mPaint = new Paint(DEFAULT_PAINT_FLAGS); diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index a9cf115..84211ef 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -454,12 +454,6 @@ public abstract class Drawable { } /** - * Specify an optional color filter for the drawable. Pass null to remove - * any existing color filter. - */ - public abstract void setColorFilter(ColorFilter cf); - - /** * @hide Consider for future API inclusion */ public void setXfermode(Xfermode mode) { @@ -469,6 +463,15 @@ public abstract class Drawable { } /** + * Specify an optional color filter for the drawable. Pass {@code null} to + * remove any existing color filter. + * + * @param cf the color filter to apply, or {@code null} to remove the + * existing color filter + */ + public abstract void setColorFilter(ColorFilter cf); + + /** * Specify a color and Porter-Duff mode to be the color filter for this * drawable. */ @@ -477,6 +480,15 @@ public abstract class Drawable { } /** + * Returns the current color filter, or {@code null} if none set. + * + * @return the current color filter, or {@code null} if none set + */ + public ColorFilter getColorFilter() { + return null; + } + + /** * Removes the color filter for this drawable. */ public void clearColorFilter() { diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index aab1fd9..44584a7 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -27,11 +27,10 @@ import android.graphics.Insets; import android.graphics.NinePatch; import android.graphics.Paint; import android.graphics.PixelFormat; +import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; import android.graphics.Region; -import android.graphics.PorterDuff.Mode; -import android.graphics.drawable.BitmapDrawable.BitmapState; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.LayoutDirection; @@ -327,31 +326,53 @@ public class NinePatchDrawable extends Drawable { * clear the tint */ public void setTint(ColorStateList tint) { - mNinePatchState.mTint = tint; - if (mTintFilter == null) { - if (tint != null) { - final int color = tint.getColorForState(getState(), 0); - mTintFilter = new PorterDuffColorFilter(color, mNinePatchState.mTintMode); - } - } else { - if (tint == null) { - mTintFilter = null; - } + if (mNinePatchState.mTint != tint) { + mNinePatchState.mTint = tint; + updateTintFilter(); + invalidateSelf(); } - invalidateSelf(); + } + + /** + * Returns the tint color for this drawable. + * + * @return Color state list to use for tinting this drawable, or null if + * none set + */ + public ColorStateList getTint() { + return mNinePatchState.mTint; } /** * Specifies the blending mode used to apply tint. * * @param tintMode A Porter-Duff blending mode + * @hide Pending finalization of supported Modes */ public void setTintMode(Mode tintMode) { - mNinePatchState.mTintMode = tintMode; - if (mTintFilter != null) { - mTintFilter.setMode(tintMode); + if (mNinePatchState.mTintMode != tintMode) { + mNinePatchState.mTintMode = tintMode; + updateTintFilter(); + invalidateSelf(); + } + } + + /** + * Ensures the tint filter is consistent with the current tint color and + * mode. + */ + private void updateTintFilter() { + final ColorStateList tint = mNinePatchState.mTint; + final Mode tintMode = mNinePatchState.mTintMode; + if (tint != null && tintMode != null) { + if (mTintFilter == null) { + mTintFilter = new PorterDuffColorFilter(0, tintMode); + } else { + mTintFilter.setMode(tintMode); + } + } else { + mTintFilter = null; } - invalidateSelf(); } @Override @@ -543,7 +564,7 @@ public class NinePatchDrawable extends Drawable { final static class NinePatchState extends ConstantState { NinePatch mNinePatch; ColorStateList mTint; - Mode mTintMode; + Mode mTintMode = Mode.SRC_IN; Rect mPadding; Insets mOpticalInsets; boolean mDither; diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java index 93f2dc6..16de9f3 100644 --- a/graphics/java/android/graphics/drawable/ShapeDrawable.java +++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java @@ -16,10 +16,18 @@ package android.graphics.drawable; -import android.graphics.*; -import android.graphics.drawable.shapes.Shape; +import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.PorterDuff.Mode; +import android.graphics.PorterDuffColorFilter; +import android.graphics.Rect; +import android.graphics.Shader; +import android.graphics.drawable.shapes.Shape; import android.util.AttributeSet; import org.xmlpull.v1.XmlPullParser; @@ -28,22 +36,24 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; /** - * A Drawable object that draws primitive shapes. - * A ShapeDrawable takes a {@link android.graphics.drawable.shapes.Shape} - * object and manages its presence on the screen. If no Shape is given, then - * the ShapeDrawable will default to a - * {@link android.graphics.drawable.shapes.RectShape}. - * - * <p>This object can be defined in an XML file with the <code><shape></code> element.</p> - * - * <div class="special reference"> - * <h3>Developer Guides</h3> - * <p>For more information about how to use ShapeDrawable, read the - * <a href="{@docRoot}guide/topics/graphics/2d-graphics.html#shape-drawable"> - * Canvas and Drawables</a> document. For more information about defining a ShapeDrawable in - * XML, read the - * <a href="{@docRoot}guide/topics/resources/drawable-resource.html#Shape">Drawable Resources</a> - * document.</p></div> + * A Drawable object that draws primitive shapes. A ShapeDrawable takes a + * {@link android.graphics.drawable.shapes.Shape} object and manages its + * presence on the screen. If no Shape is given, then the ShapeDrawable will + * default to a {@link android.graphics.drawable.shapes.RectShape}. + * <p> + * This object can be defined in an XML file with the <code><shape></code> + * element. + * </p> + * <div class="special reference"> <h3>Developer Guides</h3> + * <p> + * For more information about how to use ShapeDrawable, read the <a + * href="{@docRoot}guide/topics/graphics/2d-graphics.html#shape-drawable"> + * Canvas and Drawables</a> document. For more information about defining a + * ShapeDrawable in XML, read the <a href="{@docRoot} + * guide/topics/resources/drawable-resource.html#Shape">Drawable Resources</a> + * document. + * </p> + * </div> * * @attr ref android.R.styleable#ShapeDrawablePadding_left * @attr ref android.R.styleable#ShapeDrawablePadding_top @@ -55,6 +65,7 @@ import java.io.IOException; */ public class ShapeDrawable extends Drawable { private ShapeState mShapeState; + private PorterDuffColorFilter mTintFilter; private boolean mMutated; /** @@ -63,20 +74,25 @@ public class ShapeDrawable extends Drawable { public ShapeDrawable() { this((ShapeState) null); } - + /** * Creates a ShapeDrawable with a specified Shape. - * + * * @param s the Shape that this ShapeDrawable should be */ public ShapeDrawable(Shape s) { this((ShapeState) null); - + mShapeState.mShape = s; } - + private ShapeDrawable(ShapeState state) { mShapeState = new ShapeState(state); + + if (state != null && state.mTint != null) { + final int color = state.mTint.getColorForState(getState(), 0); + mTintFilter = new PorterDuffColorFilter(color, state.mTintMode); + } } /** @@ -85,7 +101,7 @@ public class ShapeDrawable extends Drawable { public Shape getShape() { return mShapeState.mShape; } - + /** * Sets the Shape of this ShapeDrawable. */ @@ -93,19 +109,19 @@ public class ShapeDrawable extends Drawable { mShapeState.mShape = s; updateShape(); } - + /** - * Sets a ShaderFactory to which requests for a + * Sets a ShaderFactory to which requests for a * {@link android.graphics.Shader} object will be made. - * + * * @param fact an instance of your ShaderFactory implementation */ public void setShaderFactory(ShaderFactory fact) { mShapeState.mShaderFactory = fact; } - + /** - * Returns the ShaderFactory used by this ShapeDrawable for requesting a + * Returns the ShaderFactory used by this ShapeDrawable for requesting a * {@link android.graphics.Shader}. */ public ShaderFactory getShaderFactory() { @@ -118,14 +134,14 @@ public class ShapeDrawable extends Drawable { public Paint getPaint() { return mShapeState.mPaint; } - + /** * Sets padding for the shape. - * - * @param left padding for the left side (in pixels) - * @param top padding for the top (in pixels) - * @param right padding for the right side (in pixels) - * @param bottom padding for the bottom (in pixels) + * + * @param left padding for the left side (in pixels) + * @param top padding for the top (in pixels) + * @param right padding for the right side (in pixels) + * @param bottom padding for the bottom (in pixels) */ public void setPadding(int left, int top, int right, int bottom) { if ((left | top | right | bottom) == 0) { @@ -138,10 +154,10 @@ public class ShapeDrawable extends Drawable { } invalidateSelf(); } - + /** - * Sets padding for this shape, defined by a Rect object. - * Define the padding in the Rect object as: left, top, right, bottom. + * Sets padding for this shape, defined by a Rect object. Define the padding + * in the Rect object as: left, top, right, bottom. */ public void setPadding(Rect padding) { if (padding == null) { @@ -154,37 +170,37 @@ public class ShapeDrawable extends Drawable { } invalidateSelf(); } - + /** * Sets the intrinsic (default) width for this shape. - * + * * @param width the intrinsic width (in pixels) */ public void setIntrinsicWidth(int width) { mShapeState.mIntrinsicWidth = width; invalidateSelf(); } - + /** * Sets the intrinsic (default) height for this shape. - * + * * @param height the intrinsic height (in pixels) */ public void setIntrinsicHeight(int height) { mShapeState.mIntrinsicHeight = height; invalidateSelf(); } - + @Override public int getIntrinsicWidth() { return mShapeState.mIntrinsicWidth; } - + @Override public int getIntrinsicHeight() { return mShapeState.mIntrinsicHeight; } - + @Override public boolean getPadding(Rect padding) { if (mShapeState.mPadding != null) { @@ -196,14 +212,14 @@ public class ShapeDrawable extends Drawable { } private static int modulateAlpha(int paintAlpha, int alpha) { - int scale = alpha + (alpha >>> 7); // convert to 0..256 + int scale = alpha + (alpha >>> 7); // convert to 0..256 return paintAlpha * scale >>> 8; } /** - * Called from the drawable's draw() method after the canvas has been set - * to draw the shape at (0,0). Subclasses can override for special effects - * such as multiple layers, stroking, etc. + * Called from the drawable's draw() method after the canvas has been set to + * draw the shape at (0,0). Subclasses can override for special effects such + * as multiple layers, stroking, etc. */ protected void onDraw(Shape shape, Canvas canvas, Paint paint) { shape.draw(canvas, paint); @@ -211,23 +227,37 @@ public class ShapeDrawable extends Drawable { @Override public void draw(Canvas canvas) { - Rect r = getBounds(); - Paint paint = mShapeState.mPaint; + final Rect r = getBounds(); + final ShapeState state = mShapeState; + final Paint paint = state.mPaint; - int prevAlpha = paint.getAlpha(); - paint.setAlpha(modulateAlpha(prevAlpha, mShapeState.mAlpha)); + final int prevAlpha = paint.getAlpha(); + paint.setAlpha(modulateAlpha(prevAlpha, state.mAlpha)); // only draw shape if it may affect output if (paint.getAlpha() != 0 || paint.getXfermode() != null || paint.hasShadow) { - if (mShapeState.mShape != null) { - // need the save both for the translate, and for the (unknown) Shape - int count = canvas.save(); + final boolean clearColorFilter; + if (mTintFilter != null && paint.getColorFilter() == null) { + paint.setColorFilter(mTintFilter); + clearColorFilter = true; + } else { + clearColorFilter = false; + } + + if (state.mShape != null) { + // need the save both for the translate, and for the (unknown) + // Shape + final int count = canvas.save(); canvas.translate(r.left, r.top); - onDraw(mShapeState.mShape, canvas, paint); + onDraw(state.mShape, canvas, paint); canvas.restoreToCount(count); } else { canvas.drawRect(r, paint); } + + if (clearColorFilter) { + paint.setColorFilter(null); + } } // restore @@ -239,16 +269,17 @@ public class ShapeDrawable extends Drawable { return super.getChangingConfigurations() | mShapeState.mChangingConfigurations; } - + /** * Set the alpha level for this drawable [0..255]. Note that this drawable * also has a color in its paint, which has an alpha as well. These two * values are automatically combined during drawing. Thus if the color's * alpha is 75% (i.e. 192) and the drawable's alpha is 50% (i.e. 128), then - * the combined alpha that will be used during drawing will be 37.5% - * (i.e. 96). + * the combined alpha that will be used during drawing will be 37.5% (i.e. + * 96). */ - @Override public void setAlpha(int alpha) { + @Override + public void setAlpha(int alpha) { mShapeState.mAlpha = alpha; invalidateSelf(); } @@ -258,12 +289,81 @@ public class ShapeDrawable extends Drawable { return mShapeState.mAlpha; } + /** + * Specifies a tint for this drawable. + * <p> + * Setting a color filter via {@link #setColorFilter(ColorFilter)} overrides + * tint. + * + * @param tint Color state list to use for tinting this drawable, or null to + * clear the tint + */ + public void setTint(ColorStateList tint) { + if (mShapeState.mTint != tint) { + mShapeState.mTint = tint; + updateTintFilter(); + invalidateSelf(); + } + } + + /** + * Returns the tint color for this drawable. + * + * @return Color state list to use for tinting this drawable, or null if + * none set + */ + public ColorStateList getTint() { + return mShapeState.mTint; + } + + /** + * Specifies the blending mode used to apply tint. + * + * @param tintMode A Porter-Duff blending mode + * @hide Pending finalization of supported Modes + */ + public void setTintMode(Mode tintMode) { + if (mShapeState.mTintMode != tintMode) { + mShapeState.mTintMode = tintMode; + updateTintFilter(); + invalidateSelf(); + } + } + + /** + * Ensures the tint filter is consistent with the current tint color and + * mode. + */ + private void updateTintFilter() { + final ColorStateList tint = mShapeState.mTint; + final Mode tintMode = mShapeState.mTintMode; + if (tint != null && tintMode != null) { + if (mTintFilter == null) { + mTintFilter = new PorterDuffColorFilter(0, tintMode); + } else { + mTintFilter.setMode(tintMode); + } + } else { + mTintFilter = null; + } + } + + /** + * Returns the blending mode used to apply tint. + * + * @return The Porter-Duff blending mode used to apply tint. + * @hide Pending finalization of supported Modes + */ + public Mode getTintMode() { + return mShapeState.mTintMode; + } + @Override public void setColorFilter(ColorFilter cf) { mShapeState.mPaint.setColorFilter(cf); invalidateSelf(); } - + @Override public int getOpacity() { if (mShapeState.mShape == null) { @@ -294,9 +394,31 @@ public class ShapeDrawable extends Drawable { updateShape(); } + @Override + protected boolean onStateChange(int[] stateSet) { + final ColorStateList tint = mShapeState.mTint; + if (tint != null) { + final int newColor = tint.getColorForState(stateSet, 0); + final int oldColor = mTintFilter.getColor(); + if (oldColor != newColor) { + mTintFilter.setColor(newColor); + invalidateSelf(); + return true; + } + } + + return false; + } + + @Override + public boolean isStateful() { + final ShapeState s = mShapeState; + return super.isStateful() || (s.mTint != null && s.mTint.isStateful()); + } + /** - * Subclasses override this to parse custom subelements. - * If you handle it, return true, else return <em>super.inflateTag(...)</em>. + * Subclasses override this to parse custom subelements. If you handle it, + * return true, else return <em>super.inflateTag(...)</em>. */ protected boolean inflateTag(String name, Resources r, XmlPullParser parser, AttributeSet attrs) { @@ -322,7 +444,7 @@ public class ShapeDrawable extends Drawable { @Override public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs) - throws XmlPullParserException, IOException { + throws XmlPullParserException, IOException { super.inflate(r, parser, attrs); TypedArray a = r.obtainAttributes(attrs, com.android.internal.R.styleable.ShapeDrawable); @@ -343,12 +465,12 @@ public class ShapeDrawable extends Drawable { int type; final int outerDepth = parser.getDepth(); - while ((type=parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT + && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type != XmlPullParser.START_TAG) { continue; } - + final String name = parser.getName(); // call our subclass if (!inflateTag(name, r, parser, attrs)) { @@ -371,7 +493,7 @@ public class ShapeDrawable extends Drawable { } invalidateSelf(); } - + @Override public ConstantState getConstantState() { mShapeState.mChangingConfigurations = getChangingConfigurations(); @@ -408,16 +530,20 @@ public class ShapeDrawable extends Drawable { int mChangingConfigurations; Paint mPaint; Shape mShape; + ColorStateList mTint; + Mode mTintMode = Mode.SRC_IN; Rect mPadding; int mIntrinsicWidth; int mIntrinsicHeight; int mAlpha = 255; ShaderFactory mShaderFactory; - + ShapeState(ShapeState orig) { if (orig != null) { mPaint = orig.mPaint; mShape = orig.mShape; + mTint = orig.mTint; + mTintMode = orig.mTintMode; mPadding = orig.mPadding; mIntrinsicWidth = orig.mIntrinsicWidth; mIntrinsicHeight = orig.mIntrinsicHeight; @@ -427,48 +553,45 @@ public class ShapeDrawable extends Drawable { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); } } - + @Override public Drawable newDrawable() { return new ShapeDrawable(this); } - + @Override public Drawable newDrawable(Resources res) { return new ShapeDrawable(this); } - + @Override public int getChangingConfigurations() { return mChangingConfigurations; } } - + /** * Base class defines a factory object that is called each time the drawable * is resized (has a new width or height). Its resize() method returns a - * corresponding shader, or null. - * Implement this class if you'd like your ShapeDrawable to use a special - * {@link android.graphics.Shader}, such as a - * {@link android.graphics.LinearGradient}. - * + * corresponding shader, or null. Implement this class if you'd like your + * ShapeDrawable to use a special {@link android.graphics.Shader}, such as a + * {@link android.graphics.LinearGradient}. */ public static abstract class ShaderFactory { /** - * Returns the Shader to be drawn when a Drawable is drawn. - * The dimensions of the Drawable are passed because they may be needed - * to adjust how the Shader is configured for drawing. - * This is called by ShapeDrawable.setShape(). - * - * @param width the width of the Drawable being drawn + * Returns the Shader to be drawn when a Drawable is drawn. The + * dimensions of the Drawable are passed because they may be needed to + * adjust how the Shader is configured for drawing. This is called by + * ShapeDrawable.setShape(). + * + * @param width the width of the Drawable being drawn * @param height the heigh of the Drawable being drawn - * @return the Shader to be drawn + * @return the Shader to be drawn */ public abstract Shader resize(int width, int height); } - + // other subclass could wack the Shader's localmatrix based on the // resize params (e.g. scaletofit, etc.). This could be used to scale // a bitmap to fill the bounds without needing any other special casing. } - diff --git a/libs/hwui/PatchCache.cpp b/libs/hwui/PatchCache.cpp index dc0d98c..8a44604 100644 --- a/libs/hwui/PatchCache.cpp +++ b/libs/hwui/PatchCache.cpp @@ -129,7 +129,11 @@ void PatchCache::clearGarbage() { Mutex::Autolock _l(mLock); size_t count = mGarbage.size(); for (size_t i = 0; i < count; i++) { - remove(patchesToRemove, mGarbage[i]); + Res_png_9patch* patch = mGarbage[i]; + remove(patchesToRemove, patch); + // A Res_png_9patch is actually an array of byte that's larger + // than sizeof(Res_png_9patch). It must be freed as an array. + delete[] (int8_t*) patch; } mGarbage.clear(); } diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp index 9459885..5a49f38 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -395,7 +395,9 @@ void PathCache::clearGarbage() { Mutex::Autolock l(mLock); size_t count = mGarbage.size(); for (size_t i = 0; i < count; i++) { - remove(pathsToRemove, mGarbage.itemAt(i)); + const path_pair_t& pair = mGarbage.itemAt(i); + remove(pathsToRemove, pair); + delete pair.getFirst(); } mGarbage.clear(); } diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp index 457cfa9..5562f34 100644 --- a/libs/hwui/ResourceCache.cpp +++ b/libs/hwui/ResourceCache.cpp @@ -193,8 +193,9 @@ void ResourceCache::destructorLocked(SkPath* resource) { // If we're not tracking this resource, just delete it if (Caches::hasInstance()) { Caches::getInstance().pathCache.removeDeferred(resource); + } else { + delete resource; } - delete resource; return; } ref->destroyed = true; @@ -215,8 +216,9 @@ void ResourceCache::destructorLocked(const SkBitmap* resource) { // If we're not tracking this resource, just delete it if (Caches::hasInstance()) { Caches::getInstance().textureCache.removeDeferred(resource); + } else { + delete resource; } - delete resource; return; } ref->destroyed = true; @@ -253,13 +255,14 @@ void ResourceCache::destructorLocked(Res_png_9patch* resource) { ssize_t index = mCache->indexOfKey(resource); ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL; if (ref == NULL) { + // If we're not tracking this resource, just delete it if (Caches::hasInstance()) { Caches::getInstance().patchCache.removeDeferred(resource); + } else { + // A Res_png_9patch is actually an array of byte that's larger + // than sizeof(Res_png_9patch). It must be freed as an array. + delete[] (int8_t*) resource; } - // If we're not tracking this resource, just delete it - // A Res_png_9patch is actually an array of byte that's larger - // than sizeof(Res_png_9patch). It must be freed as an array. - delete[] (int8_t*) resource; return; } ref->destroyed = true; @@ -316,16 +319,18 @@ void ResourceCache::deleteResourceReferenceLocked(const void* resource, Resource SkBitmap* bitmap = (SkBitmap*) resource; if (Caches::hasInstance()) { Caches::getInstance().textureCache.removeDeferred(bitmap); + } else { + delete bitmap; } - delete bitmap; } break; case kPath: { SkPath* path = (SkPath*) resource; if (Caches::hasInstance()) { Caches::getInstance().pathCache.removeDeferred(path); + } else { + delete path; } - delete path; } break; case kShader: { @@ -336,11 +341,12 @@ void ResourceCache::deleteResourceReferenceLocked(const void* resource, Resource case kNinePatch: { if (Caches::hasInstance()) { Caches::getInstance().patchCache.removeDeferred((Res_png_9patch*) resource); + } else { + // A Res_png_9patch is actually an array of byte that's larger + // than sizeof(Res_png_9patch). It must be freed as an array. + int8_t* patch = (int8_t*) resource; + delete[] patch; } - // A Res_png_9patch is actually an array of byte that's larger - // than sizeof(Res_png_9patch). It must be freed as an array. - int8_t* patch = (int8_t*) resource; - delete[] patch; } break; case kLayer: { diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index 467f6ca..01d72d1 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -184,7 +184,9 @@ void TextureCache::clearGarbage() { Mutex::Autolock _l(mLock); size_t count = mGarbage.size(); for (size_t i = 0; i < count; i++) { - mCache.remove(mGarbage.itemAt(i)); + const SkBitmap* bitmap = mGarbage.itemAt(i); + mCache.remove(bitmap); + delete bitmap; } mGarbage.clear(); } diff --git a/media/java/android/media/IMediaController.aidl b/media/java/android/media/session/IMediaController.aidl index fc3525a..8ca0e45 100644 --- a/media/java/android/media/IMediaController.aidl +++ b/media/java/android/media/session/IMediaController.aidl @@ -13,10 +13,10 @@ * limitations under the License. */ -package android.media; +package android.media.session; import android.content.Intent; -import android.media.IMediaControllerCallback; +import android.media.session.IMediaControllerCallback; import android.os.Bundle; import android.os.IBinder; import android.view.KeyEvent; diff --git a/media/java/android/media/IMediaControllerCallback.aidl b/media/java/android/media/session/IMediaControllerCallback.aidl index b54d0cf..3aa0ee4 100644 --- a/media/java/android/media/IMediaControllerCallback.aidl +++ b/media/java/android/media/session/IMediaControllerCallback.aidl @@ -13,7 +13,7 @@ * limitations under the License. */ -package android.media; +package android.media.session; import android.os.Bundle; diff --git a/media/java/android/media/IMediaSession.aidl b/media/java/android/media/session/IMediaSession.aidl index ed71d78..19f7092 100644 --- a/media/java/android/media/IMediaSession.aidl +++ b/media/java/android/media/session/IMediaSession.aidl @@ -13,9 +13,9 @@ * limitations under the License. */ -package android.media; +package android.media.session; -import android.media.IMediaController; +import android.media.session.IMediaController; import android.os.Bundle; /** diff --git a/media/java/android/media/IMediaSessionCallback.aidl b/media/java/android/media/session/IMediaSessionCallback.aidl index 3aaf925..eb5f222 100644 --- a/media/java/android/media/IMediaSessionCallback.aidl +++ b/media/java/android/media/session/IMediaSessionCallback.aidl @@ -13,7 +13,7 @@ * limitations under the License. */ -package android.media; +package android.media.session; import android.content.Intent; import android.os.Bundle; diff --git a/media/java/android/media/IMediaSessionManager.aidl b/media/java/android/media/session/IMediaSessionManager.aidl index 8bc0c3b..0b4328e 100644 --- a/media/java/android/media/IMediaSessionManager.aidl +++ b/media/java/android/media/session/IMediaSessionManager.aidl @@ -13,10 +13,10 @@ * limitations under the License. */ -package android.media; +package android.media.session; -import android.media.IMediaSession; -import android.media.IMediaSessionCallback; +import android.media.session.IMediaSession; +import android.media.session.IMediaSessionCallback; import android.os.Bundle; /** diff --git a/media/java/android/media/MediaController.java b/media/java/android/media/session/MediaController.java index 1e99942..09de859 100644 --- a/media/java/android/media/MediaController.java +++ b/media/java/android/media/session/MediaController.java @@ -14,9 +14,13 @@ * limitations under the License. */ -package android.media; +package android.media.session; import android.content.Intent; +import android.media.session.IMediaController; +import android.media.session.IMediaControllerCallback; +import android.media.MediaMetadataRetriever; +import android.media.RemoteControlClient; import android.os.Bundle; import android.os.Handler; import android.os.Looper; diff --git a/media/java/android/media/MediaSession.java b/media/java/android/media/session/MediaSession.java index 5e5c9fa..1f1533b 100644 --- a/media/java/android/media/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -14,10 +14,13 @@ * limitations under the License. */ -package android.media; +package android.media.session; import android.content.Intent; -import android.media.IMediaSession; +import android.media.session.IMediaController; +import android.media.session.IMediaSession; +import android.media.session.IMediaSessionCallback; +import android.media.RemoteControlClient; import android.os.Bundle; import android.os.Handler; import android.os.Looper; diff --git a/media/java/android/media/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java index 90f0071..e3f2d9c 100644 --- a/media/java/android/media/MediaSessionManager.java +++ b/media/java/android/media/session/MediaSessionManager.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package android.media; +package android.media.session; import android.content.Context; +import android.media.session.IMediaSessionManager; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; diff --git a/media/java/android/media/MediaSessionToken.aidl b/media/java/android/media/session/MediaSessionToken.aidl index e2f1abc..5812682 100644 --- a/media/java/android/media/MediaSessionToken.aidl +++ b/media/java/android/media/session/MediaSessionToken.aidl @@ -13,6 +13,6 @@ ** limitations under the License. */ -package android.media; +package android.media.session; parcelable MediaSessionToken; diff --git a/media/java/android/media/MediaSessionToken.java b/media/java/android/media/session/MediaSessionToken.java index 885fda3..dbb4964 100644 --- a/media/java/android/media/MediaSessionToken.java +++ b/media/java/android/media/session/MediaSessionToken.java @@ -14,8 +14,9 @@ * limitations under the License. */ -package android.media; +package android.media.session; +import android.media.session.IMediaController; import android.os.Parcel; import android.os.Parcelable; diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index 86105ea..c73d90a 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -29,8 +29,6 @@ import android.transition.Scene; import android.transition.Transition; import android.transition.TransitionInflater; import android.transition.TransitionManager; -import android.transition.TransitionSet; -import android.util.ArrayMap; import android.view.ViewConfiguration; import com.android.internal.R; @@ -107,9 +105,6 @@ import android.widget.TextView; import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; /** * Android-specific Window. @@ -125,13 +120,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private static final long MAX_TRANSITION_START_WAIT = 500; private static final long MAX_TRANSITION_FINISH_WAIT = 1000; - private static final String KEY_SCREEN_X = "shared_element:screenX"; - private static final String KEY_SCREEN_Y = "shared_element:screenY"; - private static final String KEY_TRANSLATION_Z = "shared_element:translationZ"; - private static final String KEY_WIDTH = "shared_element:width"; - private static final String KEY_HEIGHT = "shared_element:height"; - private static final String KEY_NAME = "shared_element:name"; - /** * Simple callback used by the context menu and its submenus. The options * menu submenus do not use this (their behavior is more complex). @@ -251,8 +239,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private ActivityOptions mActivityOptions; private SceneTransitionListener mSceneTransitionListener; - private boolean mTriggerEarly = true; - private Map<String, String> mSharedElementsMap; + private boolean mFadeEarly = true; static class WindowManagerHolder { static final IWindowManager sWindowManager = IWindowManager.Stub.asInterface( @@ -2575,11 +2562,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { return super.fitSystemWindows(insets); } - @Override - public boolean isTransitionGroup() { - return false; - } - private void updateStatusGuard(Rect insets) { boolean showStatusGuard = false; // Show the status guard when the non-overlay contextual action bar is showing @@ -4006,196 +3988,78 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } @Override - public void setTriggerEarlyEnterTransition(boolean triggerEarly) { - mTriggerEarly = triggerEarly; + public void setEarlyBackgroundTransition(boolean fadeEarly) { + mFadeEarly = fadeEarly; } @Override - public void mapTransitionTargets(Map<String, String> sharedElementNames) { - mSharedElementsMap = sharedElementNames; - } - - @Override - public Bundle startExitTransition(Map<String, View> sharedElements) { - if (mContentScene == null) { - return null; - } - Transition transition = mTransitionManager.getExitTransition(mContentScene); + public void startExitTransition(ActivityOptions activityOptions) { + Transition transition = mTransitionManager.getNamedTransition(getContentScene(), "null"); if (transition == null) { - return null; + transition = TransitionManager.getDefaultTransition().clone(); } - - // Find exiting Views and shared elements - final ArrayList<View> transitioningViews = new ArrayList<View>(); - mDecor.captureTransitioningViews(transitioningViews); - transitioningViews.removeAll(sharedElements.values()); - - Transition exitTransition = cloneAndSetTransitionTargets(transition, - transitioningViews, true); - Transition sharedElementTransition = cloneAndSetTransitionTargets(transition, - transitioningViews, false); - - // transitionSet is the total exit transition, including hero animation. - TransitionSet transitionSet = new TransitionSet(); - transitionSet.addTransition(exitTransition); - transitionSet.addTransition(sharedElementTransition); - - ActivityOptions activityOptions = createExitActivityOptions(sharedElements, - sharedElementTransition, exitTransition); - - // Start exiting the Views that need to exit - TransitionManager.beginDelayedTransition(mDecor, transitionSet); - setViewVisibility(transitioningViews, View.INVISIBLE); - - return activityOptions.toBundle(); - } - - private ActivityOptions createExitActivityOptions(final Map<String, View> sharedElements, - Transition sharedElementTransition, Transition exitTransition) { - - // Schedule capturing of the shared element state - final Bundle sharedElementArgs = new Bundle(); - captureTerminalSharedElementState(sharedElements, sharedElementArgs); - - ActivityOptions.SharedElementSource sharedElementSource - = new ActivityOptions.SharedElementSource() { + activityOptions.setExitTransition(transition, new ActivityOptions.SharedElementSource() { @Override - public Bundle getSharedElementExitState() { - return sharedElementArgs; - } - - @Override - public void acceptedSharedElements(ArrayList<String> sharedElementNames) { - if (sharedElementNames.size() == sharedElements.size()) { - return; // They were all accepted - } - Transition transition = mTransitionManager.getExitTransition(mContentScene).clone(); - TransitionManager.beginDelayedTransition(mDecor, transition); - for (String name: sharedElements.keySet()) { - if (!sharedElementNames.contains(name)) { - sharedElements.get(name).setVisibility(View.INVISIBLE); - } - } - sharedElements.keySet().retainAll(sharedElementNames); - } - - @Override - public void hideSharedElements() { - if (sharedElements != null) { - setViewVisibility(sharedElements.values(), View.INVISIBLE); - } - } - }; - - ArrayList<String> names = new ArrayList<String>(sharedElements.keySet()); - return ActivityOptions.makeSceneTransitionAnimation( - exitTransition, names, sharedElementTransition, sharedElementSource); - } - - private void captureTerminalSharedElementState(final Map<String, View> sharedElements, - final Bundle sharedElementArgs) { - mDecor.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - mDecor.getViewTreeObserver().removeOnPreDrawListener(this); - int[] tempLoc = new int[2]; - for (String name: sharedElements.keySet()) { - View sharedElement = sharedElements.get(name); - captureSharedElementState(sharedElement, name, sharedElementArgs, tempLoc); - } - return true; + public int getTextureId() { + // TODO: move shared elements to a layer and return the texture id + recurseHideExitingSharedElements(mContentParent); + return 0; } }); + ViewGroup sceneRoot = getContentScene().getSceneRoot(); + TransitionManager.beginDelayedTransition(sceneRoot, transition); + recurseExitNonSharedElements(mContentParent); } - private static Transition cloneAndSetTransitionTargets(Transition transition, - List<View> views, boolean add) { - transition = transition.clone(); - if (!transition.getTargetIds().isEmpty() || !transition.getTargets().isEmpty()) { - TransitionSet set = new TransitionSet(); - set.addTransition(transition); - transition = set; - } - for (View view: views) { - if (add) { - transition.addTarget(view); + private static void recurseExitNonSharedElements(ViewGroup viewGroup) { + int numChildren = viewGroup.getChildCount(); + for (int i = 0; i < numChildren; i++) { + View child = viewGroup.getChildAt(i); + if (child.getSharedElementName() != null || (child.getVisibility() != View.VISIBLE)) { + continue; + } + if (child instanceof ViewGroup && !((ViewGroup)child).isTransitionGroup()) { + recurseExitNonSharedElements((ViewGroup) child); } else { - transition.excludeTarget(view, true); + child.setVisibility(View.INVISIBLE); } } - return transition; } - private static void setViewVisibility(Collection<View> views, int visibility) { - for (View view : views) { - view.setVisibility(visibility); + private static void recurseHideViews(ViewGroup viewGroup, ArrayList<View> nonSharedElements, + ArrayList<View> sharedElements) { + int numChildren = viewGroup.getChildCount(); + for (int i = 0; i < numChildren; i++) { + View child = viewGroup.getChildAt(i); + if (child.getVisibility() != View.VISIBLE) { + continue; + } + if (child.getSharedElementName() != null) { + sharedElements.add(child); + child.setVisibility(View.INVISIBLE); + } else if (child instanceof ViewGroup && !((ViewGroup)child).isTransitionGroup()) { + recurseHideViews((ViewGroup) child, nonSharedElements, sharedElements); + } else { + nonSharedElements.add(child); + child.setVisibility(View.INVISIBLE); + } } } - /** - * Sets the captured values from a previous - * {@link #captureSharedElementState(android.view.View, String, android.os.Bundle, int[])} - * @param view The View to apply placement changes to. - * @param name The shared element name given from the source Activity. - * @param transitionArgs A <code>Bundle</code> containing all placementinformation for named - * shared elements in the scene. - * @param tempLoc A temporary int[2] for capturing the current location of views. - */ - private static void setSharedElementState(View view, String name, Bundle transitionArgs, - int[] tempLoc) { - Bundle sharedElementBundle = transitionArgs.getBundle(name); - if (sharedElementBundle == null) { - return; + private static void recurseHideExitingSharedElements(ViewGroup viewGroup) { + int numChildren = viewGroup.getChildCount(); + for (int i = 0; i < numChildren; i++) { + View child = viewGroup.getChildAt(i); + if (child.getVisibility() != View.VISIBLE) { + continue; + } + if (child.getSharedElementName() != null) { + child.setVisibility(View.INVISIBLE); + } else if (child instanceof ViewGroup) { + ViewGroup childViewGroup = (ViewGroup) child; + recurseHideExitingSharedElements(childViewGroup); + } } - - int x = sharedElementBundle.getInt(KEY_SCREEN_X); - view.getLocationOnScreen(tempLoc); - int offsetX = x - tempLoc[0]; - view.offsetLeftAndRight(offsetX); - - int width = sharedElementBundle.getInt(KEY_WIDTH); - view.setRight(view.getLeft() + width); - - int y = sharedElementBundle.getInt(KEY_SCREEN_Y); - int offsetY = y - tempLoc[1]; - view.offsetTopAndBottom(offsetY); - - int height = sharedElementBundle.getInt(KEY_HEIGHT); - view.setBottom(view.getTop() + height); - - float z = sharedElementBundle.getFloat(KEY_TRANSLATION_Z); - view.setTranslationZ(z); - } - - /** - * Captures placement information for Views with a shared element name for - * Activity Transitions. - * @param view The View to capture the placement information for. - * @param name The shared element name in the target Activity to apply the placement - * information for. - * @param transitionArgs Bundle to store shared element placement information. - * @param tempLoc A temporary int[2] for capturing the current location of views. - * @see #setSharedElementState(android.view.View, String, android.os.Bundle, int[]) - */ - private static void captureSharedElementState(View view, String name, Bundle transitionArgs, - int[] tempLoc) { - Bundle sharedElementBundle = new Bundle(); - view.getLocationOnScreen(tempLoc); - float scaleX = view.getScaleX(); - sharedElementBundle.putInt(KEY_SCREEN_X, tempLoc[0]); - int width = Math.round(view.getWidth() * scaleX); - sharedElementBundle.putInt(KEY_WIDTH, width); - - float scaleY = view.getScaleY(); - sharedElementBundle.putInt(KEY_SCREEN_Y, tempLoc[1]); - int height= Math.round(view.getHeight() * scaleY); - sharedElementBundle.putInt(KEY_HEIGHT, height); - - sharedElementBundle.putFloat(KEY_TRANSLATION_Z, view.getTranslationZ()); - - sharedElementBundle.putString(KEY_NAME, view.getSharedElementName()); - - transitionArgs.putBundle(name, sharedElementBundle); } /** @@ -4216,57 +4080,46 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private boolean mAllDone; private Handler mHandler = new Handler(); private boolean mEnterTransitionStarted; - private ArrayMap<String, View> mSharedElementTargets = new ArrayMap<String, View>(); - private ArrayList<View> mEnteringViews = new ArrayList<View>(); + private ArrayList<View> mSharedElements = new ArrayList<View>(); public EnterScene() { mSceneTransitionListener.nullPendingTransition(); Drawable background = getDecorView().getBackground(); if (background != null) { + setBackgroundDrawable(null); background.setAlpha(0); - mDecor.drawableChanged(); + setBackgroundDrawable(background); } mSceneTransitionListener.convertToTranslucent(); } @Override public boolean onPreDraw() { - ViewTreeObserver observer = mDecor.getViewTreeObserver(); + ViewTreeObserver observer = mContentParent.getViewTreeObserver(); observer.removeOnPreDrawListener(this); if (!mEnterTransitionStarted && mSceneTransitionListener != null) { mEnterTransitionStarted = true; - mDecor.captureTransitioningViews(mEnteringViews); - ArrayList<String> sharedElementNames = mActivityOptions.getSharedElementNames(); - if (sharedElementNames != null) { - mDecor.findSharedElements(mSharedElementTargets); - if (mSharedElementsMap != null) { - for (Map.Entry<String, String> entry : mSharedElementsMap.entrySet()) { - View sharedElement = mSharedElementTargets.remove(entry.getValue()); - if (sharedElement != null) { - mSharedElementTargets.put(entry.getKey(), sharedElement); - } - } - } - mSharedElementTargets.keySet().retainAll(sharedElementNames); - mEnteringViews.removeAll(mSharedElementTargets.values()); + ArrayList<View> enteringViews = new ArrayList<View>(); + recurseHideViews(mContentParent, enteringViews, mSharedElements); + Transition transition = getTransitionManager().getNamedTransition("null", + mContentScene); + if (transition == null) { + transition = TransitionManager.getDefaultTransition().clone(); } - - setViewVisibility(mEnteringViews, View.INVISIBLE); - setViewVisibility(mSharedElementTargets.values(), View.INVISIBLE); - if (mTriggerEarly) { - beginEnterScene(); + TransitionManager.beginDelayedTransition(mContentParent, transition); + for (View hidden : enteringViews) { + hidden.setVisibility(View.VISIBLE); } observer.addOnPreDrawListener(this); } else { mHandler.postDelayed(this, MAX_TRANSITION_START_WAIT); - mActivityOptions.dispatchSceneTransitionStarted(this, - new ArrayList<String>(mSharedElementTargets.keySet())); + mActivityOptions.dispatchSceneTransitionStarted(this); } return true; } public void start() { - ViewTreeObserver observer = mDecor.getViewTreeObserver(); + ViewTreeObserver observer = mContentParent.getViewTreeObserver(); observer.addOnPreDrawListener(this); } @@ -4276,43 +4129,25 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } @Override - public void sharedElementTransitionComplete(Bundle transitionArgs) { + public void sharedElementTransitionComplete() { if (!mSharedElementReadyReceived) { mSharedElementReadyReceived = true; mHandler.removeCallbacks(this); mHandler.postDelayed(this, MAX_TRANSITION_FINISH_WAIT); - if (!mSharedElementTargets.isEmpty()) { - Transition transition = getTransitionManager().getEnterTransition( - mContentScene); - if (transition == null) { - transition = TransitionManager.getDefaultTransition(); - } - transition = transition.clone(); - if (transitionArgs == null) { - TransitionManager.beginDelayedTransition(mDecor, transition); - setViewVisibility(mSharedElementTargets.values(), View.VISIBLE); - } else { - int[] tempLoc = new int[2]; - for (Map.Entry<String, View> entry: mSharedElementTargets.entrySet()) { - setSharedElementState(entry.getValue(), entry.getKey(), transitionArgs, - tempLoc); - } - setViewVisibility(mSharedElementTargets.values(), View.VISIBLE); - mSceneTransitionListener.sharedElementStart(transition); - mDecor.getViewTreeObserver().addOnPreDrawListener( - new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - mDecor.getViewTreeObserver().removeOnPreDrawListener(this); - mSceneTransitionListener.sharedElementEnd(); - mActivityOptions.dispatchSharedElementsReady(); - return true; - } - }); - TransitionManager.beginDelayedTransition(mDecor, transition); - } + for (View sharedElement: mSharedElements) { + sharedElement.setVisibility(View.VISIBLE); } - if (mTriggerEarly) { + mSharedElements.clear(); + mContentParent.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + mContentParent.getViewTreeObserver().removeOnPreDrawListener(this); + mSceneTransitionListener.enterSharedElement( + mActivityOptions.getSceneTransitionArgs()); + return false; + } + }); + if (mFadeEarly) { fadeInBackground(); } } @@ -4335,10 +4170,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { return; } mAllDone = true; - sharedElementTransitionComplete(null); + sharedElementTransitionComplete(); mHandler.removeCallbacks(this); - if (!mTriggerEarly) { - beginEnterScene(); + if (!mFadeEarly) { fadeInBackground(); } } @@ -4359,14 +4193,5 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { @Override public void onAnimationRepeat(Animator animation) { } - - private void beginEnterScene() { - Transition transition = getTransitionManager().getEnterTransition(mContentScene); - if (transition == null) { - transition = TransitionManager.getDefaultTransition().clone(); - } - TransitionManager.beginDelayedTransition(mDecor, transition); - setViewVisibility(mEnteringViews, View.VISIBLE); - } } } diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index 0ebbd8a..cb5946a 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -656,6 +656,7 @@ public final class BatteryService extends Binder { long ident = Binder.clearCallingIdentity(); try { if (mUpdatesStopped) { + mUpdatesStopped = false; mBatteryProps.set(mLastBatteryProps); processValuesLocked(); } diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index 95bfd2f..e43dea9 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -154,7 +154,7 @@ public class SyncManager { private static final int INITIALIZATION_UNBIND_DELAY_MS = 5000; - private static final String SYNC_WAKE_LOCK_PREFIX = "*sync*"; + private static final String SYNC_WAKE_LOCK_PREFIX = "*sync*/"; private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarm"; private static final String SYNC_LOOP_WAKE_LOCK = "SyncLoopWakeLock"; @@ -1210,9 +1210,9 @@ public class SyncManager { mBound = false; } else { try { - mEventName = serviceComponent.flattenToShortString(); + mEventName = mSyncOperation.wakeLockName(); mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_SYNC_START, - serviceComponent.flattenToShortString(), mSyncAdapterUid); + mEventName, mSyncAdapterUid); } catch (RemoteException e) { } } @@ -1927,10 +1927,10 @@ public class SyncManager { } private PowerManager.WakeLock getSyncWakeLock(SyncOperation operation) { - final String wakeLockKey = operation.wakeLockKey(); + final String wakeLockKey = operation.wakeLockName(); PowerManager.WakeLock wakeLock = mWakeLocks.get(wakeLockKey); if (wakeLock == null) { - final String name = SYNC_WAKE_LOCK_PREFIX + operation.wakeLockName(); + final String name = SYNC_WAKE_LOCK_PREFIX + wakeLockKey; wakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, name); wakeLock.setReferenceCounted(false); mWakeLocks.put(wakeLockKey, wakeLock); diff --git a/services/core/java/com/android/server/content/SyncOperation.java b/services/core/java/com/android/server/content/SyncOperation.java index 036b21f..5233014 100644 --- a/services/core/java/com/android/server/content/SyncOperation.java +++ b/services/core/java/com/android/server/content/SyncOperation.java @@ -86,6 +86,9 @@ public class SyncOperation implements Comparable { /** Amount of time before {@link #effectiveRunTime} from which this sync can run. */ public long flexTime; + /** Descriptive string key for this operation */ + public String wakeLockName; + public SyncOperation(Account account, int userId, int reason, int source, String provider, Bundle extras, long runTimeFromNow, long flexTime, long backoff, long delayUntil, boolean allowParallelSyncs) { @@ -308,25 +311,17 @@ public class SyncOperation implements Comparable { sb.append("]"); } - public String wakeLockKey() { - if (target.target_provider) { - return target.account.name + "/" + target.account.type + ":" + target.provider; - } else if (target.target_service) { - return target.service.getPackageName() + "/" + target.service.getClassName(); - } else { - Log.wtf(TAG, "Invalid target getting wakelock for operation - " + key); - return null; - } - } - public String wakeLockName() { + if (wakeLockName != null) { + return wakeLockName; + } if (target.target_provider) { - return "/" + target.provider + return (wakeLockName = target.provider + "/" + target.account.type - + "/" + target.account.name; + + "/" + target.account.name); } else if (target.target_service) { - return "/" + target.service.getPackageName() - + "/" + target.service.getClassName(); + return (wakeLockName = target.service.getPackageName() + + "/" + target.service.getClassName()); } else { Log.wtf(TAG, "Invalid target getting wakelock name for operation - " + key); return null; diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 0d3fa84..89acec9 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -17,10 +17,10 @@ package com.android.server.media; import android.content.Intent; -import android.media.IMediaController; -import android.media.IMediaControllerCallback; -import android.media.IMediaSession; -import android.media.IMediaSessionCallback; +import android.media.session.IMediaController; +import android.media.session.IMediaControllerCallback; +import android.media.session.IMediaSession; +import android.media.session.IMediaSessionCallback; import android.media.RemoteControlClient; import android.os.Bundle; import android.os.IBinder; diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 9c96c35..a7ff926 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -17,9 +17,9 @@ package com.android.server.media; import android.content.Context; -import android.media.IMediaSession; -import android.media.IMediaSessionCallback; -import android.media.IMediaSessionManager; +import android.media.session.IMediaSession; +import android.media.session.IMediaSessionCallback; +import android.media.session.IMediaSessionManager; import android.os.Binder; import android.os.RemoteException; import android.text.TextUtils; diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 93f6d22..0b19b5c 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -669,10 +669,15 @@ class WindowStateAnimator { int flags = SurfaceControl.HIDDEN; final WindowManager.LayoutParams attrs = mWin.mAttrs; + final boolean isVideoPlane = + (attrs.privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_VIDEO_PLANE) != 0; if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) { flags |= SurfaceControl.SECURE; } + if (isVideoPlane) { + flags |= SurfaceControl.FX_SURFACE_VIDEO_PLANE; + } if (DEBUG_VISIBILITY) Slog.v( TAG, "Creating surface in session " + mSession.mSurfaceSession + " window " + this diff --git a/tests/OneMedia/src/com/android/onemedia/IPlayerCallback.aidl b/tests/OneMedia/src/com/android/onemedia/IPlayerCallback.aidl index 9bc3baa..2b14384 100644 --- a/tests/OneMedia/src/com/android/onemedia/IPlayerCallback.aidl +++ b/tests/OneMedia/src/com/android/onemedia/IPlayerCallback.aidl @@ -12,10 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + package com.android.onemedia; -import android.media.MediaSessionToken; +import android.media.session.MediaSessionToken; interface IPlayerCallback { void onSessionChanged(in MediaSessionToken session); diff --git a/tests/OneMedia/src/com/android/onemedia/IPlayerService.aidl b/tests/OneMedia/src/com/android/onemedia/IPlayerService.aidl index ab1d3fc..efdbe9a 100644 --- a/tests/OneMedia/src/com/android/onemedia/IPlayerService.aidl +++ b/tests/OneMedia/src/com/android/onemedia/IPlayerService.aidl @@ -12,17 +12,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + package com.android.onemedia; -import android.media.MediaSessionToken; +import android.media.session.MediaSessionToken; import android.os.Bundle; import com.android.onemedia.IPlayerCallback; import com.android.onemedia.playback.IRequestCallback; interface IPlayerService { - MediaSessionToken getSessionToken(); + MediaSessionToken getSessionToken(); void registerCallback(in IPlayerCallback cb); void unregisterCallback(in IPlayerCallback cb); void sendRequest(String action, in Bundle params, in IRequestCallback cb); diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerController.java b/tests/OneMedia/src/com/android/onemedia/PlayerController.java index 4ccc846..3f15db5 100644 --- a/tests/OneMedia/src/com/android/onemedia/PlayerController.java +++ b/tests/OneMedia/src/com/android/onemedia/PlayerController.java @@ -1,8 +1,8 @@ package com.android.onemedia; -import android.media.MediaController; -import android.media.MediaSessionManager; +import android.media.session.MediaController; +import android.media.session.MediaSessionManager; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerService.java b/tests/OneMedia/src/com/android/onemedia/PlayerService.java index 0819077..0b2ba8f 100644 --- a/tests/OneMedia/src/com/android/onemedia/PlayerService.java +++ b/tests/OneMedia/src/com/android/onemedia/PlayerService.java @@ -2,7 +2,7 @@ package com.android.onemedia; import android.app.Service; import android.content.Intent; -import android.media.MediaSessionToken; +import android.media.session.MediaSessionToken; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java index 25a8f0d..e5fb0d0 100644 --- a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java +++ b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java @@ -2,9 +2,9 @@ package com.android.onemedia; import android.content.Context; import android.content.Intent; -import android.media.MediaSession; -import android.media.MediaSessionManager; -import android.media.MediaSessionToken; +import android.media.session.MediaSession; +import android.media.session.MediaSessionManager; +import android.media.session.MediaSessionToken; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h index cbeaae8..49b8b55 100644 --- a/tools/aapt/Bundle.h +++ b/tools/aapt/Bundle.h @@ -59,10 +59,10 @@ public: mAndroidManifestFile(NULL), mPublicOutputFile(NULL), mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL), mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL), - mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL), mExtraPackages(NULL), - mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), mProduct(NULL), - mUseCrunchCache(false), mErrorOnFailedInsert(false), mErrorOnMissingConfigEntry(false), - mOutputTextSymbols(NULL), + mVersionCode(NULL), mVersionName(NULL), mReplaceVersion(false), mCustomPackage(NULL), + mExtraPackages(NULL), mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), + mProduct(NULL), mUseCrunchCache(false), mErrorOnFailedInsert(false), + mErrorOnMissingConfigEntry(false), mOutputTextSymbols(NULL), mSingleCrunchInputFile(NULL), mSingleCrunchOutputFile(NULL), mArgc(0), mArgv(NULL) {} @@ -166,6 +166,8 @@ public: void setVersionCode(const char* val) { mVersionCode = val; } const char* getVersionName() const { return mVersionName; } void setVersionName(const char* val) { mVersionName = val; } + bool getReplaceVersion() { return mReplaceVersion; } + void setReplaceVersion(bool val) { mReplaceVersion = val; } const char* getCustomPackage() const { return mCustomPackage; } void setCustomPackage(const char* val) { mCustomPackage = val; } const char* getExtraPackages() const { return mExtraPackages; } @@ -285,6 +287,7 @@ private: const char* mMaxSdkVersion; const char* mVersionCode; const char* mVersionName; + bool mReplaceVersion; const char* mCustomPackage; const char* mExtraPackages; const char* mMaxResVersion; diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp index 1ed4630..33711fa 100644 --- a/tools/aapt/Main.cpp +++ b/tools/aapt/Main.cpp @@ -153,6 +153,11 @@ void usage(void) " inserts android:versionCode in to manifest.\n" " --version-name\n" " inserts android:versionName in to manifest.\n" + " --replace-version\n" + " If --version-code and/or --version-name are specified, these\n" + " values will replace any value already in the manifest. By\n" + " default, nothing is changed if the manifest already defines\n" + " these attributes.\n" " --custom-package\n" " generates R.java into a different package.\n" " --extra-packages\n" @@ -532,6 +537,8 @@ int main(int argc, char* const argv[]) goto bail; } bundle.setVersionName(argv[0]); + } else if (strcmp(cp, "-replace-version") == 0) { + bundle.setReplaceVersion(true); } else if (strcmp(cp, "-values") == 0) { bundle.setValues(true); } else if (strcmp(cp, "-include-meta-data") == 0) { diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp index c923bc2..6d9d62e 100644 --- a/tools/aapt/Resource.cpp +++ b/tools/aapt/Resource.cpp @@ -676,13 +676,15 @@ static bool applyFileOverlay(Bundle *bundle, } /* - * Inserts an attribute in a given node, only if the attribute does not - * exist. + * Inserts an attribute in a given node. * If errorOnFailedInsert is true, and the attribute already exists, returns false. - * Returns true otherwise, even if the attribute already exists. + * If replaceExisting is true, the attribute will be updated if it already exists. + * Returns true otherwise, even if the attribute already exists, and does not modify + * the existing attribute's value. */ bool addTagAttribute(const sp<XMLNode>& node, const char* ns8, - const char* attr8, const char* value, bool errorOnFailedInsert) + const char* attr8, const char* value, bool errorOnFailedInsert, + bool replaceExisting) { if (value == NULL) { return true; @@ -691,7 +693,16 @@ bool addTagAttribute(const sp<XMLNode>& node, const char* ns8, const String16 ns(ns8); const String16 attr(attr8); - if (node->getAttribute(ns, attr) != NULL) { + XMLNode::attribute_entry* existingEntry = node->editAttribute(ns, attr); + if (existingEntry != NULL) { + if (replaceExisting) { + NOISY(printf("Info: AndroidManifest.xml already defines %s (in %s);" + " overwriting existing value from manifest.\n", + String8(attr).string(), String8(ns).string())); + existingEntry->string = String16(value); + return true; + } + if (errorOnFailedInsert) { fprintf(stderr, "Error: AndroidManifest.xml already defines %s (in %s);" " cannot insert new value %s.\n", @@ -711,6 +722,18 @@ bool addTagAttribute(const sp<XMLNode>& node, const char* ns8, return true; } +/* + * Inserts an attribute in a given node, only if the attribute does not + * exist. + * If errorOnFailedInsert is true, and the attribute already exists, returns false. + * Returns true otherwise, even if the attribute already exists. + */ +bool addTagAttribute(const sp<XMLNode>& node, const char* ns8, + const char* attr8, const char* value, bool errorOnFailedInsert) +{ + return addTagAttribute(node, ns8, attr8, value, errorOnFailedInsert, false); +} + static void fullyQualifyClassName(const String8& package, sp<XMLNode> node, const String16& attrName) { XMLNode::attribute_entry* attr = node->editAttribute( @@ -748,13 +771,14 @@ status_t massageManifest(Bundle* bundle, sp<XMLNode> root) } bool errorOnFailedInsert = bundle->getErrorOnFailedInsert(); + bool replaceVersion = bundle->getReplaceVersion(); if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionCode", - bundle->getVersionCode(), errorOnFailedInsert)) { + bundle->getVersionCode(), errorOnFailedInsert, replaceVersion)) { return UNKNOWN_ERROR; } if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionName", - bundle->getVersionName(), errorOnFailedInsert)) { + bundle->getVersionName(), errorOnFailedInsert, replaceVersion)) { return UNKNOWN_ERROR; } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java index 281337c..a90632c 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java @@ -39,7 +39,7 @@ public class BridgePowerManager implements IPowerManager { } @Override - public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3) + public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3, String arg4) throws RemoteException { // pass for now. } diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 4a6b1ff..84e933d 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -20,6 +20,8 @@ import android.net.wifi.BatchedScanResult; import android.net.wifi.BatchedScanSettings; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; +import android.net.wifi.ScanSettings; +import android.net.wifi.WifiChannel; import android.net.wifi.ScanResult; import android.net.DhcpInfo; @@ -45,7 +47,9 @@ interface IWifiManager boolean pingSupplicant(); - void startScan(in WorkSource ws); + List<WifiChannel> getChannelList(); + + void startScan(in ScanSettings requested, in WorkSource ws); List<ScanResult> getScanResults(String callingPackage); diff --git a/wifi/java/android/net/wifi/ScanSettings.aidl b/wifi/java/android/net/wifi/ScanSettings.aidl new file mode 100644 index 0000000..ebd2a39 --- /dev/null +++ b/wifi/java/android/net/wifi/ScanSettings.aidl @@ -0,0 +1,19 @@ +/** + * 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.net.wifi; + +parcelable ScanSettings; diff --git a/wifi/java/android/net/wifi/ScanSettings.java b/wifi/java/android/net/wifi/ScanSettings.java new file mode 100644 index 0000000..094ce34 --- /dev/null +++ b/wifi/java/android/net/wifi/ScanSettings.java @@ -0,0 +1,87 @@ +/* + * 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.net.wifi; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * Bundle of customized scan settings + * + * @see WifiManager#startCustomizedScan + * + * @hide + */ +public class ScanSettings implements Parcelable { + + /** channel set to scan. this can be null or empty, indicating a full scan */ + public Collection<WifiChannel> channelSet; + + /** public constructor */ + public ScanSettings() { } + + /** copy constructor */ + public ScanSettings(ScanSettings source) { + if (source.channelSet != null) + channelSet = new ArrayList<WifiChannel>(source.channelSet); + } + + /** check for validity */ + public boolean isValid() { + for (WifiChannel channel : channelSet) + if (!channel.isValid()) return false; + return true; + } + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** implement Parcelable interface */ + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(channelSet == null ? 0 : channelSet.size()); + if (channelSet != null) + for (WifiChannel channel : channelSet) channel.writeToParcel(out, flags); + } + + /** implement Parcelable interface */ + public static final Parcelable.Creator<ScanSettings> CREATOR = + new Parcelable.Creator<ScanSettings>() { + @Override + public ScanSettings createFromParcel(Parcel in) { + ScanSettings settings = new ScanSettings(); + int size = in.readInt(); + if (size > 0) { + settings.channelSet = new ArrayList<WifiChannel>(size); + while (size-- > 0) + settings.channelSet.add(WifiChannel.CREATOR.createFromParcel(in)); + } + return settings; + } + + @Override + public ScanSettings[] newArray(int size) { + return new ScanSettings[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/WifiChannel.aidl b/wifi/java/android/net/wifi/WifiChannel.aidl new file mode 100644 index 0000000..c3d06bd --- /dev/null +++ b/wifi/java/android/net/wifi/WifiChannel.aidl @@ -0,0 +1,19 @@ +/** + * 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.net.wifi; + +parcelable WifiChannel; diff --git a/wifi/java/android/net/wifi/WifiChannel.java b/wifi/java/android/net/wifi/WifiChannel.java new file mode 100644 index 0000000..640481e --- /dev/null +++ b/wifi/java/android/net/wifi/WifiChannel.java @@ -0,0 +1,87 @@ +/* + * 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.net.wifi; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Wifi Channel + * + * @see ScanSettings + * + * @hide + */ +public class WifiChannel implements Parcelable { + + private static final int MIN_FREQ_MHZ = 2412; + private static final int MAX_FREQ_MHZ = 5825; + + private static final int MIN_CHANNEL_NUM = 1; + private static final int MAX_CHANNEL_NUM = 196; + + /** frequency */ + public int freqMHz; + + /** channel number */ + public int channelNum; + + /** is it a DFS channel? */ + public boolean isDFS; + + /** public constructor */ + public WifiChannel() { } + + /** check for validity */ + public boolean isValid() { + if (freqMHz < MIN_FREQ_MHZ || freqMHz > MAX_FREQ_MHZ) return false; + if (channelNum < MIN_CHANNEL_NUM || channelNum > MAX_CHANNEL_NUM) return false; + return true; + } + + /** implement Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** implement Parcelable interface */ + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(freqMHz); + out.writeInt(channelNum); + out.writeInt(isDFS ? 1 : 0); + } + + /** implement Parcelable interface */ + public static final Parcelable.Creator<WifiChannel> CREATOR = + new Parcelable.Creator<WifiChannel>() { + @Override + public WifiChannel createFromParcel(Parcel in) { + WifiChannel channel = new WifiChannel(); + channel.freqMHz = in.readInt(); + channel.channelNum = in.readInt(); + channel.isDFS = in.readInt() != 0; + return channel; + } + + @Override + public WifiChannel[] newArray(int size) { + return new WifiChannel[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index 6a13067..4a6821c 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -69,6 +69,10 @@ public class WifiInfo implements Parcelable { public static final String LINK_SPEED_UNITS = "Mbps"; private int mLinkSpeed; + /** Frequency in MHz */ + public static final String FREQUENCY_UNITS = "MHz"; + private int mFrequency; + private InetAddress mIpAddress; private String mMacAddress; @@ -86,6 +90,7 @@ public class WifiInfo implements Parcelable { mSupplicantState = SupplicantState.UNINITIALIZED; mRssi = -9999; mLinkSpeed = -1; + mFrequency = -1; } /** @@ -100,6 +105,7 @@ public class WifiInfo implements Parcelable { mNetworkId = source.mNetworkId; mRssi = source.mRssi; mLinkSpeed = source.mLinkSpeed; + mFrequency = source.mFrequency; mIpAddress = source.mIpAddress; mMacAddress = source.mMacAddress; mMeteredHint = source.mMeteredHint; @@ -179,6 +185,20 @@ public class WifiInfo implements Parcelable { } /** + * Returns the current frequency in {@link #FREQUENCY_UNITS}. + * @return the frequency. + * @see #FREQUENCY_UNITS + */ + public int getFrequency() { + return mFrequency; + } + + /** @hide */ + public void setFrequency(int frequency) { + this.mFrequency = frequency; + } + + /** * Record the MAC address of the WLAN interface * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form * @hide @@ -303,7 +323,8 @@ public class WifiInfo implements Parcelable { append(", Supplicant state: "). append(mSupplicantState == null ? none : mSupplicantState). append(", RSSI: ").append(mRssi). - append(", Link speed: ").append(mLinkSpeed). + append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS). + append(", Frequency: ").append(mFrequency).append(FREQUENCY_UNITS). append(", Net ID: ").append(mNetworkId). append(", Metered hint: ").append(mMeteredHint); @@ -320,6 +341,7 @@ public class WifiInfo implements Parcelable { dest.writeInt(mNetworkId); dest.writeInt(mRssi); dest.writeInt(mLinkSpeed); + dest.writeInt(mFrequency); if (mIpAddress != null) { dest.writeByte((byte)1); dest.writeByteArray(mIpAddress.getAddress()); @@ -346,6 +368,7 @@ public class WifiInfo implements Parcelable { info.setNetworkId(in.readInt()); info.setRssi(in.readInt()); info.setLinkSpeed(in.readInt()); + info.setFrequency(in.readInt()); if (in.readByte() == 1) { try { info.setInetAddress(InetAddress.getByAddress(in.createByteArray())); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index aabe007..0862b7e 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -20,6 +20,8 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.content.Context; import android.net.DhcpInfo; +import android.net.wifi.ScanSettings; +import android.net.wifi.WifiChannel; import android.os.Binder; import android.os.IBinder; import android.os.Handler; @@ -763,6 +765,22 @@ public class WifiManager { } /** + * Get a list of available channels for customized scan. + * + * @see {@link WifiChannel} + * + * @return the channel list, or null if not available + * @hide + */ + public List<WifiChannel> getChannelList() { + try { + return mService.getChannelList(); + } catch (RemoteException e) { + return null; + } + } + + /** * Request a scan for access points. Returns immediately. The availability * of the results is made known later by means of an asynchronous event sent * on completion of the scan. @@ -770,8 +788,7 @@ public class WifiManager { */ public boolean startScan() { try { - final WorkSource workSource = null; - mService.startScan(workSource); + mService.startScan(null, null); return true; } catch (RemoteException e) { return false; @@ -781,7 +798,42 @@ public class WifiManager { /** @hide */ public boolean startScan(WorkSource workSource) { try { - mService.startScan(workSource); + mService.startScan(null, workSource); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** + * Request a scan for access points in specified channel list. Each channel is specified by its + * frequency in MHz, e.g. "5500" (do NOT include "DFS" even though it is). The availability of + * the results is made known later in the same way as {@link #startScan}. + * + * Note: + * + * 1. Customized scan is for non-connection purposes, i.e. it won't trigger a wifi connection + * even though it finds some known networks. + * + * 2. Customized scan result may include access points that is not specified in the channel + * list. An app will need to do frequency filtering if it wants to get pure results for the + * channel list it specified. + * + * @hide + */ + public boolean startCustomizedScan(ScanSettings requested) { + try { + mService.startScan(requested, null); + return true; + } catch (RemoteException e) { + return false; + } + } + + /** @hide */ + public boolean startCustomizedScan(ScanSettings requested, WorkSource workSource) { + try { + mService.startScan(requested, workSource); return true; } catch (RemoteException e) { return false; |