summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk10
-rw-r--r--CleanSpec.mk1
-rw-r--r--api/current.txt127
-rw-r--r--core/java/android/app/Activity.java150
-rw-r--r--core/java/android/app/ActivityOptions.java153
-rw-r--r--core/java/android/app/ContextImpl.java2
-rw-r--r--core/java/android/content/Context.java4
-rw-r--r--core/java/android/net/NetworkStats.java11
-rw-r--r--core/java/android/os/BatteryStats.java140
-rw-r--r--core/java/android/transition/Transition.java45
-rw-r--r--core/java/android/transition/TransitionInflater.java43
-rw-r--r--core/java/android/transition/TransitionManager.java150
-rw-r--r--core/java/android/view/SurfaceControl.java7
-rw-r--r--core/java/android/view/SurfaceView.java5
-rw-r--r--core/java/android/view/VideoPlaneView.java53
-rw-r--r--core/java/android/view/View.java29
-rw-r--r--core/java/android/view/ViewGroup.java40
-rw-r--r--core/java/android/view/Window.java38
-rw-r--r--core/java/android/view/WindowManager.java223
-rw-r--r--core/java/android/widget/AbsListView.java33
-rw-r--r--core/java/android/widget/ProgressBar.java15
-rw-r--r--core/java/com/android/internal/app/ActionBarImpl.java5
-rw-r--r--core/java/com/android/internal/os/BatterySipper.java7
-rw-r--r--core/java/com/android/internal/os/BatteryStatsHelper.java79
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java144
-rw-r--r--core/res/res/layout-xlarge/screen_action_bar.xml1
-rw-r--r--core/res/res/layout/screen_action_bar.xml1
-rw-r--r--core/res/res/layout/screen_custom_title.xml1
-rw-r--r--core/res/res/values/attrs.xml8
-rw-r--r--core/res/res/values/public.xml2
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk41
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/AndroidManifest.xml31
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/res/layout/activity_main.xml7
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java29
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java34
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java39
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/Version.java25
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk41
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/AndroidManifest.xml31
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/res/layout/activity_main.xml7
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java29
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java34
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java39
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/Version.java25
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk41
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/AndroidManifest.xml31
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/res/layout/activity_main.xml7
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java29
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java34
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java39
-rw-r--r--core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/Version.java25
-rw-r--r--graphics/java/android/graphics/drawable/BitmapDrawable.java71
-rw-r--r--graphics/java/android/graphics/drawable/Drawable.java24
-rw-r--r--graphics/java/android/graphics/drawable/NinePatchDrawable.java57
-rw-r--r--graphics/java/android/graphics/drawable/ShapeDrawable.java297
-rw-r--r--libs/hwui/PatchCache.cpp6
-rw-r--r--libs/hwui/PathCache.cpp4
-rw-r--r--libs/hwui/ResourceCache.cpp30
-rw-r--r--libs/hwui/TextureCache.cpp4
-rw-r--r--media/java/android/media/session/IMediaController.aidl (renamed from media/java/android/media/IMediaController.aidl)4
-rw-r--r--media/java/android/media/session/IMediaControllerCallback.aidl (renamed from media/java/android/media/IMediaControllerCallback.aidl)2
-rw-r--r--media/java/android/media/session/IMediaSession.aidl (renamed from media/java/android/media/IMediaSession.aidl)4
-rw-r--r--media/java/android/media/session/IMediaSessionCallback.aidl (renamed from media/java/android/media/IMediaSessionCallback.aidl)2
-rw-r--r--media/java/android/media/session/IMediaSessionManager.aidl (renamed from media/java/android/media/IMediaSessionManager.aidl)6
-rw-r--r--media/java/android/media/session/MediaController.java (renamed from media/java/android/media/MediaController.java)6
-rw-r--r--media/java/android/media/session/MediaSession.java (renamed from media/java/android/media/MediaSession.java)7
-rw-r--r--media/java/android/media/session/MediaSessionManager.java (renamed from media/java/android/media/MediaSessionManager.java)3
-rw-r--r--media/java/android/media/session/MediaSessionToken.aidl (renamed from media/java/android/media/MediaSessionToken.aidl)2
-rw-r--r--media/java/android/media/session/MediaSessionToken.java (renamed from media/java/android/media/MediaSessionToken.java)3
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java345
-rw-r--r--services/core/java/com/android/server/BatteryService.java1
-rw-r--r--services/core/java/com/android/server/content/SyncManager.java10
-rw-r--r--services/core/java/com/android/server/content/SyncOperation.java25
-rw-r--r--services/core/java/com/android/server/media/MediaSessionRecord.java8
-rw-r--r--services/core/java/com/android/server/media/MediaSessionService.java6
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java5
-rw-r--r--tests/OneMedia/src/com/android/onemedia/IPlayerCallback.aidl4
-rw-r--r--tests/OneMedia/src/com/android/onemedia/IPlayerService.aidl6
-rw-r--r--tests/OneMedia/src/com/android/onemedia/PlayerController.java4
-rw-r--r--tests/OneMedia/src/com/android/onemedia/PlayerService.java2
-rw-r--r--tests/OneMedia/src/com/android/onemedia/PlayerSession.java6
-rw-r--r--tools/aapt/Bundle.h11
-rw-r--r--tools/aapt/Main.cpp7
-rw-r--r--tools/aapt/Resource.cpp38
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java2
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl6
-rw-r--r--wifi/java/android/net/wifi/ScanSettings.aidl19
-rw-r--r--wifi/java/android/net/wifi/ScanSettings.java87
-rw-r--r--wifi/java/android/net/wifi/WifiChannel.aidl19
-rw-r--r--wifi/java/android/net/wifi/WifiChannel.java87
-rw-r--r--wifi/java/android/net/wifi/WifiInfo.java25
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java58
92 files changed, 2423 insertions, 1035 deletions
diff --git a/Android.mk b/Android.mk
index 57091cc..eb288a6 100644
--- a/Android.mk
+++ b/Android.mk
@@ -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>&lt;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>&lt;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;