summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CleanSpec.mk1
-rw-r--r--api/current.txt351
-rw-r--r--core/java/android/animation/Animator.java16
-rw-r--r--core/java/android/animation/PropertyValuesHolder.java2
-rw-r--r--core/java/android/content/UndoManager.java2
-rw-r--r--core/java/android/content/UndoOperation.java2
-rw-r--r--core/java/android/content/UndoOwner.java2
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java37
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java37
-rw-r--r--core/java/android/hardware/camera2/Rational.java83
-rw-r--r--core/java/android/hardware/camera2/utils/CameraBinderDecorator.java4
-rw-r--r--core/java/android/os/BatteryStats.java25
-rw-r--r--core/java/android/os/UserManager.java13
-rw-r--r--core/java/android/provider/Settings.java22
-rw-r--r--core/java/android/transition/AutoTransition.java (renamed from core/java/android/view/transition/AutoTransition.java)16
-rw-r--r--core/java/android/transition/ChangeBounds.java (renamed from core/java/android/view/transition/Move.java)37
-rw-r--r--core/java/android/transition/Crossfade.java (renamed from core/java/android/view/transition/Crossfade.java)49
-rw-r--r--core/java/android/transition/Fade.java (renamed from core/java/android/view/transition/Fade.java)50
-rw-r--r--core/java/android/transition/Recolor.java (renamed from core/java/android/view/transition/Recolor.java)29
-rw-r--r--core/java/android/transition/Rotate.java (renamed from core/java/android/view/transition/Rotate.java)15
-rw-r--r--core/java/android/transition/Scene.java (renamed from core/java/android/view/transition/Scene.java)85
-rw-r--r--core/java/android/transition/Slide.java (renamed from core/java/android/view/transition/Slide.java)8
-rw-r--r--core/java/android/transition/TextChange.java (renamed from core/java/android/view/transition/TextChange.java)45
-rw-r--r--core/java/android/transition/Transition.java (renamed from core/java/android/view/transition/Transition.java)377
-rw-r--r--core/java/android/transition/TransitionInflater.java (renamed from core/java/android/view/transition/TransitionInflater.java)156
-rw-r--r--core/java/android/transition/TransitionManager.java (renamed from core/java/android/view/transition/TransitionManager.java)112
-rw-r--r--core/java/android/transition/TransitionSet.java (renamed from core/java/android/view/transition/TransitionGroup.java)218
-rw-r--r--core/java/android/transition/TransitionValues.java (renamed from core/java/android/view/transition/TransitionValues.java)6
-rw-r--r--core/java/android/transition/TransitionValuesMaps.java (renamed from core/java/android/view/transition/TransitionValuesMaps.java)2
-rw-r--r--core/java/android/transition/Visibility.java (renamed from core/java/android/view/transition/Visibility.java)80
-rw-r--r--core/java/android/transition/package.html (renamed from core/java/android/view/transition/package.html)11
-rw-r--r--core/java/android/view/GestureDetector.java15
-rw-r--r--core/java/android/view/View.java35
-rw-r--r--core/java/android/view/ViewGroup.java2
-rw-r--r--core/java/android/view/ViewParent.java6
-rw-r--r--core/java/android/view/ViewRootImpl.java2
-rw-r--r--core/java/android/widget/ActivityChooserView.java30
-rw-r--r--core/java/android/widget/RelativeLayout.java19
-rw-r--r--core/java/android/widget/TextView.java4
-rw-r--r--core/java/android/widget/VideoView.java69
-rw-r--r--core/java/com/android/internal/app/ProcessStats.java16
-rw-r--r--core/java/com/android/internal/os/ProcessCpuTracker.java2
-rw-r--r--core/jni/android/graphics/Paint.cpp2
-rw-r--r--core/jni/android_media_AudioTrack.cpp25
-rw-r--r--core/res/AndroidManifest.xml1
-rw-r--r--core/res/res/values/attrs.xml61
-rw-r--r--core/res/res/values/ids.xml1
-rw-r--r--core/res/res/values/public.xml5
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--data/fonts/fallback_fonts.xml24
-rw-r--r--data/keyboards/Android.mk28
-rw-r--r--data/keyboards/common.mk6
-rw-r--r--data/keyboards/keyboards.mk12
-rw-r--r--docs/html/about/dashboards/index.jd88
-rw-r--r--docs/html/about/versions/android-4.0.jd15
-rw-r--r--docs/html/about/versions/android-4.1.jd8
-rw-r--r--docs/html/guide/guide_toc.cs2
-rw-r--r--docs/html/guide/topics/connectivity/wifip2p.jd85
-rw-r--r--docs/html/training/connect-devices-wirelessly/index.jd14
-rw-r--r--docs/html/training/connect-devices-wirelessly/nsd-wifi-direct.jd16
-rw-r--r--docs/html/training/connect-devices-wirelessly/wifi-direct.jd39
-rw-r--r--docs/html/training/training_toc.cs4
-rw-r--r--location/java/android/location/LocationManager.java14
-rw-r--r--media/java/android/media/AudioTimestamp.java47
-rw-r--r--media/java/android/media/AudioTrack.java50
-rw-r--r--media/java/android/media/MediaPlayer.java591
-rw-r--r--media/java/android/media/WebVttRenderer.java1094
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java51
-rw-r--r--packages/InputDevices/Android.mk24
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java191
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java133
-rw-r--r--packages/SystemUI/res/values/colors.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java65
-rw-r--r--services/java/com/android/server/LocationManagerService.java2
-rw-r--r--services/java/com/android/server/am/BatteryStatsService.java8
-rw-r--r--services/java/com/android/server/am/ProcessStatsService.java8
-rw-r--r--services/java/com/android/server/display/WifiDisplayController.java33
-rw-r--r--telephony/java/com/android/internal/telephony/DctConstants.java1
-rw-r--r--tests/TransitionTests/res/scene/incorrect_password_scene.xml2
-rw-r--r--tests/TransitionTests/res/scene/login_scene.xml2
-rw-r--r--tests/TransitionTests/res/scene/new_user_scene.xml2
-rw-r--r--tests/TransitionTests/res/scene/password_scene.xml2
-rw-r--r--tests/TransitionTests/res/scene/results_scene.xml3
-rw-r--r--tests/TransitionTests/res/scene/search_scene.xml3
-rw-r--r--tests/TransitionTests/res/scene/success_scene.xml2
-rw-r--r--tests/TransitionTests/res/transition/colorizer_transition.xml6
-rw-r--r--tests/TransitionTests/res/transition/login_slider_transition.xml14
-rw-r--r--tests/TransitionTests/res/transition/login_transition_mgr.xml49
-rw-r--r--tests/TransitionTests/res/transition/mover.xml2
-rw-r--r--tests/TransitionTests/res/transition/mover_fader.xml6
-rw-r--r--tests/TransitionTests/res/transition/my_scene.xml (renamed from tests/TransitionTests/res/scene/my_scene.xml)0
-rw-r--r--tests/TransitionTests/res/transition/my_transition.xml26
-rw-r--r--tests/TransitionTests/res/transition/my_transition_mgr.xml8
-rw-r--r--tests/TransitionTests/res/transition/username_taken_scene.xml (renamed from tests/TransitionTests/res/scene/username_taken_scene.xml)0
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/ChangingText.java31
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/ClippingText.java33
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java30
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java21
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java18
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java45
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/DelayedTransition.java2
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/Demo1.java17
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/Demo2.java28
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/Demo3.java20
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/Demo4.java32
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/Demo5.java8
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java3
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/FadingTest.java20
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/HierarchicalMove.java54
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/InstanceTargets.java38
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java34
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java19
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java39
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/LoginActivityFromResources.java24
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/Reparenting.java8
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/ResourceLoadingTest.java14
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTargets.java20
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition.java12
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition2.java8
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java35
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java43
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java39
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java15
-rw-r--r--tests/TransitionTests/src/com/android/transitiontests/UniqueIds.java6
-rw-r--r--tools/aapt/Resource.cpp27
126 files changed, 4022 insertions, 1700 deletions
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 215d108..39742db6 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -175,6 +175,7 @@ $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framew
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/IPrinterDiscoverySessionClient.*)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/os/IBattery*)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/api/current.txt b/api/current.txt
index 099b1a5..e50d769 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -261,7 +261,7 @@ package android {
field public static final int activityCloseExitAnimation = 16842939; // 0x10100bb
field public static final int activityOpenEnterAnimation = 16842936; // 0x10100b8
field public static final int activityOpenExitAnimation = 16842937; // 0x10100b9
- field public static final int addPrintersActivity = 16843747; // 0x10103e3
+ field public static final int addPrintersActivity = 16843750; // 0x10103e6
field public static final int addStatesFromChildren = 16842992; // 0x10100f0
field public static final int adjustViewBounds = 16843038; // 0x101011e
field public static final int alertDialogIcon = 16843605; // 0x1010355
@@ -289,14 +289,14 @@ package android {
field public static final deprecated int animationResolution = 16843546; // 0x101031a
field public static final int antialias = 16843034; // 0x101011a
field public static final int anyDensity = 16843372; // 0x101026c
- field public static final int apduServiceBanner = 16843755; // 0x10103eb
+ field public static final int apduServiceBanner = 16843758; // 0x10103ee
field public static final int apiKey = 16843281; // 0x1010211
field public static final int author = 16843444; // 0x10102b4
field public static final int authorities = 16842776; // 0x1010018
field public static final int autoAdvanceViewId = 16843535; // 0x101030f
field public static final int autoCompleteTextViewStyle = 16842859; // 0x101006b
field public static final int autoLink = 16842928; // 0x10100b0
- field public static final int autoMirrored = 16843752; // 0x10103e8
+ field public static final int autoMirrored = 16843755; // 0x10103eb
field public static final int autoStart = 16843445; // 0x10102b5
field public static final deprecated int autoText = 16843114; // 0x101016a
field public static final int autoUrlDetect = 16843404; // 0x101028c
@@ -337,7 +337,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 category = 16843749; // 0x10103e5
+ field public static final int category = 16843752; // 0x10103e8
field public static final int centerBright = 16842956; // 0x10100cc
field public static final int centerColor = 16843275; // 0x101020b
field public static final int centerDark = 16842952; // 0x10100c8
@@ -393,7 +393,7 @@ package android {
field public static final int cropToPadding = 16843043; // 0x1010123
field public static final int cursorVisible = 16843090; // 0x1010152
field public static final int customNavigationLayout = 16843474; // 0x10102d2
- field public static final int customRoots = 16843751; // 0x10103e7
+ field public static final int customRoots = 16843754; // 0x10103ea
field public static final int customTokens = 16843579; // 0x101033b
field public static final int cycles = 16843220; // 0x10101d4
field public static final int dashGap = 16843175; // 0x10101a7
@@ -487,6 +487,7 @@ package android {
field public static final int fadeScrollbars = 16843434; // 0x10102aa
field public static final int fadingEdge = 16842975; // 0x10100df
field public static final int fadingEdgeLength = 16842976; // 0x10100e0
+ field public static final int fadingMode = 16843745; // 0x10103e1
field public static final int fastScrollAlwaysVisible = 16843573; // 0x1010335
field public static final int fastScrollEnabled = 16843302; // 0x1010226
field public static final int fastScrollOverlayPosition = 16843578; // 0x101033a
@@ -612,7 +613,7 @@ package android {
field public static final int installLocation = 16843447; // 0x10102b7
field public static final int interpolator = 16843073; // 0x1010141
field public static final int isAlwaysSyncable = 16843571; // 0x1010333
- field public static final int isAsciiCapable = 16843750; // 0x10103e6
+ field public static final int isAsciiCapable = 16843753; // 0x10103e9
field public static final int isAuxiliary = 16843647; // 0x101037f
field public static final int isDefault = 16843297; // 0x1010221
field public static final int isIndicator = 16843079; // 0x1010147
@@ -845,7 +846,7 @@ package android {
field public static final int prompt = 16843131; // 0x101017b
field public static final int propertyName = 16843489; // 0x10102e1
field public static final int protectionLevel = 16842761; // 0x1010009
- field public static final int provideAssistData = 16843756; // 0x10103ec
+ field public static final int provideAssistData = 16843759; // 0x10103ef
field public static final int publicKey = 16843686; // 0x10103a6
field public static final int queryActionMsg = 16843227; // 0x10101db
field public static final int queryAfterZeroResults = 16843394; // 0x1010282
@@ -870,7 +871,7 @@ package android {
field public static final int reqKeyboardType = 16843304; // 0x1010228
field public static final int reqNavigation = 16843306; // 0x101022a
field public static final int reqTouchScreen = 16843303; // 0x1010227
- field public static final int requireDeviceUnlock = 16843754; // 0x10103ea
+ field public static final int requireDeviceUnlock = 16843757; // 0x10103ed
field public static final int required = 16843406; // 0x101028e
field public static final int requiredAccountType = 16843734; // 0x10103d6
field public static final int requiredForAllUsers = 16843728; // 0x10103d0
@@ -969,12 +970,13 @@ package android {
field public static final int spinnersShown = 16843595; // 0x101034b
field public static final int splitMotionEvents = 16843503; // 0x10102ef
field public static final int src = 16843033; // 0x1010119
- field public static final int ssp = 16843744; // 0x10103e0
- field public static final int sspPattern = 16843746; // 0x10103e2
- field public static final int sspPrefix = 16843745; // 0x10103e1
+ field public static final int ssp = 16843747; // 0x10103e3
+ field public static final int sspPattern = 16843749; // 0x10103e5
+ field public static final int sspPrefix = 16843748; // 0x10103e4
field public static final int stackFromBottom = 16843005; // 0x10100fd
field public static final int starStyle = 16842882; // 0x1010082
field public static final int startColor = 16843165; // 0x101019d
+ field public static final int startDelay = 16843746; // 0x10103e2
field public static final int startOffset = 16843198; // 0x10101be
field public static final deprecated int startYear = 16843132; // 0x101017c
field public static final int stateNotNeeded = 16842774; // 0x1010016
@@ -1018,7 +1020,7 @@ package android {
field public static final int summaryOff = 16843248; // 0x10101f0
field public static final int summaryOn = 16843247; // 0x10101ef
field public static final int supportsRtl = 16843695; // 0x10103af
- field public static final int supportsSwitchingToNextInputMethod = 16843753; // 0x10103e9
+ field public static final int supportsSwitchingToNextInputMethod = 16843756; // 0x10103ec
field public static final int supportsUploading = 16843419; // 0x101029b
field public static final int switchMinWidth = 16843632; // 0x1010370
field public static final int switchPadding = 16843633; // 0x1010371
@@ -1035,7 +1037,7 @@ package android {
field public static final int targetActivity = 16843266; // 0x1010202
field public static final int targetClass = 16842799; // 0x101002f
field public static final int targetDescriptions = 16843680; // 0x10103a0
- field public static final int targetID = 16843740; // 0x10103dc
+ field public static final int targetId = 16843740; // 0x10103dc
field public static final int targetPackage = 16842785; // 0x1010021
field public static final int targetSdkVersion = 16843376; // 0x1010270
field public static final int taskAffinity = 16842770; // 0x1010012
@@ -1140,6 +1142,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 transitionOrdering = 16843744; // 0x10103e0
field public static final int translationX = 16843554; // 0x1010322
field public static final int translationY = 16843555; // 0x1010323
field public static final int type = 16843169; // 0x10101a1
@@ -1158,7 +1161,7 @@ package android {
field public static final int valueTo = 16843487; // 0x10102df
field public static final int valueType = 16843488; // 0x10102e0
field public static final int variablePadding = 16843157; // 0x1010195
- field public static final int vendor = 16843748; // 0x10103e4
+ field public static final int vendor = 16843751; // 0x10103e7
field public static final int versionCode = 16843291; // 0x101021b
field public static final int versionName = 16843292; // 0x101021c
field public static final int verticalCorrection = 16843322; // 0x101023a
@@ -2349,7 +2352,6 @@ package android.animation {
method public abstract long getDuration();
method public android.animation.TimeInterpolator getInterpolator();
method public java.util.ArrayList<android.animation.Animator.AnimatorListener> getListeners();
- method public java.util.ArrayList<android.animation.Animator.AnimatorPauseListener> getPauseListeners();
method public abstract long getStartDelay();
method public boolean isPaused();
method public abstract boolean isRunning();
@@ -6902,59 +6904,6 @@ package android.content {
method public abstract void onStatusChanged(int);
}
- public class UndoManager {
- ctor public UndoManager();
- method public void addOperation(android.content.UndoOperation<?>, int);
- method public void beginUpdate(java.lang.CharSequence);
- method public int commitState(android.content.UndoOwner);
- method public int countRedos(android.content.UndoOwner[]);
- method public int countUndos(android.content.UndoOwner[]);
- method public void endUpdate();
- method public int forgetRedos(android.content.UndoOwner[], int);
- method public int forgetUndos(android.content.UndoOwner[], int);
- method public int getHistorySize();
- method public android.content.UndoOperation<?> getLastOperation(int);
- method public android.content.UndoOperation<?> getLastOperation(android.content.UndoOwner, int);
- method public T getLastOperation(java.lang.Class<T>, android.content.UndoOwner, int);
- method public android.content.UndoOwner getOwner(java.lang.String, java.lang.Object);
- method public java.lang.CharSequence getRedoLabel(android.content.UndoOwner[]);
- method public java.lang.CharSequence getUndoLabel(android.content.UndoOwner[]);
- method public int getUpdateNestingLevel();
- method public boolean hasOperation(android.content.UndoOwner);
- method public boolean isInUndo();
- method public boolean isInUpdate();
- method public int redo(android.content.UndoOwner[], int);
- method public void restoreInstanceState(android.os.Parcelable);
- method public android.os.Parcelable saveInstanceState();
- method public void setHistorySize(int);
- method public void setUndoLabel(java.lang.CharSequence);
- method public void suggestUndoLabel(java.lang.CharSequence);
- method public boolean uncommitState(int, android.content.UndoOwner);
- method public int undo(android.content.UndoOwner[], int);
- field public static final int MERGE_MODE_ANY = 2; // 0x2
- field public static final int MERGE_MODE_NONE = 0; // 0x0
- field public static final int MERGE_MODE_UNIQUE = 1; // 0x1
- }
-
- public abstract class UndoOperation implements android.os.Parcelable {
- ctor public UndoOperation(android.content.UndoOwner);
- ctor protected UndoOperation(android.os.Parcel, java.lang.ClassLoader);
- method public boolean allowMerge();
- method public abstract void commit();
- method public int describeContents();
- method public android.content.UndoOwner getOwner();
- method public DATA getOwnerData();
- method public boolean hasData();
- method public boolean matchOwner(android.content.UndoOwner);
- method public abstract void redo();
- method public abstract void undo();
- }
-
- public class UndoOwner {
- method public java.lang.Object getData();
- method public java.lang.String getTag();
- }
-
public class UriMatcher {
ctor public UriMatcher(int);
method public void addURI(java.lang.String, java.lang.String, int);
@@ -11923,6 +11872,7 @@ package android.location {
field public static final java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled";
field public static final java.lang.String KEY_PROXIMITY_ENTERING = "entering";
field public static final java.lang.String KEY_STATUS_CHANGED = "status";
+ field public static final java.lang.String MODE_CHANGED_ACTION = "android.location.MODE_CHANGED";
field public static final java.lang.String NETWORK_PROVIDER = "network";
field public static final java.lang.String PASSIVE_PROVIDER = "passive";
field public static final java.lang.String PROVIDERS_CHANGED_ACTION = "android.location.PROVIDERS_CHANGED";
@@ -25535,6 +25485,119 @@ package android.text.util {
}
+package android.transition {
+
+ public class AutoTransition extends android.transition.TransitionSet {
+ ctor public AutoTransition();
+ }
+
+ public class ChangeBounds extends android.transition.Transition {
+ ctor public ChangeBounds();
+ method public void captureEndValues(android.transition.TransitionValues);
+ method public void captureStartValues(android.transition.TransitionValues);
+ method public void setReparent(boolean);
+ method public void setResizeClip(boolean);
+ }
+
+ public class Fade extends android.transition.Visibility {
+ ctor public Fade();
+ ctor public Fade(int);
+ field public static final int IN = 1; // 0x1
+ field public static final int OUT = 2; // 0x2
+ }
+
+ public final class Scene {
+ ctor public Scene(android.view.ViewGroup);
+ ctor public Scene(android.view.ViewGroup, android.view.ViewGroup);
+ method public void enter();
+ method public void exit();
+ method public static android.transition.Scene getSceneForLayout(android.view.ViewGroup, int, android.content.Context);
+ method public android.view.ViewGroup getSceneRoot();
+ method public void setEnterAction(java.lang.Runnable);
+ method public void setExitAction(java.lang.Runnable);
+ }
+
+ public abstract class Transition implements java.lang.Cloneable {
+ ctor public Transition();
+ method public android.transition.Transition addListener(android.transition.Transition.TransitionListener);
+ method public android.transition.Transition addTarget(android.view.View);
+ method public android.transition.Transition addTargetId(int);
+ method public abstract void captureEndValues(android.transition.TransitionValues);
+ method public abstract void captureStartValues(android.transition.TransitionValues);
+ method public android.transition.Transition clone();
+ method public android.animation.Animator createAnimator(android.view.ViewGroup, android.transition.TransitionValues, android.transition.TransitionValues);
+ method public long getDuration();
+ method public android.animation.TimeInterpolator getInterpolator();
+ method public java.lang.String getName();
+ method public long getStartDelay();
+ method public java.util.List<java.lang.Integer> getTargetIds();
+ method public java.util.List<android.view.View> getTargets();
+ method public java.lang.String[] getTransitionProperties();
+ method public android.transition.TransitionValues getTransitionValues(android.view.View, boolean);
+ method public android.transition.Transition removeListener(android.transition.Transition.TransitionListener);
+ method public android.transition.Transition removeTarget(android.view.View);
+ method public android.transition.Transition removeTargetId(int);
+ method public android.transition.Transition setDuration(long);
+ method public android.transition.Transition setInterpolator(android.animation.TimeInterpolator);
+ method public android.transition.Transition setStartDelay(long);
+ }
+
+ public static abstract interface Transition.TransitionListener {
+ method public abstract void onTransitionCancel(android.transition.Transition);
+ method public abstract void onTransitionEnd(android.transition.Transition);
+ method public abstract void onTransitionPause(android.transition.Transition);
+ method public abstract void onTransitionResume(android.transition.Transition);
+ method public abstract void onTransitionStart(android.transition.Transition);
+ }
+
+ public class TransitionInflater {
+ method public static android.transition.TransitionInflater from(android.content.Context);
+ method public android.transition.Transition inflateTransition(int);
+ method public android.transition.TransitionManager inflateTransitionManager(int, android.view.ViewGroup);
+ }
+
+ public class TransitionManager {
+ ctor public TransitionManager();
+ method public static void beginDelayedTransition(android.view.ViewGroup);
+ method public static void beginDelayedTransition(android.view.ViewGroup, android.transition.Transition);
+ method public static android.transition.Transition getDefaultTransition();
+ method public static void go(android.transition.Scene);
+ method public static void go(android.transition.Scene, android.transition.Transition);
+ method public void setDefaultTransition(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 transitionTo(android.transition.Scene);
+ }
+
+ public class TransitionSet extends android.transition.Transition {
+ ctor public TransitionSet();
+ method public android.transition.TransitionSet addTransition(android.transition.Transition);
+ method public void captureEndValues(android.transition.TransitionValues);
+ method public void captureStartValues(android.transition.TransitionValues);
+ method public int getOrdering();
+ method public android.transition.TransitionSet removeTransition(android.transition.Transition);
+ method public android.transition.TransitionSet setOrdering(int);
+ field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
+ field public static final int ORDERING_TOGETHER = 0; // 0x0
+ }
+
+ public class TransitionValues {
+ ctor public TransitionValues();
+ field public final java.util.Map values;
+ field public android.view.View view;
+ }
+
+ public abstract class Visibility extends android.transition.Transition {
+ ctor public Visibility();
+ method public void captureEndValues(android.transition.TransitionValues);
+ method public void captureStartValues(android.transition.TransitionValues);
+ method public boolean isVisible(android.transition.TransitionValues);
+ method public android.animation.Animator onAppear(android.view.ViewGroup, android.transition.TransitionValues, int, android.transition.TransitionValues, int);
+ method public android.animation.Animator onDisappear(android.view.ViewGroup, android.transition.TransitionValues, int, android.transition.TransitionValues, int);
+ }
+
+}
+
package android.util {
public class AndroidException extends java.lang.Exception {
@@ -27431,7 +27494,6 @@ package android.view {
method public java.lang.CharSequence getContentDescription();
method public final android.content.Context getContext();
method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo();
- method public android.view.transition.Scene getCurrentScene();
method public static int getDefaultSize(int, int);
method public android.view.Display getDisplay();
method public final int[] getDrawableState();
@@ -29708,155 +29770,6 @@ package android.view.textservice {
}
-package android.view.transition {
-
- public class AutoTransition extends android.view.transition.TransitionGroup {
- ctor public AutoTransition();
- }
-
- public class Crossfade extends android.view.transition.Transition {
- ctor public Crossfade();
- method protected void captureValues(android.view.transition.TransitionValues, boolean);
- method public int getFadeBehavior();
- method public int getResizeBehavior();
- method public void setFadeBehavior(int);
- method public void setResizeBehavior(int);
- field public static final int FADE_BEHAVIOR_CROSSFADE = 0; // 0x0
- field public static final int FADE_BEHAVIOR_OUT_IN = 2; // 0x2
- field public static final int FADE_BEHAVIOR_REVEAL = 1; // 0x1
- field public static final int RESIZE_BEHAVIOR_NONE = 0; // 0x0
- field public static final int RESIZE_BEHAVIOR_SCALE = 1; // 0x1
- }
-
- public class Fade extends android.view.transition.Visibility {
- ctor public Fade();
- ctor public Fade(int);
- field public static final int IN = 1; // 0x1
- field public static final int OUT = 2; // 0x2
- }
-
- public class Move extends android.view.transition.Transition {
- ctor public Move();
- method protected void captureValues(android.view.transition.TransitionValues, boolean);
- method public void setReparent(boolean);
- method public void setResizeClip(boolean);
- }
-
- public class Recolor extends android.view.transition.Transition {
- ctor public Recolor();
- method protected void captureValues(android.view.transition.TransitionValues, boolean);
- }
-
- public class Rotate extends android.view.transition.Transition {
- ctor public Rotate();
- method protected void captureValues(android.view.transition.TransitionValues, boolean);
- }
-
- public final class Scene {
- ctor public Scene(android.view.ViewGroup);
- ctor public Scene(android.view.ViewGroup, int, android.content.Context);
- ctor public Scene(android.view.ViewGroup, android.view.ViewGroup);
- method public void enter();
- method public void exit();
- method public android.view.ViewGroup getSceneRoot();
- method public void setEnterAction(java.lang.Runnable);
- method public void setExitAction(java.lang.Runnable);
- }
-
- public class Slide extends android.view.transition.Visibility {
- ctor public Slide();
- }
-
- public class TextChange extends android.view.transition.Transition {
- ctor public TextChange();
- method protected void captureValues(android.view.transition.TransitionValues, boolean);
- method public void setChangeBehavior(int);
- field public static final int CHANGE_BEHAVIOR_IN = 2; // 0x2
- field public static final int CHANGE_BEHAVIOR_KEEP = 0; // 0x0
- field public static final int CHANGE_BEHAVIOR_OUT = 1; // 0x1
- field public static final int CHANGE_BEHAVIOR_OUT_IN = 3; // 0x3
- }
-
- public abstract class Transition implements java.lang.Cloneable {
- ctor public Transition();
- method public void addListener(android.view.transition.Transition.TransitionListener);
- method protected void cancel();
- method protected abstract void captureValues(android.view.transition.TransitionValues, boolean);
- method public android.view.transition.Transition clone();
- method public long getDuration();
- method public android.animation.TimeInterpolator getInterpolator();
- method public java.util.ArrayList<android.view.transition.Transition.TransitionListener> getListeners();
- method public java.lang.String getName();
- method public long getStartDelay();
- method public int[] getTargetIds();
- method public android.view.View[] getTargets();
- method public java.lang.String[] getTransitionProperties();
- method protected android.view.transition.TransitionValues getTransitionValues(android.view.View, boolean);
- method protected android.animation.Animator play(android.view.ViewGroup, android.view.transition.TransitionValues, android.view.transition.TransitionValues);
- method public void removeListener(android.view.transition.Transition.TransitionListener);
- method public android.view.transition.Transition setDuration(long);
- method public void setInterpolator(android.animation.TimeInterpolator);
- method public void setStartDelay(long);
- method public android.view.transition.Transition setTargetIds(int...);
- method public android.view.transition.Transition setTargets(android.view.View...);
- }
-
- public static abstract interface Transition.TransitionListener {
- method public abstract void onTransitionCancel(android.view.transition.Transition);
- method public abstract void onTransitionEnd(android.view.transition.Transition);
- method public abstract void onTransitionPause(android.view.transition.Transition);
- method public abstract void onTransitionResume(android.view.transition.Transition);
- method public abstract void onTransitionStart(android.view.transition.Transition);
- }
-
- public class TransitionGroup extends android.view.transition.Transition {
- ctor public TransitionGroup();
- ctor public TransitionGroup(int);
- method public void addTransitions(android.view.transition.Transition...);
- method protected void captureValues(android.view.transition.TransitionValues, boolean);
- method public void removeTransition(android.view.transition.Transition);
- method public void setOrdering(int);
- field public static final int SEQUENTIALLY = 1; // 0x1
- field public static final int TOGETHER = 0; // 0x0
- }
-
- public class TransitionInflater {
- method public static android.view.transition.TransitionInflater from(android.content.Context);
- method public android.view.transition.Scene inflateScene(int, android.view.ViewGroup);
- method public android.view.transition.Transition inflateTransition(int);
- method public android.view.transition.TransitionManager inflateTransitionManager(int, android.view.ViewGroup);
- }
-
- public class TransitionManager {
- ctor public TransitionManager();
- method public static void beginDelayedTransition(android.view.ViewGroup, android.view.transition.Transition);
- method public android.view.transition.Transition getDefaultTransition();
- method public static void go(android.view.transition.Scene);
- method public static void go(android.view.transition.Scene, android.view.transition.Transition);
- method public static void go(android.view.ViewGroup, java.lang.Runnable);
- method public static void go(android.view.ViewGroup, java.lang.Runnable, android.view.transition.Transition);
- method public void setDefaultTransition(android.view.transition.Transition);
- method public void setTransition(android.view.transition.Scene, android.view.transition.Transition);
- method public void setTransition(android.view.transition.Scene, android.view.transition.Scene, android.view.transition.Transition);
- method public void transitionTo(android.view.transition.Scene);
- }
-
- public class TransitionValues {
- ctor public TransitionValues();
- field public final java.util.Map values;
- field public android.view.View view;
- }
-
- public abstract class Visibility extends android.view.transition.Transition {
- ctor public Visibility();
- method protected android.animation.Animator appear(android.view.ViewGroup, android.view.transition.TransitionValues, int, android.view.transition.TransitionValues, int);
- method protected void captureValues(android.view.transition.TransitionValues, boolean);
- method protected android.animation.Animator disappear(android.view.ViewGroup, android.view.transition.TransitionValues, int, android.view.transition.TransitionValues, int);
- method public boolean isVisible(android.view.transition.TransitionValues);
- }
-
-}
-
package android.webkit {
public class ConsoleMessage {
@@ -32488,7 +32401,6 @@ package android.widget {
method public int getTotalPaddingTop();
method public final android.text.method.TransformationMethod getTransformationMethod();
method public android.graphics.Typeface getTypeface();
- method public final android.content.UndoManager getUndoManager();
method public android.text.style.URLSpan[] getUrls();
method public boolean hasSelection();
method public boolean isCursorVisible();
@@ -32587,7 +32499,6 @@ package android.widget {
method public final void setTransformationMethod(android.text.method.TransformationMethod);
method public void setTypeface(android.graphics.Typeface, int);
method public void setTypeface(android.graphics.Typeface);
- method public final void setUndoManager(android.content.UndoManager, java.lang.String);
method public void setWidth(int);
}
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index 89accbb..129e52c 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -280,19 +280,9 @@ public abstract class Animator implements Cloneable {
}
/**
- * Gets the set of {@link AnimatorPauseListener} objects that are currently
- * listening for pause/resume events on this animator.
- *
- * @return ArrayList<AnimatorListener> The set of pause listeners.
- */
- public ArrayList<AnimatorPauseListener> getPauseListeners() {
- return mPauseListeners;
- }
-
- /**
- * Removes all listeners from this object. This is equivalent to calling
- * {@link #getListeners()} and {@link #getPauseListeners()} followed by calling
- * {@link ArrayList#clear()} on the returned lists of listeners.
+ * Removes all {@link #addListener(android.animation.Animator.AnimatorListener) listeners}
+ * and {@link #addPauseListener(android.animation.Animator.AnimatorPauseListener)
+ * pauseListeners} from this object.
*/
public void removeAllListeners() {
if (mListeners != null) {
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index 5b1a7cf..43014ad 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -636,7 +636,7 @@ public class PropertyValuesHolder implements Cloneable {
}
/**
- * The TypeEvaluator will the automatically determined based on the type of values
+ * The TypeEvaluator will be automatically determined based on the type of values
* supplied to PropertyValuesHolder. The evaluator can be manually set, however, if so
* desired. This may be important in cases where either the type of the values supplied
* do not match the way that they should be interpolated between, or if the values
diff --git a/core/java/android/content/UndoManager.java b/core/java/android/content/UndoManager.java
index 1c2db47..e9ec5a4 100644
--- a/core/java/android/content/UndoManager.java
+++ b/core/java/android/content/UndoManager.java
@@ -50,6 +50,8 @@ import java.util.HashMap;
* undo/redo them without needing to impact edits in other objects; while
* within the larger document, all edits can be seen and the user must
* undo/redo them as a single stream.</p>
+ *
+ * @hide
*/
public class UndoManager {
private final HashMap<String, UndoOwner> mOwners = new HashMap<String, UndoOwner>();
diff --git a/core/java/android/content/UndoOperation.java b/core/java/android/content/UndoOperation.java
index 8084b1f..1ff32d4 100644
--- a/core/java/android/content/UndoOperation.java
+++ b/core/java/android/content/UndoOperation.java
@@ -23,6 +23,8 @@ import android.os.Parcelable;
* A single undoable operation. You must subclass this to implement the state
* and behavior for your operation. Instances of this class are placed and
* managed in an {@link UndoManager}.
+ *
+ * @hide
*/
public abstract class UndoOperation<DATA> implements Parcelable {
UndoOwner mOwner;
diff --git a/core/java/android/content/UndoOwner.java b/core/java/android/content/UndoOwner.java
index a279de6..d0cdc95 100644
--- a/core/java/android/content/UndoOwner.java
+++ b/core/java/android/content/UndoOwner.java
@@ -18,6 +18,8 @@ package android.content;
/**
* Representation of an owner of {@link UndoOperation} objects in an {@link UndoManager}.
+ *
+ * @hide
*/
public class UndoOwner {
final String mTag;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 8b5bf4a..3f9b9e9 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -303,13 +303,14 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable {
* </p>
* <p>
* Each area is a rectangle plus weight: xmin, ymin,
- * xmax, ymax, weight.
+ * xmax, ymax, weight. The rectangle is defined inclusive of the
+ * specified coordinates.
* </p><p>
* The coordinate system is based on the active pixel array,
- * with (0,0) being the top-left of the active pixel array, and
- * (android.sensor.info.activeArraySize.width,
- * android.sensor.info.activeArraySize.height) being the
- * bottom-right point of the active pixel array. The weight
+ * with (0,0) being the top-left pixel in the active pixel array, and
+ * (android.sensor.info.activeArraySize.width - 1,
+ * android.sensor.info.activeArraySize.height - 1) being the
+ * bottom-right pixel in the active pixel array. The weight
* should be nonnegative.
* </p><p>
* If all regions have 0 weight, then no specific metering area
@@ -378,13 +379,14 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable {
* </p>
* <p>
* Each area is a rectangle plus weight: xmin, ymin,
- * xmax, ymax, weight.
+ * xmax, ymax, weight. The rectangle is defined inclusive of the
+ * specified coordinates.
* </p><p>
* The coordinate system is based on the active pixel array,
- * with (0,0) being the top-left of the active pixel array, and
- * (android.sensor.info.activeArraySize.width,
- * android.sensor.info.activeArraySize.height) being the
- * bottom-right point of the active pixel array. The weight
+ * with (0,0) being the top-left pixel in the active pixel array, and
+ * (android.sensor.info.activeArraySize.width - 1,
+ * android.sensor.info.activeArraySize.height - 1) being the
+ * bottom-right pixel in the active pixel array. The weight
* should be nonnegative.
* </p><p>
* If all regions have 0 weight, then no specific focus area
@@ -462,12 +464,15 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable {
* <p>
* Only used in AUTO mode.
* </p><p>
- * Each area is a rectangle plus weight: xmin, ymin, xmax,
- * ymax, weight. The coordinate system is based on the active
- * pixel array, with (0,0) being the top-left of the active
- * pixel array, and (android.sensor.info.activeArraySize.width,
- * android.sensor.info.activeArraySize.height) being the
- * bottom-right point of the active pixel array. The weight
+ * Each area is a rectangle plus weight: xmin, ymin,
+ * xmax, ymax, weight. The rectangle is defined inclusive of the
+ * specified coordinates.
+ * </p><p>
+ * The coordinate system is based on the active pixel array,
+ * with (0,0) being the top-left pixel in the active pixel array, and
+ * (android.sensor.info.activeArraySize.width - 1,
+ * android.sensor.info.activeArraySize.height - 1) being the
+ * bottom-right pixel in the active pixel array. The weight
* should be nonnegative.
* </p><p>
* If all regions have 0 weight, then no specific metering area
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index ef6aaa0..bd151a2 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -198,13 +198,14 @@ public final class CaptureResult extends CameraMetadata {
* </p>
* <p>
* Each area is a rectangle plus weight: xmin, ymin,
- * xmax, ymax, weight.
+ * xmax, ymax, weight. The rectangle is defined inclusive of the
+ * specified coordinates.
* </p><p>
* The coordinate system is based on the active pixel array,
- * with (0,0) being the top-left of the active pixel array, and
- * (android.sensor.info.activeArraySize.width,
- * android.sensor.info.activeArraySize.height) being the
- * bottom-right point of the active pixel array. The weight
+ * with (0,0) being the top-left pixel in the active pixel array, and
+ * (android.sensor.info.activeArraySize.width - 1,
+ * android.sensor.info.activeArraySize.height - 1) being the
+ * bottom-right pixel in the active pixel array. The weight
* should be nonnegative.
* </p><p>
* If all regions have 0 weight, then no specific metering area
@@ -258,13 +259,14 @@ public final class CaptureResult extends CameraMetadata {
* </p>
* <p>
* Each area is a rectangle plus weight: xmin, ymin,
- * xmax, ymax, weight.
+ * xmax, ymax, weight. The rectangle is defined inclusive of the
+ * specified coordinates.
* </p><p>
* The coordinate system is based on the active pixel array,
- * with (0,0) being the top-left of the active pixel array, and
- * (android.sensor.info.activeArraySize.width,
- * android.sensor.info.activeArraySize.height) being the
- * bottom-right point of the active pixel array. The weight
+ * with (0,0) being the top-left pixel in the active pixel array, and
+ * (android.sensor.info.activeArraySize.width - 1,
+ * android.sensor.info.activeArraySize.height - 1) being the
+ * bottom-right pixel in the active pixel array. The weight
* should be nonnegative.
* </p><p>
* If all regions have 0 weight, then no specific focus area
@@ -342,12 +344,15 @@ public final class CaptureResult extends CameraMetadata {
* <p>
* Only used in AUTO mode.
* </p><p>
- * Each area is a rectangle plus weight: xmin, ymin, xmax,
- * ymax, weight. The coordinate system is based on the active
- * pixel array, with (0,0) being the top-left of the active
- * pixel array, and (android.sensor.info.activeArraySize.width,
- * android.sensor.info.activeArraySize.height) being the
- * bottom-right point of the active pixel array. The weight
+ * Each area is a rectangle plus weight: xmin, ymin,
+ * xmax, ymax, weight. The rectangle is defined inclusive of the
+ * specified coordinates.
+ * </p><p>
+ * The coordinate system is based on the active pixel array,
+ * with (0,0) being the top-left pixel in the active pixel array, and
+ * (android.sensor.info.activeArraySize.width - 1,
+ * android.sensor.info.activeArraySize.height - 1) being the
+ * bottom-right pixel in the active pixel array. The weight
* should be nonnegative.
* </p><p>
* If all regions have 0 weight, then no specific metering area
diff --git a/core/java/android/hardware/camera2/Rational.java b/core/java/android/hardware/camera2/Rational.java
index 0260e02..77b8c26 100644
--- a/core/java/android/hardware/camera2/Rational.java
+++ b/core/java/android/hardware/camera2/Rational.java
@@ -26,22 +26,17 @@ public final class Rational {
/**
* <p>Create a Rational with a given numerator and denominator.</p>
*
- * <p>
- * The signs of the numerator and the denominator may be flipped such that the denominator
- * is always 0.
- * </p>
+ * <p>The signs of the numerator and the denominator may be flipped such that the denominator
+ * is always positive.</p>
+ *
+ * <p>A rational value with a 0-denominator may be constructed, but will have similar semantics
+ * as float NaN and INF values. The int getter functions return 0 in this case.</p>
*
* @param numerator the numerator of the rational
* @param denominator the denominator of the rational
- *
- * @throws IllegalArgumentException if the denominator is 0
*/
public Rational(int numerator, int denominator) {
- if (denominator == 0) {
- throw new IllegalArgumentException("Argument 'denominator' is 0");
- }
-
if (denominator < 0) {
numerator = -numerator;
denominator = -denominator;
@@ -55,6 +50,9 @@ public final class Rational {
* Gets the numerator of the rational.
*/
public int getNumerator() {
+ if (mDenominator == 0) {
+ return 0;
+ }
return mNumerator;
}
@@ -65,22 +63,41 @@ public final class Rational {
return mDenominator;
}
+ private boolean isNaN() {
+ return mDenominator == 0 && mNumerator == 0;
+ }
+
+ private boolean isInf() {
+ return mDenominator == 0 && mNumerator > 0;
+ }
+
+ private boolean isNegInf() {
+ return mDenominator == 0 && mNumerator < 0;
+ }
+
/**
* <p>Compare this Rational to another object and see if they are equal.</p>
*
* <p>A Rational object can only be equal to another Rational object (comparing against any other
* type will return false).</p>
*
- * <p>A Rational object is considered equal to another Rational object if and only if their
- * reduced forms have the same numerator and denominator.</p>
+ * <p>A Rational object is considered equal to another Rational object if and only if one of
+ * the following holds</p>:
+ * <ul><li>Both are NaN</li>
+ * <li>Both are infinities of the same sign</li>
+ * <li>Both have the same numerator and denominator in their reduced form</li>
+ * </ul>
*
* <p>A reduced form of a Rational is calculated by dividing both the numerator and the
* denominator by their greatest common divisor.</p>
*
* <pre>
- * (new Rational(1, 2)).equals(new Rational(1, 2)) == true // trivially true
- * (new Rational(2, 3)).equals(new Rational(1, 2)) == false // trivially false
- * (new Rational(1, 2)).equals(new Rational(2, 4)) == true // true after reduction
+ * (new Rational(1, 2)).equals(new Rational(1, 2)) == true // trivially true
+ * (new Rational(2, 3)).equals(new Rational(1, 2)) == false // trivially false
+ * (new Rational(1, 2)).equals(new Rational(2, 4)) == true // true after reduction
+ * (new Rational(0, 0)).equals(new Rational(0, 0)) == true // NaN.equals(NaN)
+ * (new Rational(1, 0)).equals(new Rational(5, 0)) == true // both are +infinity
+ * (new Rational(1, 0)).equals(new Rational(-1, 0)) == false // +infinity != -infinity
* </pre>
*
* @param obj a reference to another object
@@ -91,13 +108,17 @@ public final class Rational {
public boolean equals(Object obj) {
if (obj == null) {
return false;
- }
- if (this == obj) {
- return true;
- }
- if (obj instanceof Rational) {
+ } else if (obj instanceof Rational) {
Rational other = (Rational) obj;
- if(mNumerator == other.mNumerator && mDenominator == other.mDenominator) {
+ if (mDenominator == 0 || other.mDenominator == 0) {
+ if (isNaN() && other.isNaN()) {
+ return true;
+ } else if (isInf() && other.isInf() || isNegInf() && other.isNegInf()) {
+ return true;
+ } else {
+ return false;
+ }
+ } else if (mNumerator == other.mNumerator && mDenominator == other.mDenominator) {
return true;
} else {
int thisGcd = gcd();
@@ -117,7 +138,25 @@ public final class Rational {
@Override
public String toString() {
- return mNumerator + "/" + mDenominator;
+ if (isNaN()) {
+ return "NaN";
+ } else if (isInf()) {
+ return "Infinity";
+ } else if (isNegInf()) {
+ return "-Infinity";
+ } else {
+ return mNumerator + "/" + mDenominator;
+ }
+ }
+
+ /**
+ * <p>Convert to a floating point representation.</p>
+ *
+ * @return The floating point representation of this rational number.
+ * @hide
+ */
+ public float toFloat() {
+ return (float) mNumerator / (float) mDenominator;
}
@Override
diff --git a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
index fbe7ff4..2c05c58 100644
--- a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
+++ b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
@@ -49,7 +49,7 @@ public class CameraBinderDecorator {
public static final int EACCES = -13;
public static final int EBUSY = -16;
public static final int ENODEV = -19;
- public static final int ENOTSUP = -129;
+ public static final int EOPNOTSUPP = -95;
private static class CameraBinderDecoratorListener implements Decorator.DecoratorListener {
@@ -86,7 +86,7 @@ public class CameraBinderDecorator {
case ENODEV:
UncheckedThrow.throwAnyException(new CameraRuntimeException(
CAMERA_DISCONNECTED));
- case ENOTSUP:
+ case EOPNOTSUPP:
UncheckedThrow.throwAnyException(new CameraRuntimeException(
CAMERA_DEPRECATED_HAL));
}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 38ffb96..dbaa325 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -2380,22 +2380,25 @@ public abstract class BatteryStats implements Parcelable {
@SuppressWarnings("unused")
public void dumpCheckinLocked(
- PrintWriter pw, List<ApplicationInfo> apps, boolean isUnpluggedOnly) {
+ PrintWriter pw, List<ApplicationInfo> apps, boolean isUnpluggedOnly,
+ boolean includeHistory) {
prepareForDumpLocked();
long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
- final HistoryItem rec = new HistoryItem();
- if (startIteratingHistoryLocked()) {
- HistoryPrinter hprinter = new HistoryPrinter();
- while (getNextHistoryLocked(rec)) {
- pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
- pw.print(0); pw.print(',');
- pw.print(HISTORY_DATA); pw.print(',');
- hprinter.printNextItemCheckin(pw, rec, now);
- pw.println();
+ if (includeHistory) {
+ final HistoryItem rec = new HistoryItem();
+ if (startIteratingHistoryLocked()) {
+ HistoryPrinter hprinter = new HistoryPrinter();
+ while (getNextHistoryLocked(rec)) {
+ pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
+ pw.print(0); pw.print(',');
+ pw.print(HISTORY_DATA); pw.print(',');
+ hprinter.printNextItemCheckin(pw, rec, now);
+ pw.println();
+ }
+ finishIteratingHistoryLocked();
}
- finishIteratingHistoryLocked();
}
if (apps != null) {
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 83426ae..10b9765 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -357,7 +357,18 @@ public class UserManager {
* @param restrictionKey the string key representing the restriction
*/
public boolean hasUserRestriction(String restrictionKey) {
- return getUserRestrictions().getBoolean(restrictionKey, false);
+ return hasUserRestriction(restrictionKey, Process.myUserHandle());
+ }
+
+ /**
+ * @hide
+ * Returns whether the given user has been disallowed from performing certain actions
+ * or setting certain settings.
+ * @param restrictionKey the string key representing the restriction
+ * @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
+ */
+ public boolean hasUserRestriction(String restrictionKey, UserHandle userHandle) {
+ return getUserRestrictions(userHandle).getBoolean(restrictionKey, false);
}
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 83e1544..eb5430c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5107,6 +5107,21 @@ public final class Settings {
"wifi_display_certification_on";
/**
+ * WPS Configuration method used by Wifi display, this setting only
+ * takes effect when WIFI_DISPLAY_CERTIFICATION_ON is 1 (enabled).
+ *
+ * Possible values are:
+ *
+ * WpsInfo.INVALID: use default WPS method chosen by framework
+ * WpsInfo.PBC : use Push button
+ * WpsInfo.KEYPAD : use Keypad
+ * WpsInfo.DISPLAY: use Display
+ * @hide
+ */
+ public static final String WIFI_DISPLAY_WPS_CONFIG =
+ "wifi_display_wps_config";
+
+ /**
* Whether to notify the user of open networks.
* <p>
* If not connected and the scan results have an open network, we will
@@ -5268,6 +5283,13 @@ public final class Settings {
"data_stall_alarm_aggressive_delay_in_ms";
/**
+ * The number of milliseconds to allow the provisioning apn to remain active
+ * @hide
+ */
+ public static final String PROVISIONING_APN_ALARM_DELAY_IN_MS =
+ "provisioning_apn_alarm_delay_in_ms";
+
+ /**
* The interval in milliseconds at which to check gprs registration
* after the first registration mismatch of gprs and voice service,
* to detect possible data network registration problems.
diff --git a/core/java/android/view/transition/AutoTransition.java b/core/java/android/transition/AutoTransition.java
index 7ddac7e..6e46021 100644
--- a/core/java/android/view/transition/AutoTransition.java
+++ b/core/java/android/transition/AutoTransition.java
@@ -14,22 +14,28 @@
* limitations under the License.
*/
-package android.view.transition;
+package android.transition;
/**
* Utility class for creating a default transition that automatically fades,
* moves, and resizes views during a scene change.
+ *
+ * <p>An AutoTransition can be described in a resource file by using the
+ * tag <code>autoTransition</code>, along with the other standard
+ * attributes of {@link android.R.styleable#Transition}.</p>
*/
-public class AutoTransition extends TransitionGroup {
+public class AutoTransition extends TransitionSet {
/**
- * Constructs an AutoTransition object, which is a TransitionGroup which
+ * Constructs an AutoTransition object, which is a TransitionSet which
* first fades out disappearing targets, then moves and resizes existing
* targets, and finally fades in appearing targets.
*
*/
public AutoTransition() {
- setOrdering(SEQUENTIALLY);
- addTransitions(new Fade(Fade.OUT), new Move(), new Fade(Fade.IN));
+ setOrdering(ORDERING_SEQUENTIAL);
+ addTransition(new Fade(Fade.OUT)).
+ addTransition(new ChangeBounds()).
+ addTransition(new Fade(Fade.IN));
}
}
diff --git a/core/java/android/view/transition/Move.java b/core/java/android/transition/ChangeBounds.java
index fda0cd2..8053bff 100644
--- a/core/java/android/view/transition/Move.java
+++ b/core/java/android/transition/ChangeBounds.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.view.transition;
+package android.transition;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -33,13 +33,17 @@ import java.util.Map;
/**
* This transition captures the layout bounds of target views before and after
* the scene change and animates those changes during the transition.
+ *
+ * <p>A ChangeBounds transition can be described in a resource file by using the
+ * tag <code>changeBounds</code>, along with the other standard
+ * attributes of {@link android.R.styleable#Transition}.</p>
*/
-public class Move extends Transition {
+public class ChangeBounds extends Transition {
- private static final String PROPNAME_BOUNDS = "android:move:bounds";
- private static final String PROPNAME_PARENT = "android:move:parent";
- private static final String PROPNAME_WINDOW_X = "android:move:windowX";
- private static final String PROPNAME_WINDOW_Y = "android:move:windowY";
+ private static final String PROPNAME_BOUNDS = "android:changeBounds:bounds";
+ private static final String PROPNAME_PARENT = "android:changeBounds:parent";
+ private static final String PROPNAME_WINDOW_X = "android:changeBounds:windowX";
+ private static final String PROPNAME_WINDOW_Y = "android:changeBounds:windowY";
private static final String[] sTransitionProperties = {
PROPNAME_BOUNDS,
PROPNAME_PARENT,
@@ -50,7 +54,7 @@ public class Move extends Transition {
int[] tempLocation = new int[2];
boolean mResizeClip = false;
boolean mReparent = false;
- private static final String LOG_TAG = "Move";
+ private static final String LOG_TAG = "ChangeBounds";
private static RectEvaluator sRectEvaluator = new RectEvaluator();
@@ -64,7 +68,7 @@ public class Move extends Transition {
}
/**
- * Setting this flag tells Move to track the before/after parent
+ * Setting this flag tells ChangeBounds to track the before/after parent
* of every view using this transition. The flag is not enabled by
* default because it requires the parent instances to be the same
* in the two scenes or else all parents must use ids to allow
@@ -77,8 +81,7 @@ public class Move extends Transition {
mReparent = reparent;
}
- @Override
- protected void captureValues(TransitionValues values, boolean start) {
+ private void captureValues(TransitionValues values) {
View view = values.view;
values.values.put(PROPNAME_BOUNDS, new Rect(view.getLeft(), view.getTop(),
view.getRight(), view.getBottom()));
@@ -89,7 +92,17 @@ public class Move extends Transition {
}
@Override
- protected Animator play(final ViewGroup sceneRoot, TransitionValues startValues,
+ public void captureStartValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ @Override
+ public void captureEndValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ @Override
+ public Animator createAnimator(final ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
if (startValues == null || endValues == null) {
return null;
@@ -105,7 +118,7 @@ public class Move extends Transition {
boolean parentsEqual = (startParent == endParent) ||
(startParent.getId() == endParent.getId());
// TODO: Might want reparenting to be separate/subclass transition, or at least
- // triggered by a property on Move. Otherwise, we're forcing the requirement that
+ // triggered by a property on ChangeBounds. Otherwise, we're forcing the requirement that
// all parents in layouts have IDs to avoid layout-inflation resulting in a side-effect
// of reparenting the views.
if (!mReparent || parentsEqual) {
diff --git a/core/java/android/view/transition/Crossfade.java b/core/java/android/transition/Crossfade.java
index 18bb57f..69ce872 100644
--- a/core/java/android/view/transition/Crossfade.java
+++ b/core/java/android/transition/Crossfade.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.view.transition;
+package android.transition;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -24,10 +24,8 @@ import android.animation.RectEvaluator;
import android.animation.ValueAnimator;
import android.graphics.Bitmap;
import android.graphics.Canvas;
-import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.SurfaceView;
import android.view.TextureView;
@@ -43,6 +41,8 @@ import java.util.Map;
*
* <p>Note: This transition is not compatible with {@link TextureView}
* or {@link SurfaceView}.</p>
+ *
+ * @hide
*/
public class Crossfade extends Transition {
// TODO: Add a hook that lets a Transition call user code to query whether it should run on
@@ -121,12 +121,19 @@ public class Crossfade extends Transition {
* @param fadeBehavior The type of fading animation to use when this
* transition is run.
*/
- public void setFadeBehavior(int fadeBehavior) {
+ public Crossfade setFadeBehavior(int fadeBehavior) {
if (fadeBehavior >= FADE_BEHAVIOR_CROSSFADE && fadeBehavior <= FADE_BEHAVIOR_OUT_IN) {
mFadeBehavior = fadeBehavior;
}
+ return this;
}
+ /**
+ * Returns the fading behavior of the animation.
+ *
+ * @return This crossfade object.
+ * @see #setFadeBehavior(int)
+ */
public int getFadeBehavior() {
return mFadeBehavior;
}
@@ -139,18 +146,25 @@ public class Crossfade extends Transition {
* @param resizeBehavior The type of resizing behavior to use when this
* transition is run.
*/
- public void setResizeBehavior(int resizeBehavior) {
+ public Crossfade setResizeBehavior(int resizeBehavior) {
if (resizeBehavior >= RESIZE_BEHAVIOR_NONE && resizeBehavior <= RESIZE_BEHAVIOR_SCALE) {
mResizeBehavior = resizeBehavior;
}
+ return this;
}
+ /**
+ * Returns the resizing behavior of the animation.
+ *
+ * @return This crossfade object.
+ * @see #setResizeBehavior(int)
+ */
public int getResizeBehavior() {
return mResizeBehavior;
}
@Override
- protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+ public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
if (startValues == null || endValues == null) {
return null;
@@ -243,18 +257,16 @@ public class Crossfade extends Transition {
}
}
- @Override
- protected void captureValues(TransitionValues values, boolean start) {
- View view = values.view;
+ private void captureValues(TransitionValues transitionValues) {
+ View view = transitionValues.view;
Rect bounds = new Rect(0, 0, view.getWidth(), view.getHeight());
if (mFadeBehavior != FADE_BEHAVIOR_REVEAL) {
bounds.offset(view.getLeft(), view.getTop());
}
- values.values.put(PROPNAME_BOUNDS, bounds);
+ transitionValues.values.put(PROPNAME_BOUNDS, bounds);
if (Transition.DBG) {
- Log.d(LOG_TAG, "Captured bounds " + values.values.get(PROPNAME_BOUNDS) + ": start = " +
- start);
+ Log.d(LOG_TAG, "Captured bounds " + transitionValues.values.get(PROPNAME_BOUNDS));
}
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
Bitmap.Config.ARGB_8888);
@@ -264,12 +276,21 @@ public class Crossfade extends Transition {
Canvas c = new Canvas(bitmap);
view.draw(c);
}
- values.values.put(PROPNAME_BITMAP, bitmap);
+ transitionValues.values.put(PROPNAME_BITMAP, bitmap);
// TODO: I don't have resources, can't call the non-deprecated method?
BitmapDrawable drawable = new BitmapDrawable(bitmap);
// TODO: lrtb will be wrong if the view has transXY set
drawable.setBounds(bounds);
- values.values.put(PROPNAME_DRAWABLE, drawable);
+ transitionValues.values.put(PROPNAME_DRAWABLE, drawable);
}
+ @Override
+ public void captureStartValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ @Override
+ public void captureEndValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
}
diff --git a/core/java/android/view/transition/Fade.java b/core/java/android/transition/Fade.java
index 45c21d8..12e0d73 100644
--- a/core/java/android/view/transition/Fade.java
+++ b/core/java/android/transition/Fade.java
@@ -14,12 +14,11 @@
* limitations under the License.
*/
-package android.view.transition;
+package android.transition;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
@@ -30,6 +29,12 @@ import android.view.ViewGroup;
* or non-visible. Visibility is determined by both the
* {@link View#setVisibility(int)} state of the view as well as whether it
* is parented in the current view hierarchy.
+ *
+ * <p>A Fade transition can be described in a resource file by using the
+ * tag <code>fade</code>, along with the standard
+ * attributes of {@link android.R.styleable#Fade} and
+ * {@link android.R.styleable#Transition}.</p>
+
*/
public class Fade extends Visibility {
@@ -93,21 +98,31 @@ public class Fade extends Visibility {
return anim;
}
- @Override
- protected void captureValues(TransitionValues values, boolean start) {
- super.captureValues(values, start);
- float alpha = values.view.getAlpha();
- values.values.put(PROPNAME_ALPHA, alpha);
+ private void captureValues(TransitionValues transitionValues) {
+ float alpha = transitionValues.view.getAlpha();
+ transitionValues.values.put(PROPNAME_ALPHA, alpha);
int[] loc = new int[2];
- values.view.getLocationOnScreen(loc);
- values.values.put(PROPNAME_SCREEN_X, loc[0]);
- values.values.put(PROPNAME_SCREEN_Y, loc[1]);
+ transitionValues.view.getLocationOnScreen(loc);
+ transitionValues.values.put(PROPNAME_SCREEN_X, loc[0]);
+ transitionValues.values.put(PROPNAME_SCREEN_Y, loc[1]);
+ }
+
+ @Override
+ public void captureStartValues(TransitionValues transitionValues) {
+ super.captureStartValues(transitionValues);
+ captureValues(transitionValues);
+ }
+
+
+ @Override
+ public void captureEndValues(TransitionValues transitionValues) {
+ super.captureEndValues(transitionValues);
}
@Override
- protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+ public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
- Animator animator = super.play(sceneRoot, startValues, endValues);
+ Animator animator = super.createAnimator(sceneRoot, startValues, endValues);
if (animator == null && startValues != null && endValues != null) {
boolean endVisible = isVisible(endValues);
final View endView = endValues.view;
@@ -122,13 +137,18 @@ public class Fade extends Visibility {
}
@Override
- protected Animator appear(ViewGroup sceneRoot,
+ public Animator onAppear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
if ((mFadingMode & IN) != IN || endValues == null) {
return null;
}
final View endView = endValues.view;
+ if (DBG) {
+ View startView = (startValues != null) ? startValues.view : null;
+ Log.d(LOG_TAG, "Fade.onDisappear: startView, startVis, endView, endVis = " +
+ startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
+ }
// if alpha < 1, just fade it in from the current value
if (endView.getAlpha() == 1.0f) {
endView.setAlpha(0);
@@ -137,7 +157,7 @@ public class Fade extends Visibility {
}
@Override
- protected Animator disappear(ViewGroup sceneRoot,
+ public Animator onDisappear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
if ((mFadingMode & OUT) != OUT) {
@@ -147,7 +167,7 @@ public class Fade extends Visibility {
View startView = (startValues != null) ? startValues.view : null;
View endView = (endValues != null) ? endValues.view : null;
if (DBG) {
- Log.d(LOG_TAG, "Fade.predisappear: startView, startVis, endView, endVis = " +
+ Log.d(LOG_TAG, "Fade.onDisappear: startView, startVis, endView, endVis = " +
startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
}
View overlayView = null;
diff --git a/core/java/android/view/transition/Recolor.java b/core/java/android/transition/Recolor.java
index e4858c4..70111d1 100644
--- a/core/java/android/view/transition/Recolor.java
+++ b/core/java/android/transition/Recolor.java
@@ -14,20 +14,17 @@
* limitations under the License.
*/
-package android.view.transition;
+package android.transition;
import android.animation.Animator;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
-import android.util.ArrayMap;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
-import java.util.Map;
-
/**
* This transition tracks changes during scene changes to the
* {@link View#setBackground(android.graphics.drawable.Drawable) background}
@@ -36,22 +33,34 @@ import java.util.Map;
* {@link TextView#setTextColor(android.content.res.ColorStateList)
* color} of the text for target TextViews. If the color changes between
* scenes, the color change is animated.
+ *
+ * @hide
*/
public class Recolor extends Transition {
private static final String PROPNAME_BACKGROUND = "android:recolor:background";
private static final String PROPNAME_TEXT_COLOR = "android:recolor:textColor";
- @Override
- protected void captureValues(TransitionValues values, boolean start) {
- values.values.put(PROPNAME_BACKGROUND, values.view.getBackground());
- if (values.view instanceof TextView) {
- values.values.put(PROPNAME_TEXT_COLOR, ((TextView)values.view).getCurrentTextColor());
+ private void captureValues(TransitionValues transitionValues) {
+ transitionValues.values.put(PROPNAME_BACKGROUND, transitionValues.view.getBackground());
+ if (transitionValues.view instanceof TextView) {
+ transitionValues.values.put(PROPNAME_TEXT_COLOR,
+ ((TextView)transitionValues.view).getCurrentTextColor());
}
}
@Override
- protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+ public void captureStartValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ @Override
+ public void captureEndValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ @Override
+ public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
if (startValues == null || endValues == null) {
return null;
diff --git a/core/java/android/view/transition/Rotate.java b/core/java/android/transition/Rotate.java
index d35a6dc7..ad1720c 100644
--- a/core/java/android/view/transition/Rotate.java
+++ b/core/java/android/transition/Rotate.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.view.transition;
+package android.transition;
import android.animation.Animator;
import android.animation.ObjectAnimator;
@@ -24,18 +24,25 @@ import android.view.ViewGroup;
/**
* This transition captures the rotation property of targets before and after
* the scene change and animates any changes.
+ *
+ * @hide
*/
public class Rotate extends Transition {
private static final String PROPNAME_ROTATION = "android:rotate:rotation";
@Override
- protected void captureValues(TransitionValues values, boolean start) {
- values.values.put(PROPNAME_ROTATION, values.view.getRotation());
+ public void captureStartValues(TransitionValues transitionValues) {
+ transitionValues.values.put(PROPNAME_ROTATION, transitionValues.view.getRotation());
+ }
+
+ @Override
+ public void captureEndValues(TransitionValues transitionValues) {
+ transitionValues.values.put(PROPNAME_ROTATION, transitionValues.view.getRotation());
}
@Override
- protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+ public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
if (startValues == null || endValues == null) {
return null;
diff --git a/core/java/android/view/transition/Scene.java b/core/java/android/transition/Scene.java
index cf3eadb..f81eeef 100644
--- a/core/java/android/view/transition/Scene.java
+++ b/core/java/android/transition/Scene.java
@@ -14,10 +14,12 @@
* limitations under the License.
*/
-package android.view.transition;
+package android.transition;
import android.content.Context;
+import android.util.SparseArray;
import android.view.LayoutInflater;
+import android.view.View;
import android.view.ViewGroup;
/**
@@ -34,6 +36,37 @@ public final class Scene {
private ViewGroup mSceneRoot;
private ViewGroup mLayout; // alternative to layoutId
Runnable mEnterAction, mExitAction;
+ private static ThreadLocal<SparseArray<Scene>> sScenes = new ThreadLocal<SparseArray<Scene>>();
+
+ /**
+ * Returns a Scene described by the resource file associated with the given
+ * <code>layoutId</code> parameter. If such a Scene has already been created,
+ * that same Scene will be returned. This caching of layoutId-based scenes enables
+ * sharing of common scenes between those created in code and those referenced
+ * by {@link TransitionManager} XML resource files.
+ *
+ * @param sceneRoot The root of the hierarchy in which scene changes
+ * and transitions will take place.
+ * @param layoutId The id of a standard layout resource file.
+ * @param context The context used in the process of inflating
+ * the layout resource.
+ * @return
+ */
+ public static Scene getSceneForLayout(ViewGroup sceneRoot, int layoutId, Context context) {
+ SparseArray<Scene> scenes = sScenes.get();
+ if (scenes == null) {
+ scenes = new SparseArray<Scene>();
+ sScenes.set(scenes);
+ }
+ Scene scene = scenes.get(layoutId);
+ if (scene != null) {
+ return scene;
+ } else {
+ scene = new Scene(sceneRoot, layoutId, context);
+ scenes.put(layoutId, scene);
+ return scene;
+ }
+ }
/**
* Constructs a Scene with no information about how values will change
@@ -54,6 +87,9 @@ public final class Scene {
* children from the sceneRoot container and will inflate and add
* the hierarchy specified by the layoutId resource file.
*
+ * <p>This method is hidden because layoutId-based scenes should be
+ * created by the caching factory method {@link Scene#getCurrentScene(View)}.</p>
+ *
* @param sceneRoot The root of the hierarchy in which scene changes
* and transitions will take place.
* @param layoutId The id of a resource file that defines the view
@@ -61,7 +97,7 @@ public final class Scene {
* @param context The context used in the process of inflating
* the layout resource.
*/
- public Scene(ViewGroup sceneRoot, int layoutId, Context context) {
+ private Scene(ViewGroup sceneRoot, int layoutId, Context context) {
mContext = context;
mSceneRoot = sceneRoot;
mLayoutId = layoutId;
@@ -74,7 +110,7 @@ public final class Scene {
*
* @param sceneRoot The root of the hierarchy in which scene changes
* and transitions will take place.
- * @param layout The view hiearrchy of this scene, added as a child
+ * @param layout The view hierarchy of this scene, added as a child
* of sceneRoot when this scene is entered.
*/
public Scene(ViewGroup sceneRoot, ViewGroup layout) {
@@ -94,19 +130,14 @@ public final class Scene {
}
/**
- * Exits this scene, if it is the {@link ViewGroup#getCurrentScene()
- * currentScene} on the scene's {@link #getSceneRoot() scene root}.
- * Exiting a scene involves removing the layout added if the scene
- * has either a layoutId or layout view group (set at construction
- * time) and running the {@link #setExitAction(Runnable) exit action}
+ * Exits this scene, if it is the current scene
+ * on the scene's {@link #getSceneRoot() scene root}. The current scene is
+ * set when {@link #enter() entering} a scene.
+ * Exiting a scene runs the {@link #setExitAction(Runnable) exit action}
* if there is one.
*/
public void exit() {
- if (mSceneRoot.getCurrentScene() == this) {
- if (mLayoutId >= 0 || mLayout != null) {
- // Undo layout change caused by entering this scene
- getSceneRoot().removeAllViews();
- }
+ if (getCurrentScene(mSceneRoot) == this) {
if (mExitAction != null) {
mExitAction.run();
}
@@ -127,8 +158,7 @@ public final class Scene {
// Apply layout change, if any
if (mLayoutId >= 0 || mLayout != null) {
- // redundant with exit() action of previous scene, but must
- // empty out that parent container before adding to it
+ // empty out parent container before adding to it
getSceneRoot().removeAllViews();
if (mLayoutId >= 0) {
@@ -143,7 +173,30 @@ public final class Scene {
mEnterAction.run();
}
- mSceneRoot.setCurrentScene(this );
+ setCurrentScene(mSceneRoot, this);
+ }
+
+ /**
+ * Set the scene that the given view is in. The current scene is set only
+ * on the root view of a scene, not for every view in that hierarchy. This
+ * information is used by Scene to determine whether there is a previous
+ * scene which should be exited before the new scene is entered.
+ *
+ * @param view The view on which the current scene is being set
+ */
+ static void setCurrentScene(View view, Scene scene) {
+ view.setTagInternal(com.android.internal.R.id.current_scene, scene);
+ }
+
+ /**
+ * Gets the current {@link Scene} set on the given view. A scene is set on a view
+ * only if that view is the scene root.
+ *
+ * @return The current Scene set on this view. A value of null indicates that
+ * no Scene is currently set.
+ */
+ static Scene getCurrentScene(View view) {
+ return (Scene) view.getTag(com.android.internal.R.id.current_scene);
}
/**
diff --git a/core/java/android/view/transition/Slide.java b/core/java/android/transition/Slide.java
index b2f5db5..b38973c 100644
--- a/core/java/android/view/transition/Slide.java
+++ b/core/java/android/transition/Slide.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.view.transition;
+package android.transition;
import android.animation.Animator;
import android.animation.ObjectAnimator;
@@ -28,6 +28,8 @@ import android.view.animation.DecelerateInterpolator;
* This transition captures the visibility of target objects before and
* after a scene change and animates any changes by sliding the target
* objects into or out of place.
+ *
+ * @hide
*/
public class Slide extends Visibility {
@@ -37,7 +39,7 @@ public class Slide extends Visibility {
private static final TimeInterpolator sDecelerator = new DecelerateInterpolator();
@Override
- protected Animator appear(ViewGroup sceneRoot,
+ public Animator onAppear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
View endView = (endValues != null) ? endValues.view : null;
@@ -49,7 +51,7 @@ public class Slide extends Visibility {
}
@Override
- protected Animator disappear(ViewGroup sceneRoot,
+ public Animator onDisappear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
View startView = (startValues != null) ? startValues.view : null;
diff --git a/core/java/android/view/transition/TextChange.java b/core/java/android/transition/TextChange.java
index 7973c97..1b26942 100644
--- a/core/java/android/view/transition/TextChange.java
+++ b/core/java/android/transition/TextChange.java
@@ -14,14 +14,13 @@
* limitations under the License.
*/
-package android.view.transition;
+package android.transition;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.graphics.Color;
-import android.util.ArrayMap;
import android.view.ViewGroup;
import android.widget.TextView;
@@ -33,6 +32,8 @@ import java.util.Map;
* starting text stays until the transition ends, at which point it changes
* to the end text. This is useful in situations where you want to resize a
* text view to its new size before displaying the text that goes there.
+ *
+ * @hide
*/
public class TextChange extends Transition {
private static final String PROPNAME_TEXT = "android:textchange:text";
@@ -84,15 +85,18 @@ public class TextChange extends Transition {
/**
* Sets the type of changing animation that will be run, one of
- * {@link #CHANGE_BEHAVIOR_KEEP} and {@link #CHANGE_BEHAVIOR_OUT_IN}.
+ * {@link #CHANGE_BEHAVIOR_KEEP}, {@link #CHANGE_BEHAVIOR_OUT},
+ * {@link #CHANGE_BEHAVIOR_IN}, and {@link #CHANGE_BEHAVIOR_OUT_IN}.
*
* @param changeBehavior The type of fading animation to use when this
* transition is run.
+ * @return this textChange object.
*/
- public void setChangeBehavior(int changeBehavior) {
+ public TextChange setChangeBehavior(int changeBehavior) {
if (changeBehavior >= CHANGE_BEHAVIOR_KEEP && changeBehavior <= CHANGE_BEHAVIOR_OUT_IN) {
mChangeBehavior = changeBehavior;
}
+ return this;
}
@Override
@@ -100,19 +104,38 @@ public class TextChange extends Transition {
return sTransitionProperties;
}
- @Override
- protected void captureValues(TransitionValues values, boolean start) {
- if (values.view instanceof TextView) {
- TextView textview = (TextView) values.view;
- values.values.put(PROPNAME_TEXT, textview.getText());
+ /**
+ * Returns the type of changing animation that will be run.
+ *
+ * @return either {@link #CHANGE_BEHAVIOR_KEEP}, {@link #CHANGE_BEHAVIOR_OUT},
+ * {@link #CHANGE_BEHAVIOR_IN}, or {@link #CHANGE_BEHAVIOR_OUT_IN}.
+ */
+ public int getChangeBehavior() {
+ return mChangeBehavior;
+ }
+
+ private void captureValues(TransitionValues transitionValues) {
+ if (transitionValues.view instanceof TextView) {
+ TextView textview = (TextView) transitionValues.view;
+ transitionValues.values.put(PROPNAME_TEXT, textview.getText());
if (mChangeBehavior > CHANGE_BEHAVIOR_KEEP) {
- values.values.put(PROPNAME_TEXT_COLOR, textview.getCurrentTextColor());
+ transitionValues.values.put(PROPNAME_TEXT_COLOR, textview.getCurrentTextColor());
}
}
}
@Override
- protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+ public void captureStartValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ @Override
+ public void captureEndValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
+ @Override
+ public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
if (startValues == null || endValues == null || !(endValues.view instanceof TextView)) {
return null;
diff --git a/core/java/android/view/transition/Transition.java b/core/java/android/transition/Transition.java
index a66fa52..59df183 100644
--- a/core/java/android/view/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.view.transition;
+package android.transition;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -31,11 +31,12 @@ import android.view.ViewOverlay;
import android.widget.ListView;
import java.util.ArrayList;
+import java.util.List;
/**
* A Transition holds information about animations that will be run on its
* targets during a scene change. Subclasses of this abstract class may
- * choreograph several child transitions ({@link TransitionGroup} or they may
+ * choreograph several child transitions ({@link TransitionSet} or they may
* perform custom animations themselves. Any Transition has two main jobs:
* (1) capture property values, and (2) play animations based on changes to
* captured property values. A custom transition knows what property values
@@ -50,9 +51,42 @@ import java.util.ArrayList;
* a non-UI thread, so changes to the view due to transitions (such as moving
* and resizing the view) may be out of sync with the display inside those bounds.
* TextureView is more compatible with transitions in general, but some
- * specific transitions (such as {@link Crossfade}) may not be compatible
+ * specific transitions (such as {@link Fade}) may not be compatible
* with TextureView because they rely on {@link ViewOverlay} functionality,
* which does not currently work with TextureView.</p>
+ *
+ * <p>Transitions can be declared in XML resource files inside the <code>res/transition</code>
+ * directory. Transition resources consist of a tag name for one of the Transition
+ * subclasses along with attributes to define some of the attributes of that transition.
+ * For example, here is a minimal resource file that declares a {@link ChangeBounds} transition:</p>
+ *
+ * {@sample development/samples/ApiDemos/res/transition/changebounds.xml ChangeBounds}
+ *
+ * <p>Note that attributes for the transition are not required, just as they are
+ * optional when declared in code; Transitions created from XML resources will use
+ * the same defaults as their code-created equivalents. Here is a slightly more
+ * elaborate example which declares a {@link TransitionSet} transition with
+ * {@link ChangeBounds} and {@link Fade} child transitions:</p>
+ *
+ * {@sample
+ * development/samples/ApiDemos/res/transition/changebounds_fadeout_sequential.xml TransitionSet}
+ *
+ * <p>In this example, the transitionOrdering attribute is used on the TransitionSet
+ * object to change from the default {@link TransitionSet#ORDERING_TOGETHER} behavior
+ * to be {@link TransitionSet#ORDERING_SEQUENTIAL} instead. Also, the {@link Fade}
+ * transition uses a fadingMode of {@link Fade#OUT} instead of the default
+ * out-in behavior. Finally, note the use of the <code>targets</code> sub-tag, which
+ * takes a set of {@link android.R.styleable#TransitionTarget target} tags, each
+ * of which lists a specific <code>targetId</code> which this transition acts upon.
+ * Use of targets is optional, but can be used to either limit the time spent checking
+ * attributes on unchanging views, or limiting the types of animations run on specific views.
+ * In this case, we know that only the <code>grayscaleContainer</code> will be
+ * disappearing, so we choose to limit the {@link Fade} transition to only that view.</p>
+ *
+ * Further information on XML resource descriptions for transitions can be found for
+ * {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet},
+ * {@link android.R.styleable#TransitionTarget}, and {@link android.R.styleable#Fade}.
+ *
*/
public abstract class Transition implements Cloneable {
@@ -64,17 +98,17 @@ public abstract class Transition implements Cloneable {
long mStartDelay = -1;
long mDuration = -1;
TimeInterpolator mInterpolator = null;
- int[] mTargetIds;
- View[] mTargets;
+ ArrayList<Integer> mTargetIds = new ArrayList<Integer>();
+ ArrayList<View> mTargets = new ArrayList<View>();
private TransitionValuesMaps mStartValues = new TransitionValuesMaps();
private TransitionValuesMaps mEndValues = new TransitionValuesMaps();
- TransitionGroup mParent = null;
+ TransitionSet mParent = null;
// Per-animator information used for later canceling when future transitions overlap
private static ThreadLocal<ArrayMap<Animator, AnimationInfo>> sRunningAnimators =
new ThreadLocal<ArrayMap<Animator, AnimationInfo>>();
- // Scene Root is set at play() time in the cloned Transition
+ // Scene Root is set at createAnimator() time in the cloned Transition
ViewGroup mSceneRoot = null;
// Track all animators in use in case the transition gets canceled and needs to
@@ -91,14 +125,15 @@ public abstract class Transition implements Cloneable {
// The set of listeners to be sent transition lifecycle events.
ArrayList<TransitionListener> mListeners = null;
- // The set of animators collected from calls to play(), to be run in runAnimations()
+ // The set of animators collected from calls to createAnimator(),
+ // to be run in runAnimators()
ArrayList<Animator> mAnimators = new ArrayList<Animator>();
/**
* Constructs a Transition object with no target objects. A transition with
* no targets defaults to running on all target objects in the scene hierarchy
- * (if the transition is not contained in a TransitionGroup), or all target
- * objects passed down from its parent (if it is in a TransitionGroup).
+ * (if the transition is not contained in a TransitionSet), or all target
+ * objects passed down from its parent (if it is in a TransitionSet).
*/
public Transition() {}
@@ -110,6 +145,7 @@ public abstract class Transition implements Cloneable {
*
* @param duration The length of the animation, in milliseconds.
* @return This transition object.
+ * @attr ref android.R.styleable#Transition_duration
*/
public Transition setDuration(long duration) {
mDuration = duration;
@@ -121,8 +157,8 @@ public abstract class Transition implements Cloneable {
* the returned value will be negative, indicating that resulting animators will
* retain their own durations.
*
- * @return The duration set on this transition, if one has been set, otherwise
- * returns a negative number.
+ * @return The duration set on this transition, in milliseconds, if one has been
+ * set, otherwise returns a negative number.
*/
public long getDuration() {
return mDuration;
@@ -135,9 +171,12 @@ public abstract class Transition implements Cloneable {
* Transition is set, that delay will override the Animator delay.
*
* @param startDelay The length of the delay, in milliseconds.
+ * @return This transition object.
+ * @attr ref android.R.styleable#Transition_startDelay
*/
- public void setStartDelay(long startDelay) {
+ public Transition setStartDelay(long startDelay) {
mStartDelay = startDelay;
+ return this;
}
/**
@@ -145,8 +184,8 @@ public abstract class Transition implements Cloneable {
* the returned value will be negative, indicating that resulting animators will
* retain their own startDelays.
*
- * @return The startDealy set on this transition, if one has been set, otherwise
- * returns a negative number.
+ * @return The startDelay set on this transition, in milliseconds, if one has
+ * been set, otherwise returns a negative number.
*/
public long getStartDelay() {
return mStartDelay;
@@ -159,9 +198,12 @@ public abstract class Transition implements Cloneable {
* Transition is set, that interpolator will override the Animator interpolator.
*
* @param interpolator The time interpolator used by the transition
+ * @return This transition object.
+ * @attr ref android.R.styleable#Transition_interpolator
*/
- public void setInterpolator(TimeInterpolator interpolator) {
+ public Transition setInterpolator(TimeInterpolator interpolator) {
mInterpolator = interpolator;
+ return this;
}
/**
@@ -178,7 +220,7 @@ public abstract class Transition implements Cloneable {
/**
* Returns the set of property names used stored in the {@link TransitionValues}
- * object passed into {@link #captureValues(TransitionValues, boolean)} that
+ * object passed into {@link #captureStartValues(TransitionValues)} that
* this transition cares about for the purposes of canceling overlapping animations.
* When any transition is started on a given scene root, all transitions
* currently running on that same scene root are checked to see whether the
@@ -202,11 +244,17 @@ public abstract class Transition implements Cloneable {
}
/**
- * This method is called by the transition's parent (all the way up to the
+ * This method creates an animation that will be run for this transition
+ * given the information in the startValues and endValues structures captured
+ * earlier for the start and end scenes. Subclasses of Transition should override
+ * this method. The method should only be called by the transition system; it is
+ * not intended to be called from external classes.
+ *
+ * <p>This method is called by the transition's parent (all the way up to the
* topmost Transition in the hierarchy) with the sceneRoot and start/end
* values that the transition may need to set up initial target values
* and construct an appropriate animation. For example, if an overall
- * Transition is a {@link TransitionGroup} consisting of several
+ * Transition is a {@link TransitionSet} consisting of several
* child transitions in sequence, then some of the child transitions may
* want to set initial values on target views prior to the overall
* Transition commencing, to put them in an appropriate state for the
@@ -216,14 +264,13 @@ public abstract class Transition implements Cloneable {
* actually starting the animation. This is necessary because the scene
* change that triggers the Transition will automatically set the end-scene
* on all target views, so a Transition that wants to animate from a
- * different value should set that value prior to returning from this method.
+ * different value should set that value prior to returning from this method.</p>
*
* <p>Additionally, a Transition can perform logic to determine whether
* the transition needs to run on the given target and start/end values.
* For example, a transition that resizes objects on the screen may wish
* to avoid running for views which are not present in either the start
- * or end scenes. A return value of <code>null</code> indicates that
- * no animation should run. The default implementation returns null.</p>
+ * or end scenes.</p>
*
* <p>If there is an animator created and returned from this method, the
* transition mechanism will apply any applicable duration, startDelay,
@@ -234,31 +281,34 @@ public abstract class Transition implements Cloneable {
* <p>The method is called for every applicable target object, which is
* stored in the {@link TransitionValues#view} field.</p>
*
- * @param sceneRoot
- * @param startValues
- * @param endValues
- * @return A non-null Animator to be started at the appropriate time in the
- * overall transition for this scene change, null otherwise.
+ *
+ * @param sceneRoot The root of the transition hierarchy.
+ * @param startValues The values for a specific target in the start scene.
+ * @param endValues The values for the target in the end scene.
+ * @return A Animator to be started at the appropriate time in the
+ * overall transition for this scene change. A null value means no animation
+ * should be run.
*/
- protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+ public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
return null;
}
/**
- * This version of play() is called with the entire set of start/end
+ * This method, essentially a wrapper around all calls to createAnimator for all
+ * possible target views, is called with the entire set of start/end
* values. The implementation in Transition iterates through these lists
- * and calls {@link #play(ViewGroup, TransitionValues, TransitionValues)}
+ * and calls {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}
* with each set of start/end values on this transition. The
- * TransitionGroup subclass overrides this method and delegates it to
+ * TransitionSet subclass overrides this method and delegates it to
* each of its children in succession.
*
* @hide
*/
- protected void play(ViewGroup sceneRoot, TransitionValuesMaps startValues,
+ protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues,
TransitionValuesMaps endValues) {
if (DBG) {
- Log.d(LOG_TAG, "play() for " + this);
+ Log.d(LOG_TAG, "createAnimators() for " + this);
}
ArrayMap<View, TransitionValues> endCopy =
new ArrayMap<View, TransitionValues>(endValues.viewValues);
@@ -392,7 +442,7 @@ public abstract class Transition implements Cloneable {
}
}
// TODO: what to do about targetIds and itemIds?
- Animator animator = play(sceneRoot, start, end);
+ Animator animator = createAnimator(sceneRoot, start, end);
if (animator != null) {
// Save animation info for future cancellation purposes
View view = null;
@@ -450,19 +500,19 @@ public abstract class Transition implements Cloneable {
* views are ignored and only the ids are used).
*/
boolean isValidTarget(View target, long targetId) {
- if (mTargetIds == null && mTargets == null) {
+ if (mTargetIds.size() == 0 && mTargets.size() == 0) {
return true;
}
- if (mTargetIds != null) {
- for (int i = 0; i < mTargetIds.length; ++i) {
- if (mTargetIds[i] == targetId) {
+ if (mTargetIds.size() > 0) {
+ for (int i = 0; i < mTargetIds.size(); ++i) {
+ if (mTargetIds.get(i) == targetId) {
return true;
}
}
}
- if (target != null && mTargets != null) {
- for (int i = 0; i < mTargets.length; ++i) {
- if (mTargets[i] == target) {
+ if (target != null && mTargets.size() > 0) {
+ for (int i = 0; i < mTargets.size(); ++i) {
+ if (mTargets.get(i) == target) {
return true;
}
}
@@ -485,13 +535,13 @@ public abstract class Transition implements Cloneable {
*
* @hide
*/
- protected void runAnimations() {
+ protected void runAnimators() {
if (DBG) {
- Log.d(LOG_TAG, "runAnimations() on " + this);
+ Log.d(LOG_TAG, "runAnimators() on " + this);
}
start();
ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
- // Now start every Animator that was previously created for this transition in play()
+ // Now start every Animator that was previously created for this transition
for (Animator anim : mAnimators) {
if (DBG) {
Log.d(LOG_TAG, " anim: " + anim);
@@ -525,17 +575,49 @@ public abstract class Transition implements Cloneable {
}
/**
- * Captures the current scene of values for the properties that this
- * transition monitors. These values can be either the start or end
- * values used in a subsequent call to
- * {@link #play(ViewGroup, TransitionValues, TransitionValues)}, as indicated by
- * <code>start</code>. The main concern for an implementation is what the
+ * Captures the values in the start scene for the properties that this
+ * transition monitors. These values are then passed as the startValues
+ * structure in a later call to
+ * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}.
+ * The main concern for an implementation is what the
+ * properties are that the transition cares about and what the values are
+ * for all of those properties. The start and end values will be compared
+ * later during the
+ * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)}
+ * method to determine what, if any, animations, should be run.
+ *
+ * <p>Subclasses must implement this method. The method should only be called by the
+ * transition system; it is not intended to be called from external classes.</p>
+ *
+ * @param transitionValues The holder for any values that the Transition
+ * wishes to store. Values are stored in the <code>values</code> field
+ * of this TransitionValues object and are keyed from
+ * a String value. For example, to store a view's rotation value,
+ * a transition might call
+ * <code>transitionValues.values.put("appname:transitionname:rotation",
+ * view.getRotation())</code>. The target view will already be stored in
+ * the transitionValues structure when this method is called.
+ *
+ * @see #captureEndValues(TransitionValues)
+ * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues)
+ */
+ public abstract void captureStartValues(TransitionValues transitionValues);
+
+ /**
+ * Captures the values in the end scene for the properties that this
+ * transition monitors. These values are then passed as the endValues
+ * structure in a later call to
+ * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}.
+ * The main concern for an implementation is what the
* properties are that the transition cares about and what the values are
* for all of those properties. The start and end values will be compared
* later during the
- * {@link #play(android.view.ViewGroup, TransitionValues, TransitionValues)}
+ * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)}
* method to determine what, if any, animations, should be run.
*
+ * <p>Subclasses must implement this method. The method should only be called by the
+ * transition system; it is not intended to be called from external classes.</p>
+ *
* @param transitionValues The holder for any values that the Transition
* wishes to store. Values are stored in the <code>values</code> field
* of this TransitionValues object and are keyed from
@@ -544,29 +626,51 @@ public abstract class Transition implements Cloneable {
* <code>transitionValues.values.put("appname:transitionname:rotation",
* view.getRotation())</code>. The target view will already be stored in
* the transitionValues structure when this method is called.
+ *
+ * @see #captureStartValues(TransitionValues)
+ * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues)
*/
- protected abstract void captureValues(TransitionValues transitionValues, boolean start);
+ public abstract void captureEndValues(TransitionValues transitionValues);
/**
- * Sets the ids of target views that this Transition is interested in
+ * Adds the id of a target view that this Transition is interested in
* animating. By default, there are no targetIds, and a Transition will
* listen for changes on every view in the hierarchy below the sceneRoot
- * of the Scene being transitioned into. Setting targetIDs constrains
+ * of the Scene being transitioned into. Setting targetIds constrains
* the Transition to only listen for, and act on, views with these IDs.
* Views with different IDs, or no IDs whatsoever, will be ignored.
*
+ * <p>Note that using ids to specify targets implies that ids should be unique
+ * within the view hierarchy underneat the scene root.</p>
+ *
* @see View#getId()
- * @param targetIds A list of IDs which specify the set of Views on which
- * the Transition will act.
- * @return Transition The Transition on which the targetIds have been set.
+ * @param targetId The id of a target view, must be a positive number.
+ * @return The Transition to which the targetId is added.
+ * Returning the same object makes it easier to chain calls during
+ * construction, such as
+ * <code>transitionSet.addTransitions(new Fade()).addTargetId(someId);</code>
+ */
+ public Transition addTargetId(int targetId) {
+ if (targetId > 0) {
+ mTargetIds.add(targetId);
+ }
+ return this;
+ }
+
+ /**
+ * Removes the given targetId from the list of ids that this Transition
+ * is interested in animating.
+ *
+ * @param targetId The id of a target view, must be a positive number.
+ * @return The Transition from which the targetId is removed.
* Returning the same object makes it easier to chain calls during
* construction, such as
- * <code>transitionGroup.addTransitions(new Fade()).setTargetIds(someId);</code>
+ * <code>transitionSet.addTransitions(new Fade()).removeTargetId(someId);</code>
*/
- public Transition setTargetIds(int... targetIds) {
- int numTargets = targetIds.length;
- mTargetIds = new int[numTargets];
- System.arraycopy(targetIds, 0, mTargetIds, 0, numTargets);
+ public Transition removeTargetId(int targetId) {
+ if (targetId > 0) {
+ mTargetIds.remove(targetId);
+ }
return this;
}
@@ -578,28 +682,43 @@ public abstract class Transition implements Cloneable {
* the Transition to only listen for, and act on, these views.
* All other views will be ignored.
*
- * <p>The target list is like the {@link #setTargetIds(int...) targetId}
+ * <p>The target list is like the {@link #addTargetId(int) targetId}
* list except this list specifies the actual View instances, not the ids
* of the views. This is an important distinction when scene changes involve
* view hierarchies which have been inflated separately; different views may
* share the same id but not actually be the same instance. If the transition
- * should treat those views as the same, then seTargetIds() should be used
- * instead of setTargets(). If, on the other hand, scene changes involve
+ * should treat those views as the same, then {@link #addTargetId(int)} should be used
+ * instead of {@link #addTarget(View)}. If, on the other hand, scene changes involve
* changes all within the same view hierarchy, among views which do not
- * necessary have ids set on them, then the target list may be more
+ * necessarily have ids set on them, then the target list of views may be more
* convenient.</p>
*
- * @see #setTargetIds(int...)
- * @param targets A list of Views on which the Transition will act.
- * @return Transition The Transition on which the targets have been set.
+ * @see #addTargetId(int)
+ * @param target A View on which the Transition will act, must be non-null.
+ * @return The Transition to which the target is added.
+ * Returning the same object makes it easier to chain calls during
+ * construction, such as
+ * <code>transitionSet.addTransitions(new Fade()).addTarget(someView);</code>
+ */
+ public Transition addTarget(View target) {
+ mTargets.add(target);
+ return this;
+ }
+
+ /**
+ * Removes the given target from the list of targets that this Transition
+ * is interested in animating.
+ *
+ * @param target The target view, must be non-null.
+ * @return Transition The Transition from which the target is removed.
* Returning the same object makes it easier to chain calls during
* construction, such as
- * <code>transitionGroup.addTransitions(new Fade()).setTargets(someView);</code>
+ * <code>transitionSet.addTransitions(new Fade()).removeTarget(someView);</code>
*/
- public Transition setTargets(View... targets) {
- int numTargets = targets.length;
- mTargets = new View[numTargets];
- System.arraycopy(targets, 0, mTargets, 0, numTargets);
+ public Transition removeTarget(View target) {
+ if (target != null) {
+ mTargets.remove(target);
+ }
return this;
}
@@ -612,7 +731,7 @@ public abstract class Transition implements Cloneable {
*
* @return the list of target IDs
*/
- public int[] getTargetIds() {
+ public List<Integer> getTargetIds() {
return mTargetIds;
}
@@ -625,7 +744,7 @@ public abstract class Transition implements Cloneable {
*
* @return the list of target views
*/
- public View[] getTargets() {
+ public List<View> getTargets() {
return mTargets;
}
@@ -646,16 +765,19 @@ public abstract class Transition implements Cloneable {
mEndValues.idValues.clear();
mEndValues.itemIdValues.clear();
}
- if (mTargetIds != null && mTargetIds.length > 0 ||
- mTargets != null && mTargets.length > 0) {
- if (mTargetIds != null) {
- for (int i = 0; i < mTargetIds.length; ++i) {
- int id = mTargetIds[i];
+ if (mTargetIds.size() > 0 || mTargets.size() > 0) {
+ if (mTargetIds.size() > 0) {
+ for (int i = 0; i < mTargetIds.size(); ++i) {
+ int id = mTargetIds.get(i);
View view = sceneRoot.findViewById(id);
if (view != null) {
TransitionValues values = new TransitionValues();
values.view = view;
- captureValues(values, start);
+ if (start) {
+ captureStartValues(values);
+ } else {
+ captureEndValues(values);
+ }
if (start) {
mStartValues.viewValues.put(view, values);
if (id >= 0) {
@@ -670,13 +792,17 @@ public abstract class Transition implements Cloneable {
}
}
}
- if (mTargets != null) {
- for (int i = 0; i < mTargets.length; ++i) {
- View view = mTargets[i];
+ if (mTargets.size() > 0) {
+ for (int i = 0; i < mTargets.size(); ++i) {
+ View view = mTargets.get(i);
if (view != null) {
TransitionValues values = new TransitionValues();
values.view = view;
- captureValues(values, start);
+ if (start) {
+ captureStartValues(values);
+ } else {
+ captureEndValues(values);
+ }
if (start) {
mStartValues.viewValues.put(view, values);
} else {
@@ -723,7 +849,7 @@ public abstract class Transition implements Cloneable {
}
TransitionValues values = new TransitionValues();
values.view = view;
- captureValues(values, start);
+ captureStartValues(values);
if (start) {
if (!isListViewItem) {
mStartValues.viewValues.put(view, values);
@@ -757,7 +883,7 @@ public abstract class Transition implements Cloneable {
* necessary, for example, to query the before/after state of related views
* for a given transition.
*/
- protected TransitionValues getTransitionValues(View view, boolean start) {
+ public TransitionValues getTransitionValues(View view, boolean start) {
if (mParent != null) {
return mParent.getTransitionValues(view, start);
}
@@ -834,7 +960,7 @@ public abstract class Transition implements Cloneable {
/**
* Called by TransitionManager to play the transition. This calls
- * play() to set things up and create all of the animations and then
+ * createAnimators() to set things up and create all of the animations and then
* runAnimations() to actually start the animations.
*/
void playTransition(ViewGroup sceneRoot) {
@@ -889,11 +1015,8 @@ public abstract class Transition implements Cloneable {
}
}
- // setup() must be called on entire transition hierarchy and set of views
- // before calling play() on anything; every transition needs a chance to set up
- // target views appropriately before transitions begin running
- play(sceneRoot, mStartValues, mEndValues);
- runAnimations();
+ createAnimators(sceneRoot, mStartValues, mEndValues);
+ runAnimators();
}
/**
@@ -933,7 +1056,7 @@ public abstract class Transition implements Cloneable {
/**
* This method is called automatically by the transition and
- * TransitionGroup classes prior to a Transition subclass starting;
+ * TransitionSet classes prior to a Transition subclass starting;
* subclasses should not need to call it directly.
*
* @hide
@@ -954,9 +1077,9 @@ public abstract class Transition implements Cloneable {
/**
* This method is called automatically by the Transition and
- * TransitionGroup classes when a transition finishes, either because
+ * TransitionSet classes when a transition finishes, either because
* a transition did nothing (returned a null Animator from
- * {@link Transition#play(ViewGroup, TransitionValues,
+ * {@link Transition#createAnimator(ViewGroup, TransitionValues,
* TransitionValues)}) or because the transition returned a valid
* Animator and end() was called in the onAnimationEnd()
* callback of the AnimatorListener.
@@ -993,11 +1116,10 @@ public abstract class Transition implements Cloneable {
/**
* This method cancels a transition that is currently running.
- * Implementation TBD.
+ *
+ * @hide
*/
protected void cancel() {
- // TODO: how does this work with instances?
- // TODO: this doesn't actually do *anything* yet
int numAnimators = mCurrentAnimators.size();
for (int i = numAnimators - 1; i >= 0; i--) {
Animator animator = mCurrentAnimators.get(i);
@@ -1019,12 +1141,14 @@ public abstract class Transition implements Cloneable {
*
* @param listener the listener to be added to the current set of listeners
* for this animation.
+ * @return This transition object.
*/
- public void addListener(TransitionListener listener) {
+ public Transition addListener(TransitionListener listener) {
if (mListeners == null) {
mListeners = new ArrayList<TransitionListener>();
}
mListeners.add(listener);
+ return this;
}
/**
@@ -1032,29 +1156,22 @@ public abstract class Transition implements Cloneable {
*
* @param listener the listener to be removed from the current set of
* listeners for this transition.
+ * @return This transition object.
*/
- public void removeListener(TransitionListener listener) {
+ public Transition removeListener(TransitionListener listener) {
if (mListeners == null) {
- return;
+ return this;
}
mListeners.remove(listener);
if (mListeners.size() == 0) {
mListeners = null;
}
+ return this;
}
- /**
- * Gets the set of {@link TransitionListener} objects that are currently
- * listening for events on this <code>Transition</code> object.
- *
- * @return ArrayList<TransitionListener> The set of listeners.
- */
- public ArrayList<TransitionListener> getListeners() {
- return mListeners;
- }
-
- void setSceneRoot(ViewGroup sceneRoot) {
+ Transition setSceneRoot(ViewGroup sceneRoot) {
mSceneRoot = sceneRoot;
+ return this;
}
@Override
@@ -1076,9 +1193,9 @@ public abstract class Transition implements Cloneable {
/**
* Returns the name of this Transition. This name is used internally to distinguish
* between different transitions to determine when interrupting transitions overlap.
- * For example, a Move running on the same target view as another Move should determine
- * whether the old transition is animating to different end values and should be
- * canceled in favor of the new transition.
+ * For example, a ChangeBounds running on the same target view as another ChangeBounds
+ * should determine whether the old transition is animating to different end values
+ * and should be canceled in favor of the new transition.
*
* <p>By default, a Transition's name is simply the value of {@link Class#getName()},
* but subclasses are free to override and return something different.</p>
@@ -1101,22 +1218,22 @@ public abstract class Transition implements Cloneable {
if (mInterpolator != null) {
result += "interp(" + mInterpolator + ") ";
}
- if (mTargetIds != null || mTargets != null) {
+ if (mTargetIds.size() > 0 || mTargets.size() > 0) {
result += "tgts(";
- if (mTargetIds != null) {
- for (int i = 0; i < mTargetIds.length; ++i) {
+ if (mTargetIds.size() > 0) {
+ for (int i = 0; i < mTargetIds.size(); ++i) {
if (i > 0) {
result += ", ";
}
- result += mTargetIds[i];
+ result += mTargetIds.get(i);
}
}
- if (mTargets != null) {
- for (int i = 0; i < mTargets.length; ++i) {
+ if (mTargets.size() > 0) {
+ for (int i = 0; i < mTargets.size(); ++i) {
if (i > 0) {
result += ", ";
}
- result += mTargets[i];
+ result += mTargets.get(i);
}
}
result += ")";
@@ -1149,11 +1266,11 @@ public abstract class Transition implements Cloneable {
/**
* Notification about the cancellation of the transition.
- * Note that cancel() may be called by a parent {@link TransitionGroup} on
+ * Note that cancel may be called by a parent {@link TransitionSet} on
* a child transition which has not yet started. This allows the child
* transition to restore state on target objects which was set at
- * {@link #play(android.view.ViewGroup, TransitionValues, TransitionValues)
- * play()} time.
+ * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)
+ * createAnimator()} time.
*
* @param transition The transition which was canceled.
*/
@@ -1161,11 +1278,11 @@ public abstract class Transition implements Cloneable {
/**
* Notification when a transition is paused.
- * Note that play() may be called by a parent {@link TransitionGroup} on
+ * Note that createAnimator() may be called by a parent {@link TransitionSet} on
* a child transition which has not yet started. This allows the child
* transition to restore state on target objects which was set at
- * {@link #play(android.view.ViewGroup, TransitionValues, TransitionValues)
- * play()} time.
+ * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)
+ * createAnimator()} time.
*
* @param transition The transition which was paused.
*/
@@ -1173,7 +1290,7 @@ public abstract class Transition implements Cloneable {
/**
* Notification when a transition is resumed.
- * Note that resume() may be called by a parent {@link TransitionGroup} on
+ * Note that resume() may be called by a parent {@link TransitionSet} on
* a child transition which has not yet started. This allows the child
* transition to restore state which may have changed in an earlier call
* to {@link #onTransitionPause(Transition)}.
diff --git a/core/java/android/view/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
index be658af..ebedeeb 100644
--- a/core/java/android/view/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.view.transition;
+package android.transition;
import android.content.Context;
import android.content.res.Resources;
@@ -35,6 +35,11 @@ import java.util.ArrayList;
/**
* This class inflates scenes and transitions from resource files.
+ *
+ * Information on XML resource descriptions for transitions can be found for
+ * {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet},
+ * {@link android.R.styleable#TransitionTarget}, {@link android.R.styleable#Fade},
+ * and {@link android.R.styleable#TransitionManager}.
*/
public class TransitionInflater {
@@ -121,46 +126,12 @@ public class TransitionInflater {
}
}
- /**
- * Loads a {@link Scene} object from a resource
- *
- * @param resource The resource id of the scene to load
- * @return The loaded Scene object
- * @throws android.content.res.Resources.NotFoundException when the scene
- * cannot be loaded
- */
- public Scene inflateScene(int resource, ViewGroup parent) {
- Scene scene = mScenes.get(resource);
- if (scene != null) {
- return scene;
- }
- XmlResourceParser parser = mContext.getResources().getXml(resource);
- try {
- scene = createSceneFromXml(parser, Xml.asAttributeSet(parser), parent);
- mScenes.put(resource, scene);
- return scene;
- } catch (XmlPullParserException e) {
- InflateException ex = new InflateException(e.getMessage());
- ex.initCause(e);
- throw ex;
- } catch (IOException e) {
- InflateException ex = new InflateException(
- parser.getPositionDescription()
- + ": " + e.getMessage());
- ex.initCause(e);
- throw ex;
- } finally {
- parser.close();
- }
- }
-
-
//
// Transition loading
//
private Transition createTransitionFromXml(XmlPullParser parser,
- AttributeSet attrs, TransitionGroup transitionGroup)
+ AttributeSet attrs, TransitionSet transitionSet)
throws XmlPullParserException, IOException {
Transition transition = null;
@@ -180,10 +151,14 @@ public class TransitionInflater {
String name = parser.getName();
if ("fade".equals(name)) {
- transition = new Fade();
+ TypedArray a = mContext.obtainStyledAttributes(attrs,
+ com.android.internal.R.styleable.Fade);
+ int fadingMode = a.getInt(com.android.internal.R.styleable.Fade_fadingMode,
+ Fade.IN | Fade.OUT);
+ transition = new Fade(fadingMode);
newTransition = true;
- } else if ("move".equals(name)) {
- transition = new Move();
+ } else if ("changeBounds".equals(name)) {
+ transition = new ChangeBounds();
newTransition = true;
} else if ("slide".equals(name)) {
transition = new Slide();
@@ -194,24 +169,31 @@ public class TransitionInflater {
} else if ("recolor".equals(name)) {
transition = new Recolor();
newTransition = true;
- } else if ("transitionGroup".equals(name)) {
- transition = new TransitionGroup();
- createTransitionFromXml(parser, attrs, ((TransitionGroup) transition));
+ } else if ("set".equals(name)) {
+ transition = new TransitionSet();
+ TypedArray a = mContext.obtainStyledAttributes(attrs,
+ com.android.internal.R.styleable.TransitionSet);
+ int ordering = a.getInt(
+ com.android.internal.R.styleable.TransitionSet_transitionOrdering,
+ TransitionSet.ORDERING_TOGETHER);
+ ((TransitionSet) transition).setOrdering(ordering);
+ createTransitionFromXml(parser, attrs, ((TransitionSet) transition));
+ a.recycle();
newTransition = true;
} else if ("targets".equals(name)) {
if (parser.getDepth() - 1 > depth && transition != null) {
// We're inside the child tag - add targets to the child
- getTargetIDs(parser, attrs, transition);
- } else if (parser.getDepth() - 1 == depth && transitionGroup != null) {
- // add targets to the group
- getTargetIDs(parser, attrs, transitionGroup);
+ getTargetIds(parser, attrs, transition);
+ } else if (parser.getDepth() - 1 == depth && transitionSet != null) {
+ // add targets to the set
+ getTargetIds(parser, attrs, transitionSet);
}
}
if (transition != null || "targets".equals(name)) {
if (newTransition) {
loadTransition(transition, attrs);
- if (transitionGroup != null) {
- transitionGroup.addTransitions(transition);
+ if (transitionSet != null) {
+ transitionSet.addTransition(transition);
}
}
} else {
@@ -222,7 +204,7 @@ public class TransitionInflater {
return transition;
}
- private void getTargetIDs(XmlPullParser parser,
+ private void getTargetIds(XmlPullParser parser,
AttributeSet attrs, Transition transition) throws XmlPullParserException, IOException {
// Make sure we are on a start tag.
@@ -240,8 +222,9 @@ public class TransitionInflater {
String name = parser.getName();
if (name.equals("target")) {
TypedArray a = mContext.obtainStyledAttributes(attrs,
- com.android.internal.R.styleable.Transition);
- int id = a.getResourceId(com.android.internal.R.styleable.Transition_targetID, -1);
+ com.android.internal.R.styleable.TransitionTarget);
+ int id = a.getResourceId(
+ com.android.internal.R.styleable.TransitionTarget_targetId, -1);
if (id >= 0) {
targetIds.add(id);
}
@@ -251,11 +234,9 @@ public class TransitionInflater {
}
int numTargets = targetIds.size();
if (numTargets > 0) {
- int[] targetsArray = new int[numTargets];
- for (int i = 0; i < targetIds.size(); ++i) {
- targetsArray[i] = targetIds.get(i);
+ for (int i = 0; i < numTargets; ++i) {
+ transition.addTargetId(targetIds.get(i));
}
- transition.setTargetIds(targetsArray);
}
}
@@ -268,9 +249,9 @@ public class TransitionInflater {
if (duration >= 0) {
transition.setDuration(duration);
}
- long startOffset = a.getInt(com.android.internal.R.styleable.Transition_startOffset, -1);
- if (startOffset > 0) {
- transition.setStartDelay(startOffset);
+ long startDelay = a.getInt(com.android.internal.R.styleable.Transition_startDelay, -1);
+ if (startDelay > 0) {
+ transition.setStartDelay(startDelay);
}
final int resID =
a.getResourceId(com.android.internal.R.styleable.Animator_interpolator, 0);
@@ -313,20 +294,19 @@ public class TransitionInflater {
}
private void loadTransition(AttributeSet attrs, ViewGroup sceneRoot,
- TransitionManager transitionManager)
- throws Resources.NotFoundException {
+ TransitionManager transitionManager) throws Resources.NotFoundException {
TypedArray a = mContext.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.TransitionManager);
- int transitionId = attrs.getAttributeResourceValue(
+ int transitionId = a.getResourceId(
com.android.internal.R.styleable.TransitionManager_transition, -1);
Scene fromScene = null, toScene = null;
- int fromId = attrs.getAttributeResourceValue(
+ int fromId = a.getResourceId(
com.android.internal.R.styleable.TransitionManager_fromScene, -1);
- if (fromId >= 0) fromScene = inflateScene(fromId, sceneRoot);
- int toId = attrs.getAttributeResourceValue(
+ if (fromId >= 0) fromScene = Scene.getSceneForLayout(sceneRoot, fromId, mContext);
+ int toId = a.getResourceId(
com.android.internal.R.styleable.TransitionManager_toScene, -1);
- if (toId >= 0) toScene = inflateScene(toId, sceneRoot);
+ if (toId >= 0) toScene = Scene.getSceneForLayout(sceneRoot, toId, mContext);
if (transitionId >= 0) {
Transition transition = inflateTransition(transitionId);
if (transition != null) {
@@ -344,50 +324,4 @@ public class TransitionInflater {
}
a.recycle();
}
-
- //
- // Scene loading
- //
-
- private Scene createSceneFromXml(XmlPullParser parser, AttributeSet attrs, ViewGroup parent)
- throws XmlPullParserException, IOException {
- Scene scene = null;
-
- // Make sure we are on a start tag.
- int type;
- int depth = parser.getDepth();
-
- while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
- && type != XmlPullParser.END_DOCUMENT) {
-
- if (type != XmlPullParser.START_TAG) {
- continue;
- }
-
- String name = parser.getName();
- if (name.equals("scene")) {
- scene = loadScene(attrs, parent);
- } else {
- throw new RuntimeException("Unknown scene name: " + parser.getName());
- }
- }
-
- return scene;
- }
-
- private Scene loadScene(AttributeSet attrs, ViewGroup parent)
- throws Resources.NotFoundException {
-
- Scene scene;
- TypedArray a = mContext.obtainStyledAttributes(attrs,
- com.android.internal.R.styleable.Scene);
- int layoutId = a.getResourceId(com.android.internal.R.styleable.Scene_layout, -1);
- if (layoutId >= 0) {
- scene = new Scene(parent, layoutId, mContext);
- } else {
- scene = new Scene(parent);
- }
- a.recycle();
- return scene;
- }
}
diff --git a/core/java/android/view/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index bde891d..9904413 100644
--- a/core/java/android/view/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-package android.view.transition;
+package android.transition;
+import android.content.Context;
import android.util.ArrayMap;
import android.util.Log;
-import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
@@ -34,14 +34,36 @@ import java.util.ArrayList;
* situations. Specifying other transitions for particular scene changes is
* only necessary if the application wants different transition behavior
* in these situations.
+ *
+ * <p>TransitionManagers can be declared in XML resource files inside the
+ * <code>res/transition</code> directory. TransitionManager resources consist of
+ * the <code>transitionManager</code>tag name, containing one or more
+ * <code>transition</code> tags, each of which describe the relationship of
+ * that transition to the from/to scene information in that tag.
+ * For example, here is a resource file that declares several scene
+ * transitions:</p>
+ *
+ * {@sample development/samples/ApiDemos/res/transition/transitions_mgr.xml TransitionManager}
+ *
+ * <p>For each of the <code>fromScene</code> and <code>toScene</code> attributes,
+ * there is a reference to a standard XML layout file. This is equivalent to
+ * creating a scene from a layout in code by calling
+ * {@link Scene#getSceneForLayout(ViewGroup, int, Context)}. For the
+ * <code>transition</code> attribute, there is a reference to a resource
+ * file in the <code>res/transition</code> directory which describes that
+ * transition.</p>
+ *
+ * Information on XML resource descriptions for transitions can be found for
+ * {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet},
+ * {@link android.R.styleable#TransitionTarget}, {@link android.R.styleable#Fade},
+ * and {@link android.R.styleable#TransitionManager}.
*/
public class TransitionManager {
// TODO: how to handle enter/exit?
private static String LOG_TAG = "TransitionManager";
- private static final Transition sDefaultTransition = new AutoTransition();
- private Transition mDefaultTransition = new AutoTransition();
+ private static Transition sDefaultTransition = new AutoTransition();
ArrayMap<Scene, Transition> mSceneTransitions = new ArrayMap<Scene, Transition>();
ArrayMap<Scene, ArrayMap<Scene, Transition>> mScenePairTransitions =
@@ -59,7 +81,7 @@ public class TransitionManager {
* @param transition The default transition to be used for scene changes.
*/
public void setDefaultTransition(Transition transition) {
- mDefaultTransition = transition;
+ sDefaultTransition = transition;
}
/**
@@ -69,8 +91,8 @@ public class TransitionManager {
* @return The current default transition.
* @see #setDefaultTransition(Transition)
*/
- public Transition getDefaultTransition() {
- return mDefaultTransition;
+ public static Transition getDefaultTransition() {
+ return sDefaultTransition;
}
/**
@@ -80,7 +102,7 @@ public class TransitionManager {
* transition to run.
* @param transition The transition that will play when the given scene is
* entered. A value of null will result in the default behavior of
- * using {@link AutoTransition}.
+ * using the {@link #getDefaultTransition() default transition} instead.
*/
public void setTransition(Scene scene, Transition transition) {
mSceneTransitions.put(scene, transition);
@@ -96,7 +118,7 @@ public class TransitionManager {
* be run
* @param transition The transition that will play when the given scene is
* entered. A value of null will result in the default behavior of
- * using {@link AutoTransition}.
+ * using the {@link #getDefaultTransition() default transition} instead.
*/
public void setTransition(Scene fromScene, Scene toScene, Transition transition) {
ArrayMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(toScene);
@@ -114,15 +136,15 @@ public class TransitionManager {
*
* @param scene The scene being entered
* @return The Transition to be used for the given scene change. If no
- * Transition was specified for this scene change, {@link AutoTransition}
- * will be used instead.
+ * Transition was specified for this scene change, the {@link #getDefaultTransition()
+ * default transition} will be used instead.
*/
private Transition getTransition(Scene scene) {
Transition transition = null;
ViewGroup sceneRoot = scene.getSceneRoot();
if (sceneRoot != null) {
// TODO: cached in Scene instead? long-term, cache in View itself
- Scene currScene = sceneRoot.getCurrentScene();
+ Scene currScene = Scene.getCurrentScene(sceneRoot);
if (currScene != null) {
ArrayMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(scene);
if (sceneTransitionMap != null) {
@@ -134,7 +156,7 @@ public class TransitionManager {
}
}
transition = mSceneTransitions.get(scene);
- return (transition != null) ? transition : new AutoTransition();
+ return (transition != null) ? transition : sDefaultTransition;
}
/**
@@ -234,7 +256,7 @@ public class TransitionManager {
}
// Notify previous scene that it is being exited
- Scene previousScene = sceneRoot.getCurrentScene();
+ Scene previousScene = Scene.getCurrentScene(sceneRoot);
if (previousScene != null) {
previousScene.exit();
}
@@ -256,7 +278,7 @@ public class TransitionManager {
}
/**
- * Static utility method to simply change to the given scene using
+ * Convenience method to simply change to the given scene using
* the default transition for TransitionManager.
*
* @param scene The Scene to change to
@@ -266,15 +288,14 @@ public class TransitionManager {
}
/**
- * Static utility method to simply change to the given scene using
+ * Convenience method to simply change to the given scene using
* the given transition.
*
* <p>Passing in <code>null</code> for the transition parameter will
* result in the scene changing without any transition running, and is
* equivalent to calling {@link Scene#exit()} on the scene root's
- * {@link ViewGroup#getCurrentScene() current scene}, followed by
- * {@link Scene#enter()} on the scene specified by the <code>scene</code>
- * parameter.</p>
+ * current scene, followed by {@link Scene#enter()} on the scene
+ * specified by the <code>scene</code> parameter.</p>
*
* @param scene The Scene to change to
* @param transition The transition to use for this scene change. A
@@ -285,55 +306,20 @@ public class TransitionManager {
}
/**
- * Static utility method to simply change to a scene defined by the
- * code in the given runnable, which will be executed after
- * the current values have been captured for the transition.
- * This is equivalent to creating a Scene and calling {@link
- * Scene#setEnterAction(Runnable)} with the runnable, then calling
- * {@link #go(Scene, Transition)}. The transition used will be the
- * default provided by TransitionManager.
- *
- * @param sceneRoot The root of the View hierarchy used when this scene
- * runs a transition automatically.
- * @param action The runnable whose {@link Runnable#run() run()} method will
- * be called.
- */
- public static void go(ViewGroup sceneRoot, Runnable action) {
- Scene scene = new Scene(sceneRoot);
- scene.setEnterAction(action);
- changeScene(scene, sDefaultTransition);
- }
-
- /**
- * Static utility method to simply change to a scene defined by the
- * code in the given runnable, which will be executed after
- * the current values have been captured for the transition.
- * This is equivalent to creating a Scene and calling {@link
- * Scene#setEnterAction(Runnable)} with the runnable, then calling
- * {@link #go(Scene, Transition)}. The given transition will be
- * used to animate the changes.
- *
- * <p>Passing in <code>null</code> for the transition parameter will
- * result in the scene changing without any transition running, and is
- * equivalent to calling {@link Scene#exit()} on the scene root's
- * {@link ViewGroup#getCurrentScene() current scene}, followed by
- * {@link Scene#enter()} on a new scene specified by the
- * <code>action</code> parameter.</p>
+ * Convenience method to animate, using the default transition,
+ * to a new scene defined by all changes within the given scene root between
+ * calling this method and the next rendering frame.
+ * Equivalent to calling {@link #beginDelayedTransition(ViewGroup, Transition)}
+ * with a value of <code>null</code> for the <code>transition</code> parameter.
*
* @param sceneRoot The root of the View hierarchy to run the transition on.
- * @param action The runnable whose {@link Runnable#run() run()} method will
- * be called.
- * @param transition The transition to use for this change. A
- * value of null causes the change to happen with no transition.
*/
- public static void go(ViewGroup sceneRoot, Runnable action, Transition transition) {
- Scene scene = new Scene(sceneRoot);
- scene.setEnterAction(action);
- changeScene(scene, transition);
+ public static void beginDelayedTransition(final ViewGroup sceneRoot) {
+ beginDelayedTransition(sceneRoot, null);
}
/**
- * Static utility method to animate to a new scene defined by all changes within
+ * Convenience method to animate to a new scene defined by all changes within
* the given scene root between calling this method and the next rendering frame.
* Calling this method causes TransitionManager to capture current values in the
* scene root and then post a request to run a transition on the next frame.
@@ -367,7 +353,7 @@ public class TransitionManager {
}
final Transition finalTransition = transition.clone();
sceneChangeSetup(sceneRoot, transition);
- sceneRoot.setCurrentScene(null);
+ Scene.setCurrentScene(sceneRoot, null);
sceneChangeRunTransition(sceneRoot, finalTransition);
}
}
diff --git a/core/java/android/view/transition/TransitionGroup.java b/core/java/android/transition/TransitionSet.java
index b3bacde..1972c2a 100644
--- a/core/java/android/view/transition/TransitionGroup.java
+++ b/core/java/android/transition/TransitionSet.java
@@ -14,22 +14,24 @@
* limitations under the License.
*/
-package android.view.transition;
+package android.transition;
+import android.animation.TimeInterpolator;
import android.util.AndroidRuntimeException;
+import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
/**
- * A TransitionGroup is a parent of child transitions (including other
- * TransitionGroups). Using TransitionGroups enables more complex
- * choreography of transitions, where some groups play {@link #TOGETHER} and
- * others play {@link #SEQUENTIALLY}. For example, {@link AutoTransition}
- * uses a TransitionGroup to sequentially play a Fade(Fade.OUT), followed by
- * a {@link Move}, followed by a Fade(Fade.OUT) transition.
+ * A TransitionSet is a parent of child transitions (including other
+ * TransitionSets). Using TransitionSets enables more complex
+ * choreography of transitions, where some sets play {@link #ORDERING_TOGETHER} and
+ * others play {@link #ORDERING_SEQUENTIAL}. For example, {@link AutoTransition}
+ * uses a TransitionSet to sequentially play a Fade(Fade.OUT), followed by
+ * a {@link ChangeBounds}, followed by a Fade(Fade.OUT) transition.
*/
-public class TransitionGroup extends Transition {
+public class TransitionSet extends Transition {
ArrayList<Transition> mTransitions = new ArrayList<Transition>();
private boolean mPlayTogether = true;
@@ -37,88 +39,96 @@ public class TransitionGroup extends Transition {
boolean mStarted = false;
/**
- * A flag used to indicate that the child transitions of this group
+ * A flag used to indicate that the child transitions of this set
* should all start at the same time.
*/
- public static final int TOGETHER = 0;
+ public static final int ORDERING_TOGETHER = 0;
/**
- * A flag used to indicate that the child transitions of this group should
+ * A flag used to indicate that the child transitions of this set should
* play in sequence; when one child transition ends, the next child
* transition begins. Note that a transition does not end until all
* instances of it (which are playing on all applicable targets of the
* transition) end.
*/
- public static final int SEQUENTIALLY = 1;
+ public static final int ORDERING_SEQUENTIAL = 1;
/**
- * Constructs an empty transition group. Add child transitions to the
- * group by calling to {@link #addTransitions(Transition...)} )}. By default,
- * child transitions will play {@link #TOGETHER}.
+ * Constructs an empty transition set. Add child transitions to the
+ * set by calling {@link #addTransition(Transition)} )}. By default,
+ * child transitions will play {@link #ORDERING_TOGETHER together}.
*/
- public TransitionGroup() {
+ public TransitionSet() {
}
/**
- * Constructs an empty transition group with the specified ordering.
+ * Sets the play order of this set's child transitions.
*
- * @param ordering {@link #TOGETHER} to start this group's child
- * transitions together, {@link #SEQUENTIALLY} to play the child
- * transitions in sequence.
- * @see #setOrdering(int)
- */
- public TransitionGroup(int ordering) {
- setOrdering(ordering);
- }
-
- /**
- * Sets the play order of this group's child transitions.
- *
- * @param ordering {@link #TOGETHER} to start this group's child
- * transitions together, {@link #SEQUENTIALLY} to play the child
+ * @param ordering {@link #ORDERING_TOGETHER} to play this set's child
+ * transitions together, {@link #ORDERING_SEQUENTIAL} to play the child
* transitions in sequence.
+ * @return This transitionSet object.
*/
- public void setOrdering(int ordering) {
+ public TransitionSet setOrdering(int ordering) {
switch (ordering) {
- case SEQUENTIALLY:
+ case ORDERING_SEQUENTIAL:
mPlayTogether = false;
break;
- case TOGETHER:
+ case ORDERING_TOGETHER:
mPlayTogether = true;
break;
default:
- throw new AndroidRuntimeException("Invalid parameter for TransitionGroup " +
+ throw new AndroidRuntimeException("Invalid parameter for TransitionSet " +
"ordering: " + ordering);
}
+ return this;
}
/**
- * Adds child transitions to this group. The order of the child transitions
- * passed in determines the order in which they are started.
+ * Returns the ordering of this TransitionSet. By default, the value is
+ * {@link #ORDERING_TOGETHER}.
+ *
+ * @return {@link #ORDERING_TOGETHER} if child transitions will play at the same
+ * time, {@link #ORDERING_SEQUENTIAL} if they will play in sequence.
*
- * @param transitions A list of child transition to be added to this group.
+ * @see #setOrdering(int)
*/
- public void addTransitions(Transition... transitions) {
- if (transitions != null) {
- int numTransitions = transitions.length;
- for (int i = 0; i < numTransitions; ++i) {
- mTransitions.add(transitions[i]);
- transitions[i].mParent = this;
- if (mDuration >= 0) {
- transitions[i].setDuration(mDuration);
- }
+ public int getOrdering() {
+ return mPlayTogether ? ORDERING_TOGETHER : ORDERING_SEQUENTIAL;
+ }
+
+ /**
+ * Adds child transition to this set. The order in which this child transition
+ * is added relative to other child transitions that are added, in addition to
+ * the {@link #getOrdering() ordering} property, determines the
+ * order in which the transitions are started.
+ *
+ * <p>If this transitionSet has a {@link #getDuration() duration} set on it, the
+ * child transition will inherit that duration. Transitions are assumed to have
+ * a maximum of one transitionSet parent.</p>
+ *
+ * @param transition A non-null child transition to be added to this set.
+ * @return This transitionSet object.
+ */
+ public TransitionSet addTransition(Transition transition) {
+ if (transition != null) {
+ mTransitions.add(transition);
+ transition.mParent = this;
+ if (mDuration >= 0) {
+ transition.setDuration(mDuration);
}
}
+ return this;
}
/**
- * Setting a non-negative duration on a TransitionGroup causes all of the child
+ * Setting a non-negative duration on a TransitionSet causes all of the child
* transitions (current and future) to inherit this duration.
*
* @param duration The length of the animation, in milliseconds.
- * @return This transitionGroup object.
+ * @return This transitionSet object.
*/
@Override
- public Transition setDuration(long duration) {
+ public TransitionSet setDuration(long duration) {
super.setDuration(duration);
if (mDuration >= 0) {
int numTransitions = mTransitions.size();
@@ -129,23 +139,65 @@ public class TransitionGroup extends Transition {
return this;
}
+ @Override
+ public TransitionSet setStartDelay(long startDelay) {
+ return (TransitionSet) super.setStartDelay(startDelay);
+ }
+
+ @Override
+ public TransitionSet setInterpolator(TimeInterpolator interpolator) {
+ return (TransitionSet) super.setInterpolator(interpolator);
+ }
+
+ @Override
+ public TransitionSet addTarget(View target) {
+ return (TransitionSet) super.addTarget(target);
+ }
+
+ @Override
+ public TransitionSet addTargetId(int targetId) {
+ return (TransitionSet) super.addTargetId(targetId);
+ }
+
+ @Override
+ public TransitionSet addListener(TransitionListener listener) {
+ return (TransitionSet) super.addListener(listener);
+ }
+
+ @Override
+ public TransitionSet removeTargetId(int targetId) {
+ return (TransitionSet) super.removeTargetId(targetId);
+ }
+
+ @Override
+ public TransitionSet removeTarget(View target) {
+ return (TransitionSet) super.removeTarget(target);
+ }
+
+ @Override
+ public TransitionSet removeListener(TransitionListener listener) {
+ return (TransitionSet) super.removeListener(listener);
+ }
+
/**
- * Removes the specified child transition from this group.
+ * Removes the specified child transition from this set.
*
* @param transition The transition to be removed.
+ * @return This transitionSet object.
*/
- public void removeTransition(Transition transition) {
+ public TransitionSet removeTransition(Transition transition) {
mTransitions.remove(transition);
transition.mParent = null;
+ return this;
}
/**
* Sets up listeners for each of the child transitions. This is used to
- * determine when this transition group is finished (all child transitions
+ * determine when this transition set is finished (all child transitions
* must finish first).
*/
private void setupStartEndListeners() {
- TransitionGroupListener listener = new TransitionGroupListener(this);
+ TransitionSetListener listener = new TransitionSetListener(this);
for (Transition childTransition : mTransitions) {
childTransition.addListener(listener);
}
@@ -154,28 +206,28 @@ public class TransitionGroup extends Transition {
/**
* This listener is used to detect when all child transitions are done, at
- * which point this transition group is also done.
+ * which point this transition set is also done.
*/
- static class TransitionGroupListener extends TransitionListenerAdapter {
- TransitionGroup mTransitionGroup;
- TransitionGroupListener(TransitionGroup transitionGroup) {
- mTransitionGroup = transitionGroup;
+ static class TransitionSetListener extends TransitionListenerAdapter {
+ TransitionSet mTransitionSet;
+ TransitionSetListener(TransitionSet transitionSet) {
+ mTransitionSet = transitionSet;
}
@Override
public void onTransitionStart(Transition transition) {
- if (!mTransitionGroup.mStarted) {
- mTransitionGroup.start();
- mTransitionGroup.mStarted = true;
+ if (!mTransitionSet.mStarted) {
+ mTransitionSet.start();
+ mTransitionSet.mStarted = true;
}
}
@Override
public void onTransitionEnd(Transition transition) {
- --mTransitionGroup.mCurrentListeners;
- if (mTransitionGroup.mCurrentListeners == 0) {
+ --mTransitionSet.mCurrentListeners;
+ if (mTransitionSet.mCurrentListeners == 0) {
// All child trans
- mTransitionGroup.mStarted = false;
- mTransitionGroup.end();
+ mTransitionSet.mStarted = false;
+ mTransitionSet.end();
}
transition.removeListener(this);
}
@@ -185,10 +237,10 @@ public class TransitionGroup extends Transition {
* @hide
*/
@Override
- protected void play(ViewGroup sceneRoot, TransitionValuesMaps startValues,
+ protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues,
TransitionValuesMaps endValues) {
for (Transition childTransition : mTransitions) {
- childTransition.play(sceneRoot, startValues, endValues);
+ childTransition.createAnimators(sceneRoot, startValues, endValues);
}
}
@@ -196,7 +248,7 @@ public class TransitionGroup extends Transition {
* @hide
*/
@Override
- protected void runAnimations() {
+ protected void runAnimators() {
setupStartEndListeners();
if (!mPlayTogether) {
// Setup sequence with listeners
@@ -207,28 +259,38 @@ public class TransitionGroup extends Transition {
previousTransition.addListener(new TransitionListenerAdapter() {
@Override
public void onTransitionEnd(Transition transition) {
- nextTransition.runAnimations();
+ nextTransition.runAnimators();
transition.removeListener(this);
}
});
}
Transition firstTransition = mTransitions.get(0);
if (firstTransition != null) {
- firstTransition.runAnimations();
+ firstTransition.runAnimators();
}
} else {
for (Transition childTransition : mTransitions) {
- childTransition.runAnimations();
+ childTransition.runAnimators();
}
}
}
@Override
- protected void captureValues(TransitionValues transitionValues, boolean start) {
+ public void captureStartValues(TransitionValues transitionValues) {
int targetId = transitionValues.view.getId();
for (Transition childTransition : mTransitions) {
if (childTransition.isValidTarget(transitionValues.view, targetId)) {
- childTransition.captureValues(transitionValues, start);
+ childTransition.captureStartValues(transitionValues);
+ }
+ }
+ }
+
+ @Override
+ public void captureEndValues(TransitionValues transitionValues) {
+ int targetId = transitionValues.view.getId();
+ for (Transition childTransition : mTransitions) {
+ if (childTransition.isValidTarget(transitionValues.view, targetId)) {
+ childTransition.captureEndValues(transitionValues);
}
}
}
@@ -253,6 +315,7 @@ public class TransitionGroup extends Transition {
}
}
+ /** @hide */
@Override
protected void cancel() {
super.cancel();
@@ -263,12 +326,13 @@ public class TransitionGroup extends Transition {
}
@Override
- void setSceneRoot(ViewGroup sceneRoot) {
+ TransitionSet setSceneRoot(ViewGroup sceneRoot) {
super.setSceneRoot(sceneRoot);
int numTransitions = mTransitions.size();
for (int i = 0; i < numTransitions; ++i) {
mTransitions.get(i).setSceneRoot(sceneRoot);
}
+ return (TransitionSet) this;
}
@Override
@@ -281,8 +345,8 @@ public class TransitionGroup extends Transition {
}
@Override
- public TransitionGroup clone() {
- TransitionGroup clone = (TransitionGroup) super.clone();
+ public TransitionSet clone() {
+ TransitionSet clone = (TransitionSet) super.clone();
clone.mTransitions = new ArrayList<Transition>();
int numTransitions = mTransitions.size();
for (int i = 0; i < numTransitions; ++i) {
diff --git a/core/java/android/view/transition/TransitionValues.java b/core/java/android/transition/TransitionValues.java
index 6e5d3d3..8989f89 100644
--- a/core/java/android/view/transition/TransitionValues.java
+++ b/core/java/android/transition/TransitionValues.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.view.transition;
+package android.transition;
import android.util.ArrayMap;
import android.view.View;
@@ -33,11 +33,11 @@ import java.util.Map;
* "Fader" as "android:fader:alpha".
*
* <p>These values are cached during the
- * {@link Transition#captureValues(TransitionValues, boolean)}
+ * {@link Transition#captureStartValues(TransitionValues)}
* capture} phases of a scene change, once when the start values are captured
* and again when the end values are captured. These start/end values are then
* passed into the transitions via the
- * for {@link Transition#play(ViewGroup, TransitionValues, TransitionValues)}
+ * for {@link Transition#createAnimator(ViewGroup, TransitionValues, TransitionValues)}
* method.</p>
*/
public class TransitionValues {
diff --git a/core/java/android/view/transition/TransitionValuesMaps.java b/core/java/android/transition/TransitionValuesMaps.java
index 4cfce4d..131596b 100644
--- a/core/java/android/view/transition/TransitionValuesMaps.java
+++ b/core/java/android/transition/TransitionValuesMaps.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.view.transition;
+package android.transition;
import android.util.ArrayMap;
import android.util.LongSparseArray;
diff --git a/core/java/android/view/transition/Visibility.java b/core/java/android/transition/Visibility.java
index 348dcfb..75d3e7c 100644
--- a/core/java/android/view/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -14,13 +14,11 @@
* limitations under the License.
*/
-package android.view.transition;
+package android.transition;
import android.animation.Animator;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewOverlay;
-import android.view.ViewParent;
/**
* This transition tracks changes to the visibility of target views in the
@@ -30,13 +28,13 @@ import android.view.ViewParent;
* utility for subclasses such as {@link Fade}, which use this visibility
* information to determine the specific animations to run when visibility
* changes occur. Subclasses should implement one or both of the methods
- * {@link #appear(ViewGroup, TransitionValues, int, TransitionValues, int), and
- * {@link #disappear(ViewGroup, TransitionValues, int, TransitionValues, int)}.
+ * {@link #onAppear(ViewGroup, TransitionValues, int, TransitionValues, int)},
+ * {@link #onDisappear(ViewGroup, TransitionValues, int, TransitionValues, int)},
*
* <p>Note that a view's visibility change is determined by both whether the view
* itself is changing and whether its parent hierarchy's visibility is changing.
* That is, a view that appears in the end scene will only trigger a call to
- * {@link #appear(android.view.ViewGroup, TransitionValues, int, TransitionValues, int)
+ * {@link #onAppear(android.view.ViewGroup, TransitionValues, int, TransitionValues, int)
* appear()} if its parent hierarchy was stable between the start and end scenes.
* This is done to avoid causing a visibility transition on every node in a hierarchy
* when only the top-most node is the one that should be transitioned in/out.
@@ -75,11 +73,20 @@ public abstract class Visibility extends Transition {
return sTransitionProperties;
}
+ private void captureValues(TransitionValues transitionValues) {
+ int visibility = transitionValues.view.getVisibility();
+ transitionValues.values.put(PROPNAME_VISIBILITY, visibility);
+ transitionValues.values.put(PROPNAME_PARENT, transitionValues.view.getParent());
+ }
+
+ @Override
+ public void captureStartValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
+ }
+
@Override
- protected void captureValues(TransitionValues values, boolean start) {
- int visibility = values.view.getVisibility();
- values.values.put(PROPNAME_VISIBILITY, visibility);
- values.values.put(PROPNAME_PARENT, values.view.getParent());
+ public void captureEndValues(TransitionValues transitionValues) {
+ captureValues(transitionValues);
}
/**
@@ -87,7 +94,7 @@ public abstract class Visibility extends Transition {
* object. This is determined by testing the same properties in the values
* object that are used to determine whether the object is appearing or
* disappearing in the {@link
- * #play(android.view.ViewGroup, TransitionValues, TransitionValues)}
+ * Transition#createAnimator(ViewGroup, TransitionValues, TransitionValues)}
* method. This method can be called by, for example, subclasses that want
* to know whether the object is visible in the same way that Visibility
* determines it for the actual animation.
@@ -207,14 +214,14 @@ public abstract class Visibility extends Transition {
}
@Override
- protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+ public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
TransitionValues endValues) {
VisibilityInfo visInfo = getVisibilityChangeInfo(startValues, endValues);
if (visInfo.visibilityChange) {
// Only transition views that are either targets of this transition
// or whose parent hierarchies remain stable between scenes
boolean isTarget = false;
- if (mTargets != null || mTargetIds != null) {
+ if (mTargets.size() > 0 || mTargetIds.size() > 0) {
View startView = startValues != null ? startValues.view : null;
View endView = endValues != null ? endValues.view : null;
int startId = startView != null ? startView.getId() : -1;
@@ -225,10 +232,10 @@ public abstract class Visibility extends Transition {
!isHierarchyVisibilityChanging(sceneRoot,
visInfo.startParent, visInfo.endParent))) {
if (visInfo.fadeIn) {
- return appear(sceneRoot, startValues, visInfo.startVisibility,
+ return onAppear(sceneRoot, startValues, visInfo.startVisibility,
endValues, visInfo.endVisibility);
} else {
- return disappear(sceneRoot, startValues, visInfo.startVisibility,
+ return onDisappear(sceneRoot, startValues, visInfo.startVisibility,
endValues, visInfo.endVisibility
);
}
@@ -239,17 +246,20 @@ public abstract class Visibility extends Transition {
/**
* The default implementation of this method does nothing. Subclasses
- * should override if they need to set up anything prior to the
- * transition starting.
+ * should override if they need to create an Animator when targets appear.
+ * The method should only be called by the Visibility class; it is
+ * not intended to be called from external classes.
*
- * @param sceneRoot
- * @param startValues
- * @param startVisibility
- * @param endValues
- * @param endVisibility
- * @return
+ * @param sceneRoot The root of the transition hierarchy
+ * @param startValues The target values in the start scene
+ * @param startVisibility The target visibility in the start scene
+ * @param endValues The target values in the end scene
+ * @param endVisibility The target visibility in the end scene
+ * @return An Animator to be started at the appropriate time in the
+ * overall transition for this scene change. A null value means no animation
+ * should be run.
*/
- protected Animator appear(ViewGroup sceneRoot,
+ public Animator onAppear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
return null;
@@ -257,17 +267,21 @@ public abstract class Visibility extends Transition {
/**
* The default implementation of this method does nothing. Subclasses
- * should override if they need to set up anything prior to the
- * transition starting.
+ * should override if they need to create an Animator when targets disappear.
+ * The method should only be called by the Visibility class; it is
+ * not intended to be called from external classes.
+ *
*
- * @param sceneRoot
- * @param startValues
- * @param startVisibility
- * @param endValues
- * @param endVisibility
- * @return
+ * @param sceneRoot The root of the transition hierarchy
+ * @param startValues The target values in the start scene
+ * @param startVisibility The target visibility in the start scene
+ * @param endValues The target values in the end scene
+ * @param endVisibility The target visibility in the end scene
+ * @return An Animator to be started at the appropriate time in the
+ * overall transition for this scene change. A null value means no animation
+ * should be run.
*/
- protected Animator disappear(ViewGroup sceneRoot,
+ public Animator onDisappear(ViewGroup sceneRoot,
TransitionValues startValues, int startVisibility,
TransitionValues endValues, int endVisibility) {
return null;
diff --git a/core/java/android/view/transition/package.html b/core/java/android/transition/package.html
index 37dc0ec..f357d34 100644
--- a/core/java/android/view/transition/package.html
+++ b/core/java/android/transition/package.html
@@ -3,15 +3,15 @@
<p>The classes in this package enable "scenes & transitions" functionality for
view hiearchies.</p>
-<p>A <b>Scene</b> is an encapsulation of the state of a view hiearchy,
+<p>A <b>Scene</b> is an encapsulation of the state of a view hierarchy,
including the views in that hierarchy and the various values (layout-related
-and otherwise) that those views have. A scene be defined by a layout hierarchy
-directly or some code which sets up the scene dynamically as it is entered.</p>
+and otherwise) that those views have. A scene can be defined by a layout hierarchy
+directly or by code which sets up the scene dynamically as it is entered.</p>
<p>A <b>Transition</b> is a mechanism to automatically animate changes that occur
when a new scene is entered. Some transition capabilities are automatic. That
is, entering a scene may cause animations to run which fade out views that
-go away, move and resize existing views that change, and fade in views that
+go away, changeBounds and resize existing views that change, and fade in views that
become visible. There are additional transitions that can animate other
attributes, such as color changes, and which can optionally be specified
to take place during particular scene changes. Finally, developers can
@@ -19,7 +19,8 @@ define their own Transition subclasses which monitor particular property
changes and which run custom animations when those properties change values.</p>
<p><b>TransitionManager</b> is used to specify custom transitions for particular
-scene changes, and to cause scene changes with transitions to take place.</p>
+scene changes, and to cause scene changes with specific transitions to
+take place.</p>
</body>
</html>
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index 28c1058..6bbfe0f 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -323,7 +323,7 @@ public class GestureDetector {
/**
* Creates a GestureDetector with the supplied listener.
- * You may only use this constructor from a UI thread (this is the usual situation).
+ * You may only use this constructor from a {@link android.os.Looper} thread.
* @see android.os.Handler#Handler()
*
* @param context the application's context
@@ -337,14 +337,14 @@ public class GestureDetector {
}
/**
- * Creates a GestureDetector with the supplied listener.
- * You may only use this constructor from a UI thread (this is the usual situation).
+ * Creates a GestureDetector with the supplied listener that runs deferred events on the
+ * thread associated with the supplied {@link android.os.Handler}.
* @see android.os.Handler#Handler()
*
* @param context the application's context
* @param listener the listener invoked for all the callbacks, this must
* not be null.
- * @param handler the handler to use
+ * @param handler the handler to use for running deferred listener events.
*
* @throws NullPointerException if {@code listener} is null.
*/
@@ -362,14 +362,15 @@ public class GestureDetector {
}
/**
- * Creates a GestureDetector with the supplied listener.
- * You may only use this constructor from a UI thread (this is the usual situation).
+ * Creates a GestureDetector with the supplied listener that runs deferred events on the
+ * thread associated with the supplied {@link android.os.Handler}.
* @see android.os.Handler#Handler()
*
* @param context the application's context
* @param listener the listener invoked for all the callbacks, this must
* not be null.
- * @param handler the handler to use
+ * @param handler the handler to use for running deferred listener events.
+ * @param unused currently not used.
*
* @throws NullPointerException if {@code listener} is null.
*/
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 907290b..f2b3e89 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -74,7 +74,6 @@ import android.view.animation.Transformation;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
-import android.view.transition.Scene;
import android.widget.ScrollBarDrawable;
import static android.os.Build.VERSION_CODES.*;
@@ -1575,8 +1574,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
protected Object mTag;
- private Scene mCurrentScene = null;
-
// for mPrivateFlags:
/** {@hide} */
static final int PFLAG_WANTS_FOCUS = 0x00000001;
@@ -8836,9 +8833,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* Change the view's z order in the tree, so it's on top of other sibling
* views. This ordering change may affect layout, if the parent container
- * uses an order-dependent layout scheme (e.g., LinearLayout). This
+ * uses an order-dependent layout scheme (e.g., LinearLayout). Prior
+ * to {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE} this
* method should be followed by calls to {@link #requestLayout()} and
- * {@link View#invalidate()} on the parent.
+ * {@link View#invalidate()} on the view's parent to force the parent to redraw
+ * with the new child ordering.
*
* @see ViewGroup#bringChildToFront(View)
*/
@@ -12187,7 +12186,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
cleanupDraw();
mCurrentAnimation = null;
- mCurrentScene = null;
}
private void cleanupDraw() {
@@ -18100,31 +18098,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * Set the current Scene that this view is in. The current scene is set only
- * on the root view of a scene, not for every view in that hierarchy. This
- * information is used by Scene to determine whether there is a previous
- * scene which should be exited before the new scene is entered.
- *
- * @param scene The new scene being set on the view
- *
- * @hide
- */
- public void setCurrentScene(Scene scene) {
- mCurrentScene = scene;
- }
-
- /**
- * Gets the current {@link Scene} set on this view. A scene is set on a view
- * only if that view is the scene root.
- *
- * @return The current Scene set on this view. A value of null indicates that
- * no Scene is current set.
- */
- public Scene getCurrentScene() {
- return mCurrentScene;
- }
-
- /**
* Interface definition for a callback to be invoked when a hardware key event is
* dispatched to this view. The callback will be invoked before the key event is
* given to the view. This is only useful for hardware keyboards; a software input
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 03a9c37..2d75b06 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1123,6 +1123,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
removeFromArray(index);
addInArray(child, mChildrenCount);
child.mParent = this;
+ requestLayout();
+ invalidate();
}
}
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index 26596d9..656d756 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -148,9 +148,11 @@ public interface ViewParent {
/**
* Change the z order of the child so it's on top of all other children.
* This ordering change may affect layout, if this container
- * uses an order-dependent layout scheme (e.g., LinearLayout). This
+ * uses an order-dependent layout scheme (e.g., LinearLayout). Prior
+ * to {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE} this
* method should be followed by calls to {@link #requestLayout()} and
- * {@link View#invalidate()} on this parent.
+ * {@link View#invalidate()} on this parent to force the parent to redraw
+ * with the new child ordering.
*
* @param child The child to bring to the top of the z order
*/
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 354e815..0f9a2ac 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1449,7 +1449,7 @@ public final class ViewRootImpl implements ViewParent,
}
DisplayList displayList = mView.mDisplayList;
- if (displayList != null) {
+ if (displayList != null && displayList.isValid()) {
layerCanvas.drawDisplayList(displayList, null,
DisplayList.FLAG_CLIP_CHILDREN);
} else {
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index 778c8db..dff1531 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -29,12 +29,14 @@ import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.ActionProvider;
import android.view.LayoutInflater;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ActivityChooserModel.ActivityChooserModelClient;
+import android.widget.ListPopupWindow.ForwardingListener;
/**
* This class is a view for choosing an activity for handling a given {@link Intent}.
@@ -228,17 +230,37 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
mDefaultActivityButton.setOnLongClickListener(mCallbacks);
mDefaultActivityButtonImage = (ImageView) mDefaultActivityButton.findViewById(R.id.image);
- mExpandActivityOverflowButton = (FrameLayout) findViewById(R.id.expand_activities_button);
- mExpandActivityOverflowButton.setOnClickListener(mCallbacks);
- mExpandActivityOverflowButton.setAccessibilityDelegate(new AccessibilityDelegate() {
+ final FrameLayout expandButton = (FrameLayout) findViewById(R.id.expand_activities_button);
+ expandButton.setOnClickListener(mCallbacks);
+ expandButton.setAccessibilityDelegate(new AccessibilityDelegate() {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(host, info);
info.setCanOpenPopup(true);
}
});
+ expandButton.setOnTouchListener(new ForwardingListener(expandButton) {
+ @Override
+ public ListPopupWindow getPopup() {
+ return getListPopupWindow();
+ }
+
+ @Override
+ protected boolean onForwardingStarted() {
+ showPopup();
+ return true;
+ }
+
+ @Override
+ protected boolean onForwardingStopped() {
+ dismissPopup();
+ return true;
+ }
+ });
+ mExpandActivityOverflowButton = expandButton;
+
mExpandActivityOverflowButtonImage =
- (ImageView) mExpandActivityOverflowButton.findViewById(R.id.image);
+ (ImageView) expandButton.findViewById(R.id.image);
mExpandActivityOverflowButtonImage.setImageDrawable(expandActivityOverflowButtonDrawable);
mAdapter = new ActivityChooserViewAdapter();
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index f73e2c4..b9b6b08 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -462,6 +462,7 @@ public class RelativeLayout extends ViewGroup {
views = mSortedVerticalChildren;
count = views.length;
+ final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
for (int i = 0; i < count; i++) {
View child = views[i];
@@ -476,14 +477,26 @@ public class RelativeLayout extends ViewGroup {
if (isWrapContentWidth) {
if (isLayoutRtl()) {
- width = Math.max(width, myWidth - params.mLeft);
+ if (targetSdkVersion < Build.VERSION_CODES.KEY_LIME_PIE) {
+ width = Math.max(width, myWidth - params.mLeft);
+ } else {
+ width = Math.max(width, myWidth - params.mLeft - params.leftMargin);
+ }
} else {
- width = Math.max(width, params.mRight);
+ if (targetSdkVersion < Build.VERSION_CODES.KEY_LIME_PIE) {
+ width = Math.max(width, params.mRight);
+ } else {
+ width = Math.max(width, params.mRight + params.rightMargin);
+ }
}
}
if (isWrapContentHeight) {
- height = Math.max(height, params.mBottom);
+ if (targetSdkVersion < Build.VERSION_CODES.KEY_LIME_PIE) {
+ height = Math.max(height, params.mBottom);
+ } else {
+ height = Math.max(height, params.mBottom + params.bottomMargin);
+ }
}
if (child != ignore || verticalGravity) {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a2d48a8..3c9cc98 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1519,6 +1519,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* with this TextView. By default there is no associated UndoManager, so null
* is returned. One can be associated with the TextView through
* {@link #setUndoManager(android.content.UndoManager, String)}
+ *
+ * @hide
*/
public final UndoManager getUndoManager() {
return mEditor == null ? null : mEditor.mUndoManager;
@@ -1535,6 +1537,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @param tag String tag identifying this particular TextView owner in the
* UndoManager. This is used to keep the correct association with the
* {@link android.content.UndoOwner} of any operations inside of the UndoManager.
+ *
+ * @hide
*/
public final void setUndoManager(UndoManager undoManager, String tag) {
if (undoManager != null) {
diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java
index 0ddc131..f449797 100644
--- a/core/java/android/widget/VideoView.java
+++ b/core/java/android/widget/VideoView.java
@@ -29,9 +29,12 @@ import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.Metadata;
+import android.media.SubtitleController;
+import android.media.WebVttRenderer;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.Pair;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
@@ -54,7 +57,8 @@ import java.util.Vector;
* it can be used in any layout manager, and provides various display options
* such as scaling and tinting.
*/
-public class VideoView extends SurfaceView implements MediaPlayerControl {
+public class VideoView extends SurfaceView
+ implements MediaPlayerControl, SubtitleController.Anchor {
private String TAG = "VideoView";
// settable by the client
private Uri mUri;
@@ -208,7 +212,7 @@ public class VideoView extends SurfaceView implements MediaPlayerControl {
setFocusable(true);
setFocusableInTouchMode(true);
requestFocus();
- mPendingSubtitleTracks = 0;
+ mPendingSubtitleTracks = new Vector<Pair<InputStream, MediaFormat>>();
mCurrentState = STATE_IDLE;
mTargetState = STATE_IDLE;
}
@@ -256,23 +260,19 @@ public class VideoView extends SurfaceView implements MediaPlayerControl {
* specify "und" for the language.
*/
public void addSubtitleSource(InputStream is, MediaFormat format) {
- // always signal unsupported message for now
- try {
- if (is != null) {
- is.close();
- }
- } catch (IOException e) {
- }
-
if (mMediaPlayer == null) {
- ++mPendingSubtitleTracks;
+ mPendingSubtitleTracks.add(Pair.create(is, format));
} else {
- mInfoListener.onInfo(
- mMediaPlayer, MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE, 0);
+ try {
+ mMediaPlayer.addSubtitleSource(is, format);
+ } catch (IllegalStateException e) {
+ mInfoListener.onInfo(
+ mMediaPlayer, MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE, 0);
+ }
}
}
- private int mPendingSubtitleTracks;
+ private Vector<Pair<InputStream, MediaFormat>> mPendingSubtitleTracks;
public void stopPlayback() {
if (mMediaPlayer != null) {
@@ -300,6 +300,15 @@ public class VideoView extends SurfaceView implements MediaPlayerControl {
release(false);
try {
mMediaPlayer = new MediaPlayer();
+ // TODO: create SubtitleController in MediaPlayer, but we need
+ // a context for the subtitle renderers
+ SubtitleController controller = new SubtitleController(
+ getContext(),
+ mMediaPlayer.getMediaTimeProvider(),
+ mMediaPlayer);
+ controller.registerRenderer(new WebVttRenderer(getContext(), null));
+ mMediaPlayer.setSubtitleAnchor(controller, this);
+
if (mAudioSession != 0) {
mMediaPlayer.setAudioSessionId(mAudioSession);
} else {
@@ -318,9 +327,13 @@ public class VideoView extends SurfaceView implements MediaPlayerControl {
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.prepareAsync();
- for (int ix = 0; ix < mPendingSubtitleTracks; ix++) {
- mInfoListener.onInfo(
- mMediaPlayer, MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE, 0);
+ for (Pair<InputStream, MediaFormat> pending: mPendingSubtitleTracks) {
+ try {
+ mMediaPlayer.addSubtitleSource(pending.first, pending.second);
+ } catch (IllegalStateException e) {
+ mInfoListener.onInfo(
+ mMediaPlayer, MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE, 0);
+ }
}
// we don't set the target state here either, but preserve the
@@ -340,7 +353,7 @@ public class VideoView extends SurfaceView implements MediaPlayerControl {
mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
return;
} finally {
- mPendingSubtitleTracks = 0;
+ mPendingSubtitleTracks.clear();
}
}
@@ -604,7 +617,7 @@ public class VideoView extends SurfaceView implements MediaPlayerControl {
mMediaPlayer.reset();
mMediaPlayer.release();
mMediaPlayer = null;
- mPendingSubtitleTracks = 0;
+ mPendingSubtitleTracks.clear();
mCurrentState = STATE_IDLE;
if (cleartargetstate) {
mTargetState = STATE_IDLE;
@@ -874,4 +887,22 @@ public class VideoView extends SurfaceView implements MediaPlayerControl {
overlay.layout(left, top, right, bottom);
}
}
+
+ /** @hide */
+ @Override
+ public void setSubtitleView(View view) {
+ if (mSubtitleView == view) {
+ return;
+ }
+
+ if (mSubtitleView != null) {
+ removeOverlay(mSubtitleView);
+ }
+ mSubtitleView = view;
+ if (mSubtitleView != null) {
+ addOverlay(mSubtitleView);
+ }
+ }
+
+ private View mSubtitleView;
}
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
index ac9bf16..16b119a 100644
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -1583,7 +1583,7 @@ public final class ProcessStats implements Parcelable {
final int NSRVS = pkgState.mServices.size();
if (NPROCS > 0 || NSRVS > 0) {
if (!printedHeader) {
- pw.println("Per-Package Process Stats:");
+ pw.println("Per-Package Stats:");
printedHeader = true;
}
pw.print(" * "); pw.print(pkgName); pw.print(" / ");
@@ -1651,7 +1651,8 @@ public final class ProcessStats implements Parcelable {
continue;
}
if (!printedHeader) {
- pw.println("Process Stats:");
+ pw.println();
+ pw.println("Per-Process Stats:");
printedHeader = true;
}
pw.print(" * "); pw.print(procName); pw.print(" / ");
@@ -2536,7 +2537,8 @@ public final class ProcessStats implements Parcelable {
if (mActive <= 0) {
throw new IllegalStateException("Service " + this + " has mActive=" + mActive);
}
- int state = started ? memFactor : STATE_NOTHING;
+ final boolean wasStarted = mStartedState != STATE_NOTHING;
+ final int state = started ? memFactor : STATE_NOTHING;
if (mStartedState != state) {
if (mStartedState != STATE_NOTHING) {
addStateTime(SERVICE_STARTED + (mStartedState*SERVICE_COUNT),
@@ -2546,8 +2548,8 @@ public final class ProcessStats implements Parcelable {
}
mStartedState = state;
mStartedStartTime = now;
- if (mProc != null) {
- mProc = mProc.pullFixedProc(mPackage);
+ mProc = mProc.pullFixedProc(mPackage);
+ if (wasStarted != started) {
if (started) {
mProc.incStartedServices(memFactor, now);
} else {
@@ -2561,7 +2563,7 @@ public final class ProcessStats implements Parcelable {
if (mActive <= 0) {
throw new IllegalStateException("Service " + this + " has mActive=" + mActive);
}
- int state = bound ? memFactor : STATE_NOTHING;
+ final int state = bound ? memFactor : STATE_NOTHING;
if (mBoundState != state) {
if (mBoundState != STATE_NOTHING) {
addStateTime(SERVICE_BOUND + (mBoundState*SERVICE_COUNT),
@@ -2578,7 +2580,7 @@ public final class ProcessStats implements Parcelable {
if (mActive <= 0) {
throw new IllegalStateException("Service " + this + " has mActive=" + mActive);
}
- int state = executing ? memFactor : STATE_NOTHING;
+ final int state = executing ? memFactor : STATE_NOTHING;
if (mExecState != state) {
if (mExecState != STATE_NOTHING) {
addStateTime(SERVICE_EXEC + (mExecState*SERVICE_COUNT), now - mExecStartTime);
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index c092807..30ca73e 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -35,7 +35,7 @@ import java.util.Comparator;
import java.util.StringTokenizer;
public class ProcessCpuTracker {
- private static final String TAG = "ProcessStats";
+ private static final String TAG = "ProcessCpuTracker";
private static final boolean DEBUG = false;
private static final boolean localLOGV = DEBUG || false;
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 527aee4..40e0731 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -764,8 +764,6 @@ public:
static void doTextBounds(JNIEnv* env, const jchar* text, int count,
jobject bounds, const SkPaint& paint, jint bidiFlags) {
SkRect r;
- r.set(0,0,0,0);
-
SkIRect ir;
sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 51ba52a..225bf06 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -742,6 +742,30 @@ static jint android_media_AudioTrack_get_latency(JNIEnv *env, jobject thiz) {
// ----------------------------------------------------------------------------
+static jint android_media_AudioTrack_get_timestamp(JNIEnv *env, jobject thiz, jlongArray jTimestamp) {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+
+ if (lpTrack == NULL) {
+ ALOGE("Unable to retrieve AudioTrack pointer for getTimestamp()");
+ return AUDIOTRACK_ERROR;
+ }
+ AudioTimestamp timestamp;
+ status_t status = lpTrack->getTimestamp(timestamp);
+ if (status == OK) {
+ jlong* nTimestamp = (jlong *) env->GetPrimitiveArrayCritical(jTimestamp, NULL);
+ if (nTimestamp == NULL) {
+ ALOGE("Unable to get array for getTimestamp()");
+ return AUDIOTRACK_ERROR;
+ }
+ nTimestamp[0] = (jlong) timestamp.mPosition;
+ nTimestamp[1] = (jlong) ((timestamp.mTime.tv_sec * 1000000000LL) + timestamp.mTime.tv_nsec);
+ env->ReleasePrimitiveArrayCritical(jTimestamp, nTimestamp, 0);
+ }
+ return (jint) android_media_translateErrorCode(status);
+}
+
+
+// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_set_loop(JNIEnv *env, jobject thiz,
jint loopStart, jint loopEnd, jint loopCount) {
sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
@@ -869,6 +893,7 @@ static JNINativeMethod gMethods[] = {
{"native_set_position", "(I)I", (void *)android_media_AudioTrack_set_position},
{"native_get_position", "()I", (void *)android_media_AudioTrack_get_position},
{"native_get_latency", "()I", (void *)android_media_AudioTrack_get_latency},
+ {"native_get_timestamp", "([J)I", (void *)android_media_AudioTrack_get_timestamp},
{"native_set_loop", "(III)I", (void *)android_media_AudioTrack_set_loop},
{"native_reload_static", "()I", (void *)android_media_AudioTrack_reload},
{"native_get_output_sample_rate",
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9613df3..49945f0 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -247,6 +247,7 @@
<protected-broadcast android:name="android.location.GPS_ENABLED_CHANGE" />
<protected-broadcast android:name="android.location.PROVIDERS_CHANGED" />
+ <protected-broadcast android:name="android.location.MODE_CHANGED" />
<protected-broadcast android:name="android.location.GPS_FIX_CHANGE" />
<protected-broadcast android:name="android.net.proxy.PAC_REFRESH" />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index b6a4250..a47e518 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4511,24 +4511,71 @@
</declare-styleable>
<!-- ========================== -->
- <!-- State class attributes -->
+ <!-- Transition attributes -->
<!-- ========================== -->
<eat-comment />
- <declare-styleable name="Scene">
- <attr name="layout" />
- </declare-styleable>
-
+ <!-- Use specific transition subclass names as the root tag of the XML resource that
+ describes a {@link android.transition.Transition Transition},
+ such as <code>move</code>, <code>fade</code>, and <code>set</code>. -->
<declare-styleable name="Transition">
+ <!-- Amount of time (in milliseconds) that the transition should run. -->
<attr name="duration" />
- <attr name="startOffset" />
+ <!-- Delay in milliseconds before the transition starts. -->
+ <attr name="startDelay" format="integer" />
+ <!-- Interpolator to be used in the animations spawned by this transition. -->
<attr name="interpolator" />
- <attr name="targetID" format="reference" />
</declare-styleable>
+ <!-- Use <code>fade</code>as the root tag of the XML resource that
+ describes a {@link android.transition.Fade Fade} transition.
+ The attributes of the {@link android.R.styleable#Transition Transition}
+ resource are available in addition to the specific attributes of Fade
+ described here. -->
+ <declare-styleable name="Fade">
+ <attr name="fadingMode">
+ <!-- Fade will only fade appearing items in. -->
+ <enum name="fade_in" value="1" />
+ <!-- Fade will only fade disappearing items out. -->
+ <enum name="fade_out" value="2" />
+ <!-- Fade will fade appearing items in and disappearing items out. -->
+ <enum name="fade_in_out" value="3" />
+ </attr>
+ </declare-styleable>
+
+ <!-- Use <code>target</code> as the root tag of the XML resource that
+ describes a {@link android.transition.Transition#addTargetId(int)
+ targetId} of a transition. There can be one or more targets inside
+ a <code>targets</code> tag, which is itself inside an appropriate
+ {@link android.R.styleable#Transition Transition} tag.
+ -->
+ <declare-styleable name="TransitionTarget">
+ <!-- The id of a target on which this transition will animate changes. -->
+ <attr name="targetId" format="reference" />
+ </declare-styleable>
+
+ <!-- Use <code>set</code> as the root tag of the XML resource that
+ describes a {@link android.transition.TransitionSet
+ TransitionSet} transition. -->
+ <declare-styleable name="TransitionSet">
+ <attr name="transitionOrdering">
+ <!-- child transitions should be played together. -->
+ <enum name="together" value="0" />
+ <!-- child transitions should be played sequentially, in the same order
+ as the xml. -->
+ <enum name="sequential" value="1" />
+ </attr>
+ </declare-styleable>
+
+ <!-- Use <code>transitionManager</code> as the root tag of the XML resource that
+ describes a {@link android.transition.TransitionManager
+ TransitionManager}. -->
<declare-styleable name="TransitionManager">
+ <!-- The id of a transition to be used in a particular scene change. -->
<attr name="transition" format="reference" />
+ <!-- The originating scene in this scene change. -->
<attr name="fromScene" format="reference" />
+ <!-- The destination scene in this scene change. -->
<attr name="toScene" format="reference" />
</declare-styleable>
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 21bae04..15df295 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -80,4 +80,5 @@
<item type="id" name="overflow_menu_presenter" />
<item type="id" name="popup_submenu_presenter" />
<item type="id" name="action_bar_spinner" />
+ <item type="id" name="current_scene" />
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index e6702b0..6c3856e 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2059,10 +2059,13 @@
<eat-comment />
<public type="attr" name="keyset" />
- <public type="attr" name="targetID" />
+ <public type="attr" name="targetId" />
<public type="attr" name="fromScene" />
<public type="attr" name="toScene" />
<public type="attr" name="transition" />
+ <public type="attr" name="transitionOrdering" />
+ <public type="attr" name="fadingMode" />
+ <public type="attr" name="startDelay" />
<public type="attr" name="ssp" />
<public type="attr" name="sspPrefix" />
<public type="attr" name="sspPattern" />
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1035054..fcd56eb 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -54,6 +54,7 @@
<java-symbol type="id" name="characterPicker" />
<java-symbol type="id" name="clearDefaultHint" />
<java-symbol type="id" name="contentPanel" />
+ <java-symbol type="id" name="current_scene" />
<java-symbol type="id" name="customPanel" />
<java-symbol type="id" name="datePicker" />
<java-symbol type="id" name="day" />
diff --git a/data/fonts/fallback_fonts.xml b/data/fonts/fallback_fonts.xml
index 16d760c..d11a3c7 100644
--- a/data/fonts/fallback_fonts.xml
+++ b/data/fonts/fallback_fonts.xml
@@ -126,6 +126,30 @@
</family>
<family>
<fileset>
+ <file variant="elegant">NotoSansKhmer-Regular.ttf</file>
+ <file variant="elegant">NotoSansKhmer-Bold.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file variant="compact">NotoSansKhmerUI-Regular.ttf</file>
+ <file variant="compact">NotoSansKhmerUI-Bold.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file variant="elegant">NotoSansLao-Regular.ttf</file>
+ <file variant="elegant">NotoSansLao-Bold.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
+ <file variant="compact">NotoSansLaoUI-Regular.ttf</file>
+ <file variant="compact">NotoSansLaoUI-Bold.ttf</file>
+ </fileset>
+ </family>
+ <family>
+ <fileset>
<file>NanumGothic.ttf</file>
</fileset>
</family>
diff --git a/data/keyboards/Android.mk b/data/keyboards/Android.mk
index a66a884..898efe8 100644
--- a/data/keyboards/Android.mk
+++ b/data/keyboards/Android.mk
@@ -21,17 +21,21 @@ include $(LOCAL_PATH)/common.mk
# Validate all key maps.
include $(CLEAR_VARS)
-validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
-files := \
- $(foreach file,$(keylayouts),frameworks/base/data/keyboards/$(file)) \
- $(foreach file,$(keycharmaps),frameworks/base/data/keyboards/$(file)) \
- $(foreach file,$(keyconfigs),frameworks/base/data/keyboards/$(file))
-
LOCAL_MODULE := validate_framework_keymaps
-LOCAL_MODULE_TAGS := optional
-LOCAL_REQUIRED_MODULES := validatekeymaps
+intermediates := $(call intermediates-dir-for,ETC,$(LOCAL_MODULE),,COMMON)
+LOCAL_BUILT_MODULE := $(intermediates)/stamp
-validate_framework_keymaps: $(files)
- $(hide) $(validatekeymaps) $(files)
-
-include $(BUILD_PHONY_PACKAGE)
+validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
+$(LOCAL_BUILT_MODULE): PRIVATE_VALIDATEKEYMAPS := $(validatekeymaps)
+$(LOCAL_BUILT_MODULE) : $(framework_keylayouts) $(framework_keycharmaps) $(framework_keyconfigs) | $(validatekeymaps)
+ $(hide) $(PRIVATE_VALIDATEKEYMAPS) $^
+ $(hide) mkdir -p $(dir $@) && touch $@
+
+# Run validatekeymaps uncondionally for platform build.
+droidcore all_modules : $(LOCAL_BUILT_MODULE)
+
+# Reset temp vars.
+validatekeymaps :=
+framework_keylayouts :=
+framework_keycharmaps :=
+framework_keyconfigs :=
diff --git a/data/keyboards/common.mk b/data/keyboards/common.mk
index 87c2ef5..d75b691 100644
--- a/data/keyboards/common.mk
+++ b/data/keyboards/common.mk
@@ -15,8 +15,8 @@
# This is the list of framework provided keylayouts and key character maps to include.
# Used by Android.mk and keyboards.mk.
-keylayouts := $(notdir $(wildcard $(LOCAL_PATH)/*.kl))
+framework_keylayouts := $(wildcard $(LOCAL_PATH)/*.kl)
-keycharmaps := $(notdir $(wildcard $(LOCAL_PATH)/*.kcm))
+framework_keycharmaps := $(wildcard $(LOCAL_PATH)/*.kcm)
-keyconfigs := $(notdir $(wildcard $(LOCAL_PATH)/*.idc))
+framework_keyconfigs := $(wildcard $(LOCAL_PATH)/*.idc)
diff --git a/data/keyboards/keyboards.mk b/data/keyboards/keyboards.mk
index c964961..d545241 100644
--- a/data/keyboards/keyboards.mk
+++ b/data/keyboards/keyboards.mk
@@ -16,11 +16,11 @@
include $(LOCAL_PATH)/common.mk
-PRODUCT_COPY_FILES := $(foreach file,$(keylayouts),\
- frameworks/base/data/keyboards/$(file):system/usr/keylayout/$(file))
+PRODUCT_COPY_FILES := $(foreach file,$(framework_keylayouts),\
+ $(file):system/usr/keylayout/$(file))
-PRODUCT_COPY_FILES += $(foreach file,$(keycharmaps),\
- frameworks/base/data/keyboards/$(file):system/usr/keychars/$(file))
+PRODUCT_COPY_FILES += $(foreach file,$(framework_keycharmaps),\
+ $(file):system/usr/keychars/$(file))
-PRODUCT_COPY_FILES += $(foreach file,$(keyconfigs),\
- frameworks/base/data/keyboards/$(file):system/usr/idc/$(file))
+PRODUCT_COPY_FILES += $(foreach file,$(framework_keyconfigs),\
+ $(file):system/usr/idc/$(file))
diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd
index 6e4a03c..ff19476 100644
--- a/docs/html/about/dashboards/index.jd
+++ b/docs/html/about/dashboards/index.jd
@@ -30,16 +30,20 @@ you optimize your app.</p>
<p>This page provides information about the relative number of devices that share a certain
characteristic, such as Android version or screen size. This information may
help you prioritize efforts for <a
-href="{@docRoot}training/basics/supporting-devices/index.html">supporting different devices</a>.</p>
+href="{@docRoot}training/basics/supporting-devices/index.html">supporting different devices</a>
+by revealing which devices are active in the Android and Google Play ecosystem.</p>
-<p>Each snapshot of data represents all the devices that visited the Google Play Store in the
-prior 14 days.</p>
+<p>This data reflects devices running the latest Google Play Store app, which is compatible
+with Android 2.2 and higher. Each snapshot of data represents all the devices that visited the
+Google Play Store in the prior 7 days.</p>
-<p class="note"><strong>Note:</strong> Beginning in April, 2013, these charts are now built
-using data collected from each device when the user visits the Google Play Store. Previously, the
-data was collected when the device simply checked-in to Google servers. We believe the new
-data more accurately reflects those users who are most engaged in the Android and Google Play
-ecosystem.</p>
+
+<div class="note">
+<p><strong>Note:</strong> Beginning in September, 2013, devices running versions older than Android
+2.2 do not appear in this data because those devices do not support the new Google Play Store
+app. Only the new app is able to measure the number of devices that actively visit Google Play Store
+and we believe this measurement best reflects your potential user-base.</p>
+</div>
<h2 id="Platform">Platform Versions</h2>
@@ -57,10 +61,15 @@ Platform Versions</a>.</p>
</div>
-<p style="clear:both"><em>Data collected during a 14-day period ending on August 1, 2013.
+<p style="clear:both"><em>Data collected during a 7-day period ending on September 4, 2013.
<br/>Any versions with less than 0.1% distribution are not shown.</em>
</p>
+<p class="note"><strong>Note:</strong> Because this data is gathered from the new Google Play
+Store app, which supports Android 2.2 and above, devices running older versions are not included.
+However, in August, 2013, versions older than Android 2.2 accounted for about 1% of devices that
+<em>checked in</em> to Google servers (not those that actually visited Google Play Store).
+</p>
@@ -83,7 +92,7 @@ Screens</a>.</p>
</div>
-<p style="clear:both"><em>Data collected during a 14-day period ending on August 1, 2013
+<p style="clear:both"><em>Data collected during a 7-day period ending on September 4, 2013
<br/>Any screen configurations with less than 0.1% distribution are not shown.</em></p>
@@ -130,7 +139,7 @@ uses.</p>
-<p style="clear:both"><em>Data collected during a 14-day period ending on August 1, 2013</em></p>
+<p style="clear:both"><em>Data collected during a 7-day period ending on September 4, 2013</em></p>
@@ -148,32 +157,17 @@ uses.</p>
var VERSION_DATA =
[
{
- "chart": "//chart.googleapis.com/chart?cht=p&chs=500x250&chl=Eclair%7CFroyo%7CGingerbread%7CHoneycomb%7CIce%20Cream%20Sandwich%7CJelly%20Bean&chf=bg%2Cs%2C00000000&chd=t%3A1.3%2C2.5%2C33.1%2C0.1%2C22.5%2C40.5&chco=c4df9b%2C6fad0c",
+ "chart": "//chart.googleapis.com/chart?chs=500x250&cht=p&chco=c4df9b%2C6fad0c&chd=t%3A2.4%2C30.7%2C0.1%2C21.7%2C45.1&chf=bg%2Cs%2C00000000&chl=Froyo%7CGingerbread%7CHoneycomb%7CIce%20Cream%20Sandwich%7CJelly%20Bean",
"data": [
{
- "api": 4,
- "name": "Donut",
- "perc": "0.1"
- },
- {
- "api": 7,
- "name": "Eclair",
- "perc": "1.2"
- },
- {
"api": 8,
"name": "Froyo",
- "perc": "2.5"
- },
- {
- "api": 9,
- "name": "Gingerbread",
- "perc": "0.1"
+ "perc": "2.4"
},
{
"api": 10,
"name": "Gingerbread",
- "perc": "33.0"
+ "perc": "30.7"
},
{
"api": 13,
@@ -183,17 +177,17 @@ var VERSION_DATA =
{
"api": 15,
"name": "Ice Cream Sandwich",
- "perc": "22.5"
+ "perc": "21.7"
},
{
"api": 16,
"name": "Jelly Bean",
- "perc": "34.0"
+ "perc": "36.6"
},
{
"api": 17,
"name": "Jelly Bean",
- "perc": "6.5"
+ "perc": "8.5"
}
]
}
@@ -209,30 +203,29 @@ var SCREEN_DATA =
"data": {
"Large": {
"hdpi": "0.4",
- "ldpi": "0.5",
- "mdpi": "3.2",
- "tvdpi": "1.1",
+ "ldpi": "0.6",
+ "mdpi": "3.4",
+ "tvdpi": "1.2",
"xhdpi": "0.5"
},
"Normal": {
- "hdpi": "34.5",
+ "hdpi": "33.6",
"ldpi": "0.1",
- "mdpi": "15.9",
- "xhdpi": "23.9",
- "xxhdpi": "5.7"
+ "mdpi": "15.7",
+ "xhdpi": "23.1",
+ "xxhdpi": "7.1"
},
"Small": {
- "hdpi": "0.1",
- "ldpi": "9.7"
+ "ldpi": "9.5"
},
"Xlarge": {
- "hdpi": "0.2",
- "mdpi": "4.1",
+ "hdpi": "0.3",
+ "mdpi": "4.4",
"xhdpi": "0.1"
}
},
- "densitychart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chf=bg%2Cs%2C00000000&chd=t%3A10.3%2C23.2%2C1.1%2C35.2%2C24.5%2C5.7&chco=c4df9b%2C6fad0c",
- "layoutchart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chl=Xlarge%7CLarge%7CNormal%7CSmall&chf=bg%2Cs%2C00000000&chd=t%3A4.4%2C5.7%2C80.2%2C9.8&chco=c4df9b%2C6fad0c"
+ "densitychart": "//chart.googleapis.com/chart?chs=400x250&cht=p&chco=c4df9b%2C6fad0c&chd=t%3A10.2%2C23.5%2C1.2%2C34.3%2C23.7%2C7.1&chf=bg%2Cs%2C00000000&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi",
+ "layoutchart": "//chart.googleapis.com/chart?chs=400x250&cht=p&chco=c4df9b%2C6fad0c&chd=t%3A4.8%2C6.1%2C79.6%2C9.5&chf=bg%2Cs%2C00000000&chl=Xlarge%7CLarge%7CNormal%7CSmall"
}
];
@@ -294,6 +287,11 @@ var VERSION_NAMES =
"api":17,
"link":"<a href='/about/versions/android-4.2.html'>4.2.x</a>",
"codename":"Jelly Bean"
+ },
+ {
+ "api":18,
+ "link":"<a href='/about/versions/android-4.3.html'>4.3</a>",
+ "codename":"Jelly Bean"
}
];
diff --git a/docs/html/about/versions/android-4.0.jd b/docs/html/about/versions/android-4.0.jd
index 2fa180c..c026534 100644
--- a/docs/html/about/versions/android-4.0.jd
+++ b/docs/html/about/versions/android-4.0.jd
@@ -62,7 +62,7 @@ class="toggle-content-img" alt="" />
<li><a href="#Multimedia">Multimedia</a></li>
<li><a href="#Camera">Camera</a></li>
<li><a href="#AndroidBeam">Android Beam (NDEF Push with NFC)</a></li>
- <li><a href="#WiFiDirect">Wi-Fi Direct</a></li>
+ <li><a href="#WiFiDirect">Wi-Fi P2P</a></li>
<li><a href="#Bluetooth">Bluetooth Health Devices</a></li>
<li><a href="#A11y">Accessibility</a></li>
<li><a href="#SpellChecker">Spell Checker Services</a></li>
@@ -617,12 +617,13 @@ Beam Demo</a>.</p>
-<h3 id="WiFiDirect">Wi-Fi Direct</h3>
+<h3 id="WiFiDirect">Wi-Fi P2P</h3>
-<p>Android now supports Wi-Fi Direct for peer-to-peer (P2P) connections between Android-powered
-devices and other device types without a hotspot or Internet connection. The Android framework
+<p>Android now supports Wi-Fi peer-to-peer (P2P) connections between Android-powered
+devices and other device types (in compliance with the Wi-Fi
+Alliance's Wi-Fi Direct&trade; certification program) without a hotspot or Internet connection. The Android framework
provides a set of Wi-Fi P2P APIs that allow you to discover and connect to other devices when each
-device supports Wi-Fi Direct, then communicate over a speedy connection across distances much longer
+device supports Wi-Fi P2P, then communicate over a speedy connection across distances much longer
than a Bluetooth connection.</p>
<p>A new package, {@link android.net.wifi.p2p}, contains all the APIs for performing peer-to-peer
@@ -669,7 +670,7 @@ formed and who is the group owner.</li>
<li>{@link android.Manifest.permission#ACCESS_WIFI_STATE}</li>
<li>{@link android.Manifest.permission#CHANGE_WIFI_STATE}</li>
<li>{@link android.Manifest.permission#INTERNET} (although your app doesn’t technically connect
-to the Internet, communicating to Wi-Fi Direct peers with standard java sockets requires Internet
+to the Internet, communicating to Wi-Fi P2P peers with standard java sockets requires Internet
permission).</li>
</ul>
@@ -696,7 +697,7 @@ this device have changed.</li>
</ul>
<p>See the {@link android.net.wifi.p2p.WifiP2pManager} documentation for more information. Also
-look at the <a href="{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi Direct Demo</a>
+look at the <a href="{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi P2P Demo</a>
sample application.</p>
diff --git a/docs/html/about/versions/android-4.1.jd b/docs/html/about/versions/android-4.1.jd
index d4b9ebf..76b90ac 100644
--- a/docs/html/about/versions/android-4.1.jd
+++ b/docs/html/about/versions/android-4.1.jd
@@ -41,7 +41,7 @@ sdk.platform.apiLevel=16
<ol>
<li><a href="#AndroidBeam">Android Beam</a></li>
<li><a href="#LocalNsd">Network service discovery</a></li>
- <li><a href="#WiFiNsd">Wi-Fi Direct service discovery</a></li>
+ <li><a href="#WiFiNsd">Wi-Fi P2P service discovery</a></li>
<li><a href="#NetworkUsage">Network usage</a></li>
</ol>
</li>
@@ -506,11 +506,11 @@ discovered service, allowing you to initiate the connection.</p>
-<h3 id="WiFiNsd">Wi-Fi Direct service discovery</h3>
+<h3 id="WiFiNsd">Wi-Fi P2P service discovery</h3>
-<p>The Wi-Fi Direct APIs are enhanced in Android 4.1 to support pre-association service discovery in
+<p>The Wi-Fi P2P APIs are enhanced in Android 4.1 to support pre-association service discovery in
the {@link android.net.wifi.p2p.WifiP2pManager}. This allows you to discover and filter nearby
-devices by services using Wi-Fi Direct before connecting to one, while Network Service
+devices by services using Wi-Fi P2P before connecting to one, while Network Service
Discovery allows you to discover a service on an existing connected network (such as a local Wi-Fi
network).</p>
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 2a31374..21d295a 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -408,7 +408,7 @@
</ul>
</li>
<li><a href="<?cs var:toroot?>guide/topics/connectivity/wifip2p.html">
- <span class="en">Wi-Fi Direct</span></a>
+ <span class="en">Wi-Fi P2P</span></a>
</li>
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot?>guide/topics/connectivity/usb/index.html">
diff --git a/docs/html/guide/topics/connectivity/wifip2p.jd b/docs/html/guide/topics/connectivity/wifip2p.jd
index 2167a0f..7cadde1 100644
--- a/docs/html/guide/topics/connectivity/wifip2p.jd
+++ b/docs/html/guide/topics/connectivity/wifip2p.jd
@@ -1,5 +1,5 @@
-page.title=Wi-Fi Direct
-page.tags="wireless","WifiP2pManager"
+page.title=Wi-Fi Peer-to-Peer
+page.tags="wireless","WifiP2pManager","Wi-Fi Direct","WiFi Direct","P2P","Wi-Fi P2P","WiFi P2P"
@jd:body
@@ -9,10 +9,10 @@ page.tags="wireless","WifiP2pManager"
<ol>
<li><a href="#api">API Overview</a></li>
- <li><a href="#creating-br">Creating a Broadcast Receiver for Wi-Fi Direct Intents</a></li>
+ <li><a href="#creating-br">Creating a Broadcast Receiver for Wi-Fi P2P Intents</a></li>
<li>
- <a href="#creating-app">Creating a Wi-Fi Direct Application</a>
+ <a href="#creating-app">Creating a Wi-Fi P2P Application</a>
<ol>
<li><a href="#setup">Initial setup</a></li>
@@ -25,21 +25,24 @@ page.tags="wireless","WifiP2pManager"
</ol>
</li>
</ol>
- <h2>Related Samples</h2>
- <ol>
- <li><a href="{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi Direct Demo</a></li>
- </ol>
+ <h2>See also</h2>
+ <ul>
+ <li><a href="{@docRoot}training/connect-devices-wirelessly/wifi-direct.html">Creating
+ P2P Connections with Wi-Fi</a></li>
+ </ul>
</div>
</div>
- <p>Wi-Fi Direct allows Android 4.0 (API level 14) or later devices with the appropriate hardware
- to connect directly to each other via Wi-Fi without an intermediate access point.
- Using these APIs, you can discover and connect to other devices when each device supports Wi-Fi Direct,
- then communicate over a speedy connection across distances much longer than a Bluetooth connection.
- This is useful for applications that share data among users, such as a multiplayer game or
- a photo sharing application.</p>
- <p>The Wi-Fi Direct APIs consist of the following main parts:</p>
+<p>Wi-Fi peer-to-peer (P2P) allows Android 4.0 (API level 14) or later devices with the appropriate
+hardware to connect directly to each other via Wi-Fi without an intermediate access point (Android's
+Wi-Fi P2P framework complies with the Wi-Fi Alliance's Wi-Fi Direct&trade; certification program).
+Using these APIs, you can discover and connect to other devices when each device supports Wi-Fi P2P,
+then communicate over a speedy connection across distances much longer than a Bluetooth connection.
+This is useful for applications that share data among users, such as a multiplayer game or
+a photo sharing application.</p>
+
+ <p>The Wi-Fi P2P APIs consist of the following main parts:</p>
<ul>
<li>Methods that allow you to discover, request, and connect to peers are defined
@@ -50,7 +53,7 @@ page.tags="wireless","WifiP2pManager"
android.net.wifi.p2p.WifiP2pManager} methods, each method can receive a specific listener
passed in as a parameter.</li>
- <li>Intents that notify you of specific events detected by the Wi-Fi Direct framework,
+ <li>Intents that notify you of specific events detected by the Wi-Fi P2P framework,
such as a dropped connection or a newly discovered peer.</li>
</ul>
@@ -70,7 +73,7 @@ page.tags="wireless","WifiP2pManager"
the Wi-Fi hardware on your device to do things like discover and connect to peers. The following actions
are available:</p>
-<p class="table-caption"><strong>Table 1.</strong>Wi-Fi Direct Methods</p>
+<p class="table-caption"><strong>Table 1.</strong>Wi-Fi P2P Methods</p>
<table>
<tr>
@@ -80,7 +83,7 @@ page.tags="wireless","WifiP2pManager"
<tr>
<td>{@link android.net.wifi.p2p.WifiP2pManager#initialize initialize()}</td>
- <td>Registers the application with the Wi-Fi framework. This must be called before calling any other Wi-Fi Direct method.</td>
+ <td>Registers the application with the Wi-Fi framework. This must be called before calling any other Wi-Fi P2P method.</td>
</tr>
<tr>
@@ -126,12 +129,12 @@ page.tags="wireless","WifiP2pManager"
<p>{@link android.net.wifi.p2p.WifiP2pManager} methods let you pass in a listener,
- so that the Wi-Fi Direct framework can notify your
+ so that the Wi-Fi P2P framework can notify your
activity of the status of a call. The available listener interfaces and the
corresponding {@link android.net.wifi.p2p.WifiP2pManager} method calls that use the listeners
are described in the following table:</p>
- <p class="table-caption"><strong>Table 2.</strong> Wi-Fi Direct Listeners</p>
+ <p class="table-caption"><strong>Table 2.</strong> Wi-Fi P2P Listeners</p>
<table>
<tr>
@@ -168,12 +171,12 @@ page.tags="wireless","WifiP2pManager"
</tr>
</table>
-<p>The Wi-Fi Direct APIs define intents that are broadcast when certain Wi-Fi Direct events happen,
+<p>The Wi-Fi P2P APIs define intents that are broadcast when certain Wi-Fi P2P events happen,
such as when a new peer is discovered or when a device's Wi-Fi state changes. You can register
to receive these intents in your application by <a href="#creating-br">creating a broadcast
receiver</a> that handles these intents:</p>
-<p class="table-caption"><strong>Table 3.</strong> Wi-Fi Direct Intents</p>
+<p class="table-caption"><strong>Table 3.</strong> Wi-Fi P2P Intents</p>
<table>
<tr>
@@ -194,7 +197,7 @@ page.tags="wireless","WifiP2pManager"
</tr>
<tr>
<td>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_CHANGED_ACTION}</td>
- <td>Broadcast when Wi-Fi Direct is enabled or disabled on the device.</td>
+ <td>Broadcast when Wi-Fi P2P is enabled or disabled on the device.</td>
</tr>
<tr>
<td>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_THIS_DEVICE_CHANGED_ACTION}</td>
@@ -204,11 +207,11 @@ page.tags="wireless","WifiP2pManager"
- <h2 id="creating-br">Creating a Broadcast Receiver for Wi-Fi Direct Intents</h2>
+ <h2 id="creating-br">Creating a Broadcast Receiver for Wi-Fi P2P Intents</h2>
<p>A broadcast receiver allows you to receive intents broadcast by the Android system,
so that your application can respond to events that you are interested in. The basic steps
- for creating a broadcast receiver to handle Wi-Fi Direct intents are as follows:</p>
+ for creating a broadcast receiver to handle Wi-Fi P2P intents are as follows:</p>
<ol>
<li>Create a class that extends the {@link android.content.BroadcastReceiver} class. For the
@@ -267,17 +270,17 @@ public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
}
</pre>
- <h2 id="creating-app">Creating a Wi-Fi Direct Application</h2>
+ <h2 id="creating-app">Creating a Wi-Fi P2P Application</h2>
- <p>Creating a Wi-Fi Direct application involves creating and registering a
+ <p>Creating a Wi-Fi P2P application involves creating and registering a
broadcast receiver for your application, discovering peers, connecting to a peer, and
transferring data to a peer. The following sections describe how to do this.</p>
<h3 id="setup">Initial setup</h3>
- <p>Before using the Wi-Fi Direct APIs, you must ensure that your application can access
- the hardware and that the device supports the Wi-Fi Direct protocol. If Wi-Fi Direct is supported,
+ <p>Before using the Wi-Fi P2P APIs, you must ensure that your application can access
+ the hardware and that the device supports the Wi-Fi P2P protocol. If Wi-Fi P2P is supported,
you can obtain an instance of {@link android.net.wifi.p2p.WifiP2pManager}, create and register
- your broadcast receiver, and begin using the Wi-Fi Direct APIs.</p>
+ your broadcast receiver, and begin using the Wi-Fi P2P APIs.</p>
<ol>
<li>
<p>Request permission to use the Wi-Fi hardware on the device and also declare
@@ -292,10 +295,10 @@ public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
</pre>
</li>
- <li>Check to see if Wi-Fi Direct is on and supported. A good place to check this is in your
+ <li>Check to see if Wi-Fi P2P is on and supported. A good place to check this is in your
broadcast receiver when it receives the {@link
android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_CHANGED_ACTION} intent. Notify your
- activity of the Wi-Fi Direct state and react accordingly:
+ activity of the Wi-Fi P2P state and react accordingly:
<pre>
&#064;Override
public void onReceive(Context context, Intent intent) {
@@ -304,9 +307,9 @@ public void onReceive(Context context, Intent intent) {
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
- // Wifi Direct is enabled
+ // Wifi P2P is enabled
} else {
- // Wi-Fi Direct is not enabled
+ // Wi-Fi P2P is not enabled
}
}
...
@@ -315,10 +318,10 @@ public void onReceive(Context context, Intent intent) {
</li>
<li>In your activity's {@link android.app.Activity#onCreate onCreate()} method, obtain an instance of {@link
- android.net.wifi.p2p.WifiP2pManager} and register your application with the Wi-Fi Direct
+ android.net.wifi.p2p.WifiP2pManager} and register your application with the Wi-Fi P2P
framework by calling {@link android.net.wifi.p2p.WifiP2pManager#initialize initialize()}. This
method returns a {@link android.net.wifi.p2p.WifiP2pManager.Channel}, which is used to connect
- your application to the Wi-Fi Direct framework. You should also create an instance of your
+ your application to the Wi-Fi P2P framework. You should also create an instance of your
broadcast receiver with the {@link
android.net.wifi.p2p.WifiP2pManager} and {@link android.net.wifi.p2p.WifiP2pManager.Channel}
objects along with a reference to your activity. This allows your broadcast receiver to notify
@@ -376,11 +379,11 @@ protected void onPause() {
</pre>
<p>When you have obtained a {@link android.net.wifi.p2p.WifiP2pManager.Channel} and
- set up a broadcast receiver, your application can make Wi-Fi Direct method calls and receive
- Wi-Fi Direct intents.</p>
+ set up a broadcast receiver, your application can make Wi-Fi P2P method calls and receive
+ Wi-Fi P2P intents.</p>
</li>
- <p>You can now implement your application and use the Wi-Fi Direct features by calling the
+ <p>You can now implement your application and use the Wi-Fi P2P features by calling the
methods in {@link android.net.wifi.p2p.WifiP2pManager}. The next sections describe how to do common actions
such as discovering and connecting to peers.</p>
</ol>
@@ -492,10 +495,10 @@ mManager.connect(mChannel, config, new ActionListener() {
</ol>
<p>The following example, modified from the <a href=
- "{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi Direct Demo</a> sample, shows you how
+ "{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi P2P Demo</a> sample, shows you how
to create this client-server socket communication and transfer JPEG images from a client
to a server with a service. For a complete working example, compile and run the <a href=
- "{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi Direct Demo</a> sample.</p>
+ "{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi P2P Demo</a> sample.</p>
<pre>
public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
diff --git a/docs/html/training/connect-devices-wirelessly/index.jd b/docs/html/training/connect-devices-wirelessly/index.jd
index f27b9c3..db79abe 100644
--- a/docs/html/training/connect-devices-wirelessly/index.jd
+++ b/docs/html/training/connect-devices-wirelessly/index.jd
@@ -17,7 +17,7 @@ startpage=true
<h2>You should also read</h2>
<ul>
- <li><a href="{@docRoot}guide/topics/connectivity/wifip2p.html">Wi-Fi Direct</a></li>
+ <li><a href="{@docRoot}guide/topics/connectivity/wifip2p.html">Wi-Fi P2P</a></li>
</ul>
@@ -37,8 +37,8 @@ other machines on the same network.</p>
<p>This class describes the key APIs for finding and
connecting to other devices from your application. Specifically, it
describes the NSD API for discovering available services and the Wi-Fi
-Direct&trade; API for doing peer-to-peer wireless connections. This class also
-shows you how to use NSD and Wi-Fi Direct in
+Peer-to-Peer (P2P) API for doing peer-to-peer wireless connections. This class also
+shows you how to use NSD and Wi-Fi P2P in
combination to detect the services offered by a device and connect to the
device when neither device is connected to a network.
</p>
@@ -49,13 +49,13 @@ device when neither device is connected to a network.
<dd>Learn how to broadcast services offered by your own application, discover
services offered on the local network, and use NSD to determine the connection
details for the service you wish to connect to.</dd>
- <dt><strong><a href="wifi-direct.html">Connecting with Wi-Fi Direct</a></strong></dt>
+ <dt><strong><a href="wifi-direct.html">Creating P2P Connections with Wi-Fi</a></strong></dt>
<dd>Learn how to fetch a list of nearby peer devices, create an access point
- for legacy devices, and connect to other devices capable of Wi-Fi Direct
+ for legacy devices, and connect to other devices capable of Wi-Fi P2P
connections.</dd>
- <dt><strong><a href="nsd-wifi-direct.html">Using Wi-Fi Direct for Service
+ <dt><strong><a href="nsd-wifi-direct.html">Using Wi-Fi P2P for Service
Discovery</a></strong></dt>
<dd>Learn how to discover services published by nearby devices without being
- on the same network, using Wi-Fi Direct.</dd>
+ on the same network, using Wi-Fi P2P.</dd>
</dl>
diff --git a/docs/html/training/connect-devices-wirelessly/nsd-wifi-direct.jd b/docs/html/training/connect-devices-wirelessly/nsd-wifi-direct.jd
index 5e276de..8dc5fd9 100644
--- a/docs/html/training/connect-devices-wirelessly/nsd-wifi-direct.jd
+++ b/docs/html/training/connect-devices-wirelessly/nsd-wifi-direct.jd
@@ -1,4 +1,4 @@
-page.title=Using Wi-Fi Direct for Service Discovery
+page.title=Using Wi-Fi P2P for Service Discovery
parent.title=Connecting Devices Wirelessly
parent.link=index.html
@@ -26,23 +26,23 @@ trainingnavtop=true
<p>The first lesson in this class, <a href="nsd.html">Using Network Service
Discovery</a>, showed you
how to discover services that are connected to a local network. However, using
-Wi-Fi Direct&trad; Service Discovery allows you to discover the services of nearby devices directly,
-without being connected to a network. You can also advertise the services
+Wi-Fi Peer-to-Peer (P2P) Service Discovery allows you to discover the services of nearby devices
+directly, without being connected to a network. You can also advertise the services
running on your device. These capabilities help you communicate between apps,
even when no local network or hotspot is available.</p>
<p>While this set of APIs is similar in purpose to the Network Service Discovery
APIs outlined in a previous lesson, implementing them in code is very different.
This lesson shows you how to discover services available from other devices,
-using Wi-Fi Direct&trade;. The lesson assumes that you're already familiar with the
-<a href="{@docRoot}guide/topics/connectivity/wifip2p.html">Wi-Fi Direct</a> API.</p>
+using Wi-Fi P2P. The lesson assumes that you're already familiar with the
+<a href="{@docRoot}guide/topics/connectivity/wifip2p.html">Wi-Fi P2P</a> API.</p>
<h2 id="manifest">Set Up the Manifest</h2>
-<p>In order to use Wi-Fi Direct, add the {@link
+<p>In order to use Wi-Fi P2P, add the {@link
android.Manifest.permission#CHANGE_WIFI_STATE}, {@link
android.Manifest.permission#ACCESS_WIFI_STATE},
and {@link android.Manifest.permission#INTERNET}
-permissions to your manifest. Even though Wi-Fi Direct doesn't require an
+permissions to your manifest. Even though Wi-Fi P2P doesn't require an
Internet connection, it uses standard Java sockets, and using these in Android
requires the requested permissions.</p>
@@ -244,7 +244,7 @@ provided by the method hints at the problem. Here are the possible error values
and what they mean</p>
<dl>
<dt> {@link android.net.wifi.p2p.WifiP2pManager#P2P_UNSUPPORTED}</dt>
- <dd> Wi-Fi Direct isn't supported on the device running the app.</dd>
+ <dd> Wi-Fi P2P isn't supported on the device running the app.</dd>
<dt> {@link android.net.wifi.p2p.WifiP2pManager#BUSY}</dt>
<dd> The system is to busy to process the request.</dd>
<dt> {@link android.net.wifi.p2p.WifiP2pManager#ERROR}</dt>
diff --git a/docs/html/training/connect-devices-wirelessly/wifi-direct.jd b/docs/html/training/connect-devices-wirelessly/wifi-direct.jd
index b8ed664..98435c6 100644
--- a/docs/html/training/connect-devices-wirelessly/wifi-direct.jd
+++ b/docs/html/training/connect-devices-wirelessly/wifi-direct.jd
@@ -1,12 +1,6 @@
-page.title=Connecting with Wi-Fi Direct
-parent.title=Connecting Devices Wirelessly
-parent.link=index.html
+page.title=Creating P2P Connections with Wi-Fi
trainingnavtop=true
-previous.title=Using Network Service Discovery
-previous.link=nsd.html
-next.title=Service Discovery with Wi-Fi Direct
-next.link=nsd-wifi-direct.html
@jd:body
@@ -21,25 +15,30 @@ next.link=nsd-wifi-direct.html
<li><a href="#fetch">Fetch the List of Peers</a></li>
<li><a href="#connect">Connect to a Peer</a></li>
</ol>
+ <h2>You should also read</h2>
+ <ul>
+ <li><a href="{@docRoot}guide/topics/connectivity/wifip2p.html">Wi-Fi Peer-to-Peer</a></li>
+ </ul>
</div>
</div>
-<p>The Wi-Fi Direct&trade; APIs allow applications to connect to nearby devices without
-needing to connect to a network or hotspot. This allows your application to quickly
+<p>The Wi-Fi peer-to-peer (P2P) APIs allow applications to connect to nearby devices without
+needing to connect to a network or hotspot (Android's Wi-Fi P2P framework complies with the Wi-Fi
+Alliance's Wi-Fi Direct&trade; certification program). Wi-Fi P2P allows your application to quickly
find and interact with nearby devices, at a range beyond the capabilities of Bluetooth.
</p>
<p>
-This lesson shows you how to find and connect to nearby devices using Wi-Fi Direct.
+This lesson shows you how to find and connect to nearby devices using Wi-Fi P2P.
</p>
<h2 id="permissions">Set Up Application Permissions</h2>
-<p>In order to use Wi-Fi Direct, add the {@link
+<p>In order to use Wi-Fi P2P, add the {@link
android.Manifest.permission#CHANGE_WIFI_STATE}, {@link
android.Manifest.permission#ACCESS_WIFI_STATE},
and {@link android.Manifest.permission#INTERNET}
-permissions to your manifest. Wi-Fi Direct doesn't require an internet connection,
+permissions to your manifest. Wi-Fi P2P doesn't require an internet connection,
but it does use standard Java sockets, which require the {@link
android.Manifest.permission#INTERNET} permission.
-So you need the following permissions to use Wi-Fi Direct.</p>
+So you need the following permissions to use Wi-Fi P2P.</p>
<pre>
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
@@ -59,13 +58,13 @@ So you need the following permissions to use Wi-Fi Direct.</p>
</pre>
<h2 id="receiver">Set Up a Broadcast Receiver and Peer-to-Peer Manager</h2>
-<p>To use Wi-Fi Direct, you need to listen for broadcast intents that tell your
+<p>To use Wi-Fi P2P, you need to listen for broadcast intents that tell your
application when certain events have occurred. In your application, instantiate
an {@link
android.content.IntentFilter} and set it to listen for the following:</p>
<dl>
<dt>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_CHANGED_ACTION}</dt>
- <dd>Indicates whether Wi-Fi Peer-To-Peer (P2P) is enabled</dd>
+ <dd>Indicates whether Wi-Fi P2P is enabled</dd>
<dt>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION}</dt>
<dd>Indicates that the available peer list has changed.</dd>
<dt>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_CONNECTION_CHANGED_ACTION}</dt>
@@ -80,7 +79,7 @@ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
- // Indicates a change in the Wi-Fi Peer-to-Peer status.
+ // Indicates a change in the Wi-Fi P2P status.
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
// Indicates a change in the list of available peers.
@@ -101,7 +100,7 @@ android.net.wifi.p2p.WifiP2pManager}, and call its {@link
android.net.wifi.p2p.WifiP2pManager#initialize(Context, Looper, WifiP2pManager.ChannelListener) initialize()}
method. This method returns a {@link
android.net.wifi.p2p.WifiP2pManager.Channel} object, which you'll use later to
-connect your app to the Wi-Fi Direct Framework.</p>
+connect your app to the Wi-Fi P2P framework.</p>
<pre>
&#64;Override
@@ -126,7 +125,7 @@ method, add a condition to handle each P2P state change listed above.</p>
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
- // Determine if Wifi Direct mode is enabled or not, alert
+ // Determine if Wifi P2P mode is enabled or not, alert
// the Activity.
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
@@ -177,7 +176,7 @@ The best place to do this is the {@link android.app.Activity#onResume()} and
<h2 id="discover">Initiate Peer Discovery</h2>
-<p>To start searching for nearby devices with Wi-Fi Direct, call {@link
+<p>To start searching for nearby devices with Wi-Fi P2P, call {@link
android.net.wifi.p2p.WifiP2pManager#discoverPeers(WifiP2pManager.Channel,
WifiP2pManager.ActionListener) discoverPeers()}. This method takes the
following arguments:</p>
@@ -218,7 +217,7 @@ formed.</p>
<h2 id="fetch">Fetch the List of Peers</h2>
<p>Now write the code that fetches and processes the list of peers. First
implement the {@link android.net.wifi.p2p.WifiP2pManager.PeerListListener}
-interface, which provides information about the peers that Wi-Fi Direct has
+interface, which provides information about the peers that Wi-Fi P2P has
detected. The following code snippet illustrates this.</p>
<pre>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index b884620..ebf553c 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -405,7 +405,7 @@ include the action bar on devices running Android 2.1 or higher."
<a href="<?cs var:toroot ?>training/connect-devices-wirelessly/index.html"
description=
"How to find and connect to local devices using Network Service
- Discovery and Wi-Fi Direct in order to create peer-to-peer connections."
+ Discovery and how to create peer-to-peer connections with Wi-Fi."
>Connecting Devices Wirelessly</a>
</div>
<ul>
@@ -414,7 +414,7 @@ include the action bar on devices running Android 2.1 or higher."
</a>
</li>
<li><a href="<?cs var:toroot ?>training/connect-devices-wirelessly/wifi-direct.html">
- Connecting with Wi-Fi Direct
+ Creating P2P Connections with Wi-Fi
</a>
</li>
<li><a href="<?cs var:toroot ?>training/connect-devices-wirelessly/nsd-wifi-direct.html">
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index e5f1cf5..14b812e 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -152,12 +152,24 @@ public class LocationManager {
/**
* Broadcast intent action when the configured location providers
- * change.
+ * change. If you're interacting with the
+ * {@link android.provider.Settings.Secure#LOCATION_MODE} API,
+ * use {@link #MODE_CHANGED_ACTION} instead.
*/
public static final String PROVIDERS_CHANGED_ACTION =
"android.location.PROVIDERS_CHANGED";
/**
+ * Broadcast intent action when {@link android.provider.Settings.Secure#LOCATION_MODE} changes.
+ * If you're interacting with provider-based APIs such as {@link #getProviders(boolean)}, you
+ * use {@link #PROVIDERS_CHANGED_ACTION} instead.
+ *
+ * In the future, there may be mode changes that do not result in
+ * {@link #PROVIDERS_CHANGED_ACTION} broadcasts.
+ */
+ public static final String MODE_CHANGED_ACTION = "android.location.MODE_CHANGED";
+
+ /**
* Broadcast intent action indicating that the GPS has either started or
* stopped receiving GPS fixes. An intent extra provides this state as a
* boolean, where {@code true} means that the GPS is actively receiving fixes.
diff --git a/media/java/android/media/AudioTimestamp.java b/media/java/android/media/AudioTimestamp.java
new file mode 100644
index 0000000..437a0c6
--- /dev/null
+++ b/media/java/android/media/AudioTimestamp.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 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.media;
+
+/**
+ * Structure that groups a position in frame units relative to an assumed audio stream,
+ * together with the estimated time when that frame was presented or is committed to be
+ * presented.
+ * In the case of audio output, "present" means that audio produced on device
+ * is detectable by an external observer off device.
+ * The time is based on the implementation's best effort, using whatever knowledge
+ * is available to the system, but cannot account for any delay unknown to the implementation.
+ *
+ * @see AudioTrack#getTimestamp
+ * @see AudioTrack.TimestampListener
+ *
+ * @hide
+ */
+public final class AudioTimestamp
+{
+ /**
+ * Position in frames relative to start of an assumed audio stream.
+ * The low-order 32 bits of position is in wrapping frame units similar to
+ * {@link AudioTrack#getPlaybackHeadPosition}.
+ */
+ public long framePosition;
+
+ /**
+ * The estimated time when frame was presented or is committed to be presented,
+ * in the same units and timebase as {@link java.lang.System#nanoTime}.
+ */
+ public long nanoTime;
+}
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index d9227bd..88539f28 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -732,6 +732,51 @@ public class AudioTrack
return mSessionId;
}
+ /**
+ * Poll for a timestamp on demand.
+ *
+ * Use if {@link TimestampListener} is not delivered often enough for your needs,
+ * or if you need to get the most recent timestamp outside of the event callback handler.
+ * Calling this method too often may be inefficient;
+ * if you need a high-resolution mapping between frame position and presentation time,
+ * consider implementing that at application level, based on low-resolution timestamps.
+ * The audio data at the returned position may either already have been
+ * presented, or may have not yet been presented but is committed to be presented.
+ * It is not possible to request the time corresponding to a particular position,
+ * or to request the (fractional) position corresponding to a particular time.
+ * If you need such features, consider implementing them at application level.
+ *
+ * @param timestamp a reference to a non-null AudioTimestamp instance allocated
+ * and owned by caller, or null.
+ * @return that same instance if timestamp parameter is non-null and a timestamp is available,
+ * or a reference to a new AudioTimestamp instance which is now owned by caller
+ * if timestamp parameter is null and a timestamp is available,
+ * or null if no timestamp is available. In either successful case,
+ * the AudioTimestamp instance is filled in with a position in frame units, together
+ * with the estimated time when that frame was presented or is committed to
+ * be presented.
+ * In the case that no timestamp is available, any supplied instance is left unaltered.
+ *
+ * @hide
+ */
+ public AudioTimestamp getTimestamp(AudioTimestamp timestamp)
+ {
+ // It's unfortunate, but we have to either create garbage every time or use synchronized
+ long[] longArray = new long[2];
+ int ret = native_get_timestamp(longArray);
+ if (ret == SUCCESS) {
+ if (timestamp == null) {
+ timestamp = new AudioTimestamp();
+ }
+ timestamp.framePosition = longArray[0];
+ timestamp.nanoTime = longArray[1];
+ } else {
+ timestamp = null;
+ }
+ return timestamp;
+ }
+
+
//--------------------------------------------------------------------------
// Initialization / configuration
//--------------------
@@ -1321,6 +1366,11 @@ public class AudioTrack
private native final int native_get_latency();
+ // longArray must be a non-null array of length >= 2
+ // [0] is assigned the frame position
+ // [1] is assigned the time in CLOCK_MONOTONIC nanoseconds
+ private native final int native_get_timestamp(long[] longArray);
+
private native final int native_set_loop(int start, int end, int loopCount);
static private native final int native_get_output_sample_rate(int streamType);
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 1b9bdaf..d286be4 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -26,11 +26,13 @@ import android.net.Proxy;
import android.net.ProxyProperties;
import android.net.Uri;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.ParcelFileDescriptor;
+import android.os.Process;
import android.os.PowerManager;
import android.util.Log;
import android.view.Surface;
@@ -39,15 +41,22 @@ import android.graphics.Bitmap;
import android.graphics.SurfaceTexture;
import android.media.AudioManager;
import android.media.MediaFormat;
+import android.media.MediaTimeProvider;
+import android.media.MediaTimeProvider.OnMediaTimeListener;
+import android.media.SubtitleController;
import android.media.SubtitleData;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.lang.Runnable;
import java.net.InetSocketAddress;
import java.util.Map;
+import java.util.Scanner;
import java.util.Set;
+import java.util.Vector;
import java.lang.ref.WeakReference;
/**
@@ -517,7 +526,7 @@ import java.lang.ref.WeakReference;
* thread by default has a Looper running).
*
*/
-public class MediaPlayer
+public class MediaPlayer implements SubtitleController.Listener
{
/**
Constant to retrieve only the new metadata since the last
@@ -590,6 +599,11 @@ public class MediaPlayer
mEventHandler = null;
}
+ mTimeProvider = new TimeProvider(this);
+ mOutOfBandSubtitleTracks = new Vector<SubtitleTrack>();
+ mOpenSubtitleSources = new Vector<InputStream>();
+ mInbandSubtitleTracks = new SubtitleTrack[0];
+
/* Native setup requires a weak reference to our object.
* It's easier to create it here than in C++.
*/
@@ -1337,6 +1351,8 @@ public class MediaPlayer
mOnInfoListener = null;
mOnVideoSizeChangedListener = null;
mOnTimedTextListener = null;
+ mTimeProvider.close();
+ mTimeProvider = null;
mOnSubtitleDataListener = null;
_release();
}
@@ -1349,6 +1365,22 @@ public class MediaPlayer
* data source and calling prepare().
*/
public void reset() {
+ mSelectedSubtitleTrackIndex = -1;
+ synchronized(mOpenSubtitleSources) {
+ for (final InputStream is: mOpenSubtitleSources) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ }
+ }
+ mOpenSubtitleSources.clear();
+ }
+ mOutOfBandSubtitleTracks.clear();
+ mInbandSubtitleTracks = new SubtitleTrack[0];
+ if (mSubtitleController != null) {
+ mSubtitleController.reset();
+ }
+
stayAwake(false);
_reset();
// make sure none of the listeners get called anymore
@@ -1568,6 +1600,12 @@ public class MediaPlayer
}
}
+ /** @hide */
+ TrackInfo(int type, MediaFormat format) {
+ mTrackType = type;
+ mFormat = format;
+ }
+
/**
* {@inheritDoc}
*/
@@ -1612,6 +1650,19 @@ public class MediaPlayer
* @throws IllegalStateException if it is called in an invalid state.
*/
public TrackInfo[] getTrackInfo() throws IllegalStateException {
+ TrackInfo trackInfo[] = getInbandTrackInfo();
+ // add out-of-band tracks
+ TrackInfo allTrackInfo[] = new TrackInfo[trackInfo.length + mOutOfBandSubtitleTracks.size()];
+ System.arraycopy(trackInfo, 0, allTrackInfo, 0, trackInfo.length);
+ int i = trackInfo.length;
+ for (SubtitleTrack track: mOutOfBandSubtitleTracks) {
+ allTrackInfo[i] = new TrackInfo(TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE, track.getFormat());
+ ++i;
+ }
+ return allTrackInfo;
+ }
+
+ private TrackInfo[] getInbandTrackInfo() throws IllegalStateException {
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
@@ -1644,6 +1695,143 @@ public class MediaPlayer
return false;
}
+ private SubtitleController mSubtitleController;
+
+ /** @hide */
+ public void setSubtitleAnchor(
+ SubtitleController controller,
+ SubtitleController.Anchor anchor) {
+ // TODO: create SubtitleController in MediaPlayer
+ mSubtitleController = controller;
+ mSubtitleController.setAnchor(anchor);
+ }
+
+ private SubtitleTrack[] mInbandSubtitleTracks;
+ private int mSelectedSubtitleTrackIndex = -1;
+ private Vector<SubtitleTrack> mOutOfBandSubtitleTracks;
+ private Vector<InputStream> mOpenSubtitleSources;
+
+ private OnSubtitleDataListener mSubtitleDataListener = new OnSubtitleDataListener() {
+ @Override
+ public void onSubtitleData(MediaPlayer mp, SubtitleData data) {
+ int index = data.getTrackIndex();
+ if (index >= mInbandSubtitleTracks.length) {
+ return;
+ }
+ SubtitleTrack track = mInbandSubtitleTracks[index];
+ if (track != null) {
+ try {
+ long runID = data.getStartTimeUs() + 1;
+ // TODO: move conversion into track
+ track.onData(new String(data.getData(), "UTF-8"), true /* eos */, runID);
+ track.setRunDiscardTimeMs(
+ runID,
+ (data.getStartTimeUs() + data.getDurationUs()) / 1000);
+ } catch (java.io.UnsupportedEncodingException e) {
+ Log.w(TAG, "subtitle data for track " + index + " is not UTF-8 encoded: " + e);
+ }
+ }
+ }
+ };
+
+ /** @hide */
+ @Override
+ public void onSubtitleTrackSelected(SubtitleTrack track) {
+ if (mSelectedSubtitleTrackIndex >= 0) {
+ deselectTrack(mSelectedSubtitleTrackIndex);
+ }
+ mSelectedSubtitleTrackIndex = -1;
+ setOnSubtitleDataListener(null);
+ for (int i = 0; i < mInbandSubtitleTracks.length; i++) {
+ if (mInbandSubtitleTracks[i] == track) {
+ Log.v(TAG, "Selecting subtitle track " + i);
+ selectTrack(i);
+ mSelectedSubtitleTrackIndex = i;
+ setOnSubtitleDataListener(mSubtitleDataListener);
+ break;
+ }
+ }
+ // no need to select out-of-band tracks
+ }
+
+ /** @hide */
+ public void addSubtitleSource(InputStream is, MediaFormat format)
+ throws IllegalStateException
+ {
+ final InputStream fIs = is;
+ final MediaFormat fFormat = format;
+
+ // Ensure all input streams are closed. It is also a handy
+ // way to implement timeouts in the future.
+ synchronized(mOpenSubtitleSources) {
+ mOpenSubtitleSources.add(is);
+ }
+
+ // process each subtitle in its own thread
+ final HandlerThread thread = new HandlerThread("SubtitleReadThread",
+ Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
+ thread.start();
+ Handler handler = new Handler(thread.getLooper());
+ handler.post(new Runnable() {
+ private int addTrack() {
+ if (fIs == null || mSubtitleController == null) {
+ return MEDIA_INFO_UNSUPPORTED_SUBTITLE;
+ }
+
+ SubtitleTrack track = mSubtitleController.addTrack(fFormat);
+ if (track == null) {
+ return MEDIA_INFO_UNSUPPORTED_SUBTITLE;
+ }
+
+ // TODO: do the conversion in the subtitle track
+ Scanner scanner = new Scanner(fIs, "UTF-8");
+ String contents = scanner.useDelimiter("\\A").next();
+ synchronized(mOpenSubtitleSources) {
+ mOpenSubtitleSources.remove(fIs);
+ }
+ scanner.close();
+ mOutOfBandSubtitleTracks.add(track);
+ track.onData(contents, true /* eos */, ~0 /* runID: keep forever */);
+ // update default track selection
+ mSubtitleController.selectDefaultTrack();
+ return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
+ }
+
+ public void run() {
+ int res = addTrack();
+ if (mEventHandler != null) {
+ Message m = mEventHandler.obtainMessage(MEDIA_INFO, res, 0, null);
+ mEventHandler.sendMessage(m);
+ }
+ thread.getLooper().quitSafely();
+ }
+ });
+ }
+
+ private void scanInternalSubtitleTracks() {
+ if (mSubtitleController == null) {
+ Log.e(TAG, "Should have subtitle controller already set");
+ return;
+ }
+
+ TrackInfo[] tracks = getInbandTrackInfo();
+ SubtitleTrack[] inbandTracks = new SubtitleTrack[tracks.length];
+ for (int i=0; i < tracks.length; i++) {
+ if (tracks[i].getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
+ if (i < mInbandSubtitleTracks.length) {
+ inbandTracks[i] = mInbandSubtitleTracks[i];
+ } else {
+ MediaFormat format = MediaFormat.createSubtitleFormat(
+ "text/vtt", tracks[i].getLanguage());
+ SubtitleTrack track = mSubtitleController.addTrack(format);
+ inbandTracks[i] = track;
+ }
+ }
+ }
+ mInbandSubtitleTracks = inbandTracks;
+ mSubtitleController.selectDefaultTrack();
+ }
+
/* TODO: Limit the total number of external timed text source to a reasonable number.
*/
/**
@@ -1834,6 +2022,13 @@ public class MediaPlayer
private void selectOrDeselectTrack(int index, boolean select)
throws IllegalStateException {
+ // ignore out-of-band tracks
+ TrackInfo[] trackInfo = getInbandTrackInfo();
+ if (index >= trackInfo.length &&
+ index < trackInfo.length + mOutOfBandSubtitleTracks.size()) {
+ return;
+ }
+
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
@@ -1914,11 +2109,21 @@ public class MediaPlayer
private static final int MEDIA_BUFFERING_UPDATE = 3;
private static final int MEDIA_SEEK_COMPLETE = 4;
private static final int MEDIA_SET_VIDEO_SIZE = 5;
+ private static final int MEDIA_STARTED = 6;
+ private static final int MEDIA_PAUSED = 7;
+ private static final int MEDIA_STOPPED = 8;
private static final int MEDIA_TIMED_TEXT = 99;
private static final int MEDIA_ERROR = 100;
private static final int MEDIA_INFO = 200;
private static final int MEDIA_SUBTITLE_DATA = 201;
+ private TimeProvider mTimeProvider;
+
+ /** @hide */
+ public MediaTimeProvider getMediaTimeProvider() {
+ return mTimeProvider;
+ }
+
private class EventHandler extends Handler
{
private MediaPlayer mMediaPlayer;
@@ -1936,6 +2141,7 @@ public class MediaPlayer
}
switch(msg.what) {
case MEDIA_PREPARED:
+ scanInternalSubtitleTracks();
if (mOnPreparedListener != null)
mOnPreparedListener.onPrepared(mMediaPlayer);
return;
@@ -1946,14 +2152,31 @@ public class MediaPlayer
stayAwake(false);
return;
+ case MEDIA_STOPPED:
+ if (mTimeProvider != null) {
+ mTimeProvider.onStopped();
+ }
+ break;
+
+ case MEDIA_STARTED:
+ case MEDIA_PAUSED:
+ if (mTimeProvider != null) {
+ mTimeProvider.onPaused(msg.what == MEDIA_PAUSED);
+ }
+ break;
+
case MEDIA_BUFFERING_UPDATE:
if (mOnBufferingUpdateListener != null)
mOnBufferingUpdateListener.onBufferingUpdate(mMediaPlayer, msg.arg1);
return;
case MEDIA_SEEK_COMPLETE:
- if (mOnSeekCompleteListener != null)
+ if (mOnSeekCompleteListener != null) {
mOnSeekCompleteListener.onSeekComplete(mMediaPlayer);
+ }
+ if (mTimeProvider != null) {
+ mTimeProvider.onSeekComplete(mMediaPlayer);
+ }
return;
case MEDIA_SET_VIDEO_SIZE:
@@ -1974,9 +2197,18 @@ public class MediaPlayer
return;
case MEDIA_INFO:
- if (msg.arg1 != MEDIA_INFO_VIDEO_TRACK_LAGGING) {
+ switch (msg.arg1) {
+ case MEDIA_INFO_VIDEO_TRACK_LAGGING:
Log.i(TAG, "Info (" + msg.arg1 + "," + msg.arg2 + ")");
+ break;
+ case MEDIA_INFO_METADATA_UPDATE:
+ scanInternalSubtitleTracks();
+ break;
+ case MEDIA_INFO_EXTERNAL_METADATA_UPDATE:
+ msg.arg1 = MEDIA_INFO_METADATA_UPDATE;
+ break;
}
+
if (mOnInfoListener != null) {
mOnInfoListener.onInfo(mMediaPlayer, msg.arg1, msg.arg2);
}
@@ -2375,6 +2607,12 @@ public class MediaPlayer
*/
public static final int MEDIA_INFO_METADATA_UPDATE = 802;
+ /** A new set of external-only metadata is available. Used by
+ * JAVA framework to avoid triggering track scanning.
+ * @hide
+ */
+ public static final int MEDIA_INFO_EXTERNAL_METADATA_UPDATE = 803;
+
/** Failed to handle timed text track properly.
* @see android.media.MediaPlayer.OnInfoListener
*
@@ -2496,4 +2734,351 @@ public class MediaPlayer
}
private native void updateProxyConfig(ProxyProperties props);
+
+ /** @hide */
+ static class TimeProvider implements MediaPlayer.OnSeekCompleteListener,
+ MediaTimeProvider {
+ private static final String TAG = "MTP";
+ private static final long MAX_NS_WITHOUT_POSITION_CHECK = 5000000000L;
+ private static final long MAX_EARLY_CALLBACK_US = 1000;
+ private static final long TIME_ADJUSTMENT_RATE = 2; /* meaning 1/2 */
+ private long mLastTimeUs = 0;
+ private MediaPlayer mPlayer;
+ private boolean mPaused = true;
+ private boolean mStopped = true;
+ private long mLastReportedTime;
+ private long mTimeAdjustment;
+ // since we are expecting only a handful listeners per stream, there is
+ // no need for log(N) search performance
+ private MediaTimeProvider.OnMediaTimeListener mListeners[];
+ private long mTimes[];
+ private long mLastNanoTime;
+ private Handler mEventHandler;
+ private boolean mRefresh = false;
+ private boolean mPausing = false;
+ private static final int NOTIFY = 1;
+ private static final int NOTIFY_TIME = 0;
+ private static final int REFRESH_AND_NOTIFY_TIME = 1;
+ private static final int NOTIFY_STOP = 2;
+ private static final int NOTIFY_SEEK = 3;
+
+ /** @hide */
+ public boolean DEBUG = false;
+
+ public TimeProvider(MediaPlayer mp) {
+ mPlayer = mp;
+ try {
+ getCurrentTimeUs(true, false);
+ } catch (IllegalStateException e) {
+ // we assume starting position
+ mRefresh = true;
+ }
+ mEventHandler = new EventHandler();
+ mListeners = new MediaTimeProvider.OnMediaTimeListener[0];
+ mTimes = new long[0];
+ mLastTimeUs = 0;
+ mTimeAdjustment = 0;
+ }
+
+ private void scheduleNotification(int type, long delayUs) {
+ if (DEBUG) Log.v(TAG, "scheduleNotification " + type + " in " + delayUs);
+ mEventHandler.removeMessages(NOTIFY);
+ Message msg = mEventHandler.obtainMessage(NOTIFY, type, 0);
+ mEventHandler.sendMessageDelayed(msg, (int) (delayUs / 1000));
+ }
+
+ /** @hide */
+ public void close() {
+ mEventHandler.removeMessages(NOTIFY);
+ }
+
+ /** @hide */
+ public void onPaused(boolean paused) {
+ synchronized(this) {
+ if (DEBUG) Log.d(TAG, "onPaused: " + paused);
+ if (mStopped) { // handle as seek if we were stopped
+ mStopped = false;
+ scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
+ } else {
+ mPausing = paused; // special handling if player disappeared
+ scheduleNotification(REFRESH_AND_NOTIFY_TIME, 0 /* delay */);
+ }
+ }
+ }
+
+ /** @hide */
+ public void onStopped() {
+ synchronized(this) {
+ if (DEBUG) Log.d(TAG, "onStopped");
+ mPaused = true;
+ mStopped = true;
+ scheduleNotification(NOTIFY_STOP, 0 /* delay */);
+ }
+ }
+
+ /** @hide */
+ @Override
+ public void onSeekComplete(MediaPlayer mp) {
+ synchronized(this) {
+ mStopped = false;
+ scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
+ }
+ }
+
+ /** @hide */
+ public void onNewPlayer() {
+ if (mRefresh) {
+ synchronized(this) {
+ scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
+ }
+ }
+ }
+
+ private synchronized void notifySeek() {
+ try {
+ long timeUs = getCurrentTimeUs(true, false);
+ if (DEBUG) Log.d(TAG, "onSeekComplete at " + timeUs);
+
+ for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) {
+ if (listener == null) {
+ break;
+ }
+ listener.onSeek(timeUs);
+ }
+ } catch (IllegalStateException e) {
+ // we should not be there, but at least signal pause
+ if (DEBUG) Log.d(TAG, "onSeekComplete but no player");
+ mPausing = true; // special handling if player disappeared
+ notifyTimedEvent(false /* refreshTime */);
+ }
+ }
+
+ private synchronized void notifyStop() {
+ for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) {
+ if (listener == null) {
+ break;
+ }
+ listener.onStop();
+ }
+ }
+
+ private int registerListener(MediaTimeProvider.OnMediaTimeListener listener) {
+ int i = 0;
+ for (; i < mListeners.length; i++) {
+ if (mListeners[i] == listener || mListeners[i] == null) {
+ break;
+ }
+ }
+
+ // new listener
+ if (i >= mListeners.length) {
+ MediaTimeProvider.OnMediaTimeListener[] newListeners =
+ new MediaTimeProvider.OnMediaTimeListener[i + 1];
+ long[] newTimes = new long[i + 1];
+ System.arraycopy(mListeners, 0, newListeners, 0, mListeners.length);
+ System.arraycopy(mTimes, 0, newTimes, 0, mTimes.length);
+ mListeners = newListeners;
+ mTimes = newTimes;
+ }
+
+ if (mListeners[i] == null) {
+ mListeners[i] = listener;
+ mTimes[i] = MediaTimeProvider.NO_TIME;
+ }
+ return i;
+ }
+
+ public void notifyAt(
+ long timeUs, MediaTimeProvider.OnMediaTimeListener listener) {
+ synchronized(this) {
+ if (DEBUG) Log.d(TAG, "notifyAt " + timeUs);
+ mTimes[registerListener(listener)] = timeUs;
+ scheduleNotification(NOTIFY_TIME, 0 /* delay */);
+ }
+ }
+
+ public void scheduleUpdate(MediaTimeProvider.OnMediaTimeListener listener) {
+ synchronized(this) {
+ if (DEBUG) Log.d(TAG, "scheduleUpdate");
+ int i = registerListener(listener);
+
+ if (mStopped) {
+ scheduleNotification(NOTIFY_STOP, 0 /* delay */);
+ } else {
+ mTimes[i] = 0;
+ scheduleNotification(NOTIFY_TIME, 0 /* delay */);
+ }
+ }
+ }
+
+ public void cancelNotifications(
+ MediaTimeProvider.OnMediaTimeListener listener) {
+ synchronized(this) {
+ int i = 0;
+ for (; i < mListeners.length; i++) {
+ if (mListeners[i] == listener) {
+ System.arraycopy(mListeners, i + 1,
+ mListeners, i, mListeners.length - i - 1);
+ System.arraycopy(mTimes, i + 1,
+ mTimes, i, mTimes.length - i - 1);
+ mListeners[mListeners.length - 1] = null;
+ mTimes[mTimes.length - 1] = NO_TIME;
+ break;
+ } else if (mListeners[i] == null) {
+ break;
+ }
+ }
+
+ scheduleNotification(NOTIFY_TIME, 0 /* delay */);
+ }
+ }
+
+ private synchronized void notifyTimedEvent(boolean refreshTime) {
+ // figure out next callback
+ long nowUs;
+ try {
+ nowUs = getCurrentTimeUs(refreshTime, true);
+ } catch (IllegalStateException e) {
+ // assume we paused until new player arrives
+ mRefresh = true;
+ mPausing = true; // this ensures that call succeeds
+ nowUs = getCurrentTimeUs(refreshTime, true);
+ }
+ long nextTimeUs = nowUs;
+
+ if (DEBUG) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("notifyTimedEvent(").append(mLastTimeUs).append(" -> ")
+ .append(nowUs).append(") from {");
+ boolean first = true;
+ for (long time: mTimes) {
+ if (time == NO_TIME) {
+ continue;
+ }
+ if (!first) sb.append(", ");
+ sb.append(time);
+ first = false;
+ }
+ sb.append("}");
+ Log.d(TAG, sb.toString());
+ }
+
+ Vector<MediaTimeProvider.OnMediaTimeListener> activatedListeners =
+ new Vector<MediaTimeProvider.OnMediaTimeListener>();
+ for (int ix = 0; ix < mTimes.length; ix++) {
+ if (mListeners[ix] == null) {
+ break;
+ }
+ if (mTimes[ix] <= NO_TIME) {
+ // ignore, unless we were stopped
+ } else if (mTimes[ix] <= nowUs + MAX_EARLY_CALLBACK_US) {
+ activatedListeners.add(mListeners[ix]);
+ if (DEBUG) Log.d(TAG, "removed");
+ mTimes[ix] = NO_TIME;
+ } else if (nextTimeUs == nowUs || mTimes[ix] < nextTimeUs) {
+ nextTimeUs = mTimes[ix];
+ }
+ }
+
+ if (nextTimeUs > nowUs && !mPaused) {
+ // schedule callback at nextTimeUs
+ if (DEBUG) Log.d(TAG, "scheduling for " + nextTimeUs + " and " + nowUs);
+ scheduleNotification(NOTIFY_TIME, nextTimeUs - nowUs);
+ } else {
+ mEventHandler.removeMessages(NOTIFY);
+ // no more callbacks
+ }
+
+ for (MediaTimeProvider.OnMediaTimeListener listener: activatedListeners) {
+ listener.onTimedEvent(nowUs);
+ }
+ }
+
+ private long getEstimatedTime(long nanoTime, boolean monotonic) {
+ if (mPaused) {
+ mLastReportedTime = mLastTimeUs + mTimeAdjustment;
+ } else {
+ long timeSinceRead = (nanoTime - mLastNanoTime) / 1000;
+ mLastReportedTime = mLastTimeUs + timeSinceRead;
+ if (mTimeAdjustment > 0) {
+ long adjustment =
+ mTimeAdjustment - timeSinceRead / TIME_ADJUSTMENT_RATE;
+ if (adjustment <= 0) {
+ mTimeAdjustment = 0;
+ } else {
+ mLastReportedTime += adjustment;
+ }
+ }
+ }
+ return mLastReportedTime;
+ }
+
+ public long getCurrentTimeUs(boolean refreshTime, boolean monotonic)
+ throws IllegalStateException {
+ synchronized (this) {
+ // we always refresh the time when the paused-state changes, because
+ // we expect to have received the pause-change event delayed.
+ if (mPaused && !refreshTime) {
+ return mLastReportedTime;
+ }
+
+ long nanoTime = System.nanoTime();
+ if (refreshTime ||
+ nanoTime >= mLastNanoTime + MAX_NS_WITHOUT_POSITION_CHECK) {
+ try {
+ mLastTimeUs = mPlayer.getCurrentPosition() * 1000;
+ mPaused = !mPlayer.isPlaying();
+ if (DEBUG) Log.v(TAG, (mPaused ? "paused" : "playing") + " at " + mLastTimeUs);
+ } catch (IllegalStateException e) {
+ if (mPausing) {
+ // if we were pausing, get last estimated timestamp
+ mPausing = false;
+ getEstimatedTime(nanoTime, monotonic);
+ mPaused = true;
+ if (DEBUG) Log.d(TAG, "illegal state, but pausing: estimating at " + mLastReportedTime);
+ return mLastReportedTime;
+ }
+ // TODO get time when prepared
+ throw e;
+ }
+ mLastNanoTime = nanoTime;
+ if (monotonic && mLastTimeUs < mLastReportedTime) {
+ /* have to adjust time */
+ mTimeAdjustment = mLastReportedTime - mLastTimeUs;
+ } else {
+ mTimeAdjustment = 0;
+ }
+ }
+
+ return getEstimatedTime(nanoTime, monotonic);
+ }
+ }
+
+ private class EventHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == NOTIFY) {
+ switch (msg.arg1) {
+ case NOTIFY_TIME:
+ notifyTimedEvent(false /* refreshTime */);
+ break;
+ case REFRESH_AND_NOTIFY_TIME:
+ notifyTimedEvent(true /* refreshTime */);
+ break;
+ case NOTIFY_STOP:
+ notifyStop();
+ break;
+ case NOTIFY_SEEK:
+ notifySeek();
+ break;
+ }
+ }
+ }
+ }
+
+ /** @hide */
+ public Handler getHandler() {
+ return mEventHandler;
+ }
+ }
}
diff --git a/media/java/android/media/WebVttRenderer.java b/media/java/android/media/WebVttRenderer.java
new file mode 100644
index 0000000..527c57f
--- /dev/null
+++ b/media/java/android/media/WebVttRenderer.java
@@ -0,0 +1,1094 @@
+package android.media;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.TextView;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+/** @hide */
+public class WebVttRenderer extends SubtitleController.Renderer {
+ private TextView mMyTextView;
+
+ public WebVttRenderer(Context context, AttributeSet attrs) {
+ mMyTextView = new WebVttView(context, attrs);
+ }
+
+ @Override
+ public boolean supports(MediaFormat format) {
+ if (format.containsKey(MediaFormat.KEY_MIME)) {
+ return format.getString(MediaFormat.KEY_MIME).equals("text/vtt");
+ }
+ return false;
+ }
+
+ @Override
+ public SubtitleTrack createTrack(MediaFormat format) {
+ return new WebVttTrack(format, mMyTextView);
+ }
+}
+
+/** @hide */
+class WebVttView extends TextView {
+ public WebVttView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setTextColor(0xffffff00);
+ setTextSize(46);
+ setTextAlignment(TextView.TEXT_ALIGNMENT_CENTER);
+ setLayoutParams(new LayoutParams(
+ LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
+ }
+}
+
+/** @hide */
+class TextTrackCueSpan {
+ long mTimestampMs;
+ boolean mEnabled;
+ String mText;
+ TextTrackCueSpan(String text, long timestamp) {
+ mTimestampMs = timestamp;
+ mText = text;
+ // spans with timestamp will be enabled by Cue.onTime
+ mEnabled = (mTimestampMs < 0);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof TextTrackCueSpan)) {
+ return false;
+ }
+ TextTrackCueSpan span = (TextTrackCueSpan) o;
+ return mTimestampMs == span.mTimestampMs &&
+ mText.equals(span.mText);
+ }
+}
+
+/**
+ * @hide
+ *
+ * Extract all text without style, but with timestamp spans.
+ */
+class UnstyledTextExtractor implements Tokenizer.OnTokenListener {
+ StringBuilder mLine = new StringBuilder();
+ Vector<TextTrackCueSpan[]> mLines = new Vector<TextTrackCueSpan[]>();
+ Vector<TextTrackCueSpan> mCurrentLine = new Vector<TextTrackCueSpan>();
+ long mLastTimestamp;
+
+ UnstyledTextExtractor() {
+ init();
+ }
+
+ private void init() {
+ mLine.delete(0, mLine.length());
+ mLines.clear();
+ mCurrentLine.clear();
+ mLastTimestamp = -1;
+ }
+
+ @Override
+ public void onData(String s) {
+ mLine.append(s);
+ }
+
+ @Override
+ public void onStart(String tag, String[] classes, String annotation) { }
+
+ @Override
+ public void onEnd(String tag) { }
+
+ @Override
+ public void onTimeStamp(long timestampMs) {
+ // finish any prior span
+ if (mLine.length() > 0 && timestampMs != mLastTimestamp) {
+ mCurrentLine.add(
+ new TextTrackCueSpan(mLine.toString(), mLastTimestamp));
+ mLine.delete(0, mLine.length());
+ }
+ mLastTimestamp = timestampMs;
+ }
+
+ @Override
+ public void onLineEnd() {
+ // finish any pending span
+ if (mLine.length() > 0) {
+ mCurrentLine.add(
+ new TextTrackCueSpan(mLine.toString(), mLastTimestamp));
+ mLine.delete(0, mLine.length());
+ }
+
+ TextTrackCueSpan[] spans = new TextTrackCueSpan[mCurrentLine.size()];
+ mCurrentLine.toArray(spans);
+ mCurrentLine.clear();
+ mLines.add(spans);
+ }
+
+ public TextTrackCueSpan[][] getText() {
+ // for politeness, finish last cue-line if it ends abruptly
+ if (mLine.length() > 0 || mCurrentLine.size() > 0) {
+ onLineEnd();
+ }
+ TextTrackCueSpan[][] lines = new TextTrackCueSpan[mLines.size()][];
+ mLines.toArray(lines);
+ init();
+ return lines;
+ }
+}
+
+/**
+ * @hide
+ *
+ * Tokenizer tokenizes the WebVTT Cue Text into tags and data
+ */
+class Tokenizer {
+ private static final String TAG = "Tokenizer";
+ private TokenizerPhase mPhase;
+ private TokenizerPhase mDataTokenizer;
+ private TokenizerPhase mTagTokenizer;
+
+ private OnTokenListener mListener;
+ private String mLine;
+ private int mHandledLen;
+
+ interface TokenizerPhase {
+ TokenizerPhase start();
+ void tokenize();
+ }
+
+ class DataTokenizer implements TokenizerPhase {
+ // includes both WebVTT data && escape state
+ private StringBuilder mData;
+
+ public TokenizerPhase start() {
+ mData = new StringBuilder();
+ return this;
+ }
+
+ private boolean replaceEscape(String escape, String replacement, int pos) {
+ if (mLine.startsWith(escape, pos)) {
+ mData.append(mLine.substring(mHandledLen, pos));
+ mData.append(replacement);
+ mHandledLen = pos + escape.length();
+ pos = mHandledLen - 1;
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void tokenize() {
+ int end = mLine.length();
+ for (int pos = mHandledLen; pos < mLine.length(); pos++) {
+ if (mLine.charAt(pos) == '&') {
+ if (replaceEscape("&amp;", "&", pos) ||
+ replaceEscape("&lt;", "<", pos) ||
+ replaceEscape("&gt;", ">", pos) ||
+ replaceEscape("&lrm;", "\u200e", pos) ||
+ replaceEscape("&rlm;", "\u200f", pos) ||
+ replaceEscape("&nbsp;", "\u00a0", pos)) {
+ continue;
+ }
+ } else if (mLine.charAt(pos) == '<') {
+ end = pos;
+ mPhase = mTagTokenizer.start();
+ break;
+ }
+ }
+ mData.append(mLine.substring(mHandledLen, end));
+ // yield mData
+ mListener.onData(mData.toString());
+ mData.delete(0, mData.length());
+ mHandledLen = end;
+ }
+ }
+
+ class TagTokenizer implements TokenizerPhase {
+ private boolean mAtAnnotation;
+ private String mName, mAnnotation;
+
+ public TokenizerPhase start() {
+ mName = mAnnotation = "";
+ mAtAnnotation = false;
+ return this;
+ }
+
+ @Override
+ public void tokenize() {
+ if (!mAtAnnotation)
+ mHandledLen++;
+ if (mHandledLen < mLine.length()) {
+ String[] parts;
+ /**
+ * Collect annotations and end-tags to closing >. Collect tag
+ * name to closing bracket or next white-space.
+ */
+ if (mAtAnnotation || mLine.charAt(mHandledLen) == '/') {
+ parts = mLine.substring(mHandledLen).split(">");
+ } else {
+ parts = mLine.substring(mHandledLen).split("[\t\f >]");
+ }
+ String part = mLine.substring(
+ mHandledLen, mHandledLen + parts[0].length());
+ mHandledLen += parts[0].length();
+
+ if (mAtAnnotation) {
+ mAnnotation += " " + part;
+ } else {
+ mName = part;
+ }
+ }
+
+ mAtAnnotation = true;
+
+ if (mHandledLen < mLine.length() && mLine.charAt(mHandledLen) == '>') {
+ yield_tag();
+ mPhase = mDataTokenizer.start();
+ mHandledLen++;
+ }
+ }
+
+ private void yield_tag() {
+ if (mName.startsWith("/")) {
+ mListener.onEnd(mName.substring(1));
+ } else if (mName.length() > 0 && Character.isDigit(mName.charAt(0))) {
+ // timestamp
+ try {
+ long timestampMs = WebVttParser.parseTimestampMs(mName);
+ mListener.onTimeStamp(timestampMs);
+ } catch (NumberFormatException e) {
+ Log.d(TAG, "invalid timestamp tag: <" + mName + ">");
+ }
+ } else {
+ mAnnotation = mAnnotation.replaceAll("\\s+", " ");
+ if (mAnnotation.startsWith(" ")) {
+ mAnnotation = mAnnotation.substring(1);
+ }
+ if (mAnnotation.endsWith(" ")) {
+ mAnnotation = mAnnotation.substring(0, mAnnotation.length() - 1);
+ }
+
+ String[] classes = null;
+ int dotAt = mName.indexOf('.');
+ if (dotAt >= 0) {
+ classes = mName.substring(dotAt + 1).split("\\.");
+ mName = mName.substring(0, dotAt);
+ }
+ mListener.onStart(mName, classes, mAnnotation);
+ }
+ }
+ }
+
+ Tokenizer(OnTokenListener listener) {
+ mDataTokenizer = new DataTokenizer();
+ mTagTokenizer = new TagTokenizer();
+ reset();
+ mListener = listener;
+ }
+
+ void reset() {
+ mPhase = mDataTokenizer.start();
+ }
+
+ void tokenize(String s) {
+ mHandledLen = 0;
+ mLine = s;
+ while (mHandledLen < mLine.length()) {
+ mPhase.tokenize();
+ }
+ /* we are finished with a line unless we are in the middle of a tag */
+ if (!(mPhase instanceof TagTokenizer)) {
+ // yield END-OF-LINE
+ mListener.onLineEnd();
+ }
+ }
+
+ interface OnTokenListener {
+ void onData(String s);
+ void onStart(String tag, String[] classes, String annotation);
+ void onEnd(String tag);
+ void onTimeStamp(long timestampMs);
+ void onLineEnd();
+ }
+}
+
+/** @hide */
+class TextTrackRegion {
+ final static int SCROLL_VALUE_NONE = 300;
+ final static int SCROLL_VALUE_SCROLL_UP = 301;
+
+ String mId;
+ float mWidth;
+ int mLines;
+ float mAnchorPointX, mAnchorPointY;
+ float mViewportAnchorPointX, mViewportAnchorPointY;
+ int mScrollValue;
+
+ TextTrackRegion() {
+ mId = "";
+ mWidth = 100;
+ mLines = 3;
+ mAnchorPointX = mViewportAnchorPointX = 0.f;
+ mAnchorPointY = mViewportAnchorPointY = 100.f;
+ mScrollValue = SCROLL_VALUE_NONE;
+ }
+
+ public String toString() {
+ StringBuilder res = new StringBuilder(" {id:\"").append(mId)
+ .append("\", width:").append(mWidth)
+ .append(", lines:").append(mLines)
+ .append(", anchorPoint:(").append(mAnchorPointX)
+ .append(", ").append(mAnchorPointY)
+ .append("), viewportAnchorPoints:").append(mViewportAnchorPointX)
+ .append(", ").append(mViewportAnchorPointY)
+ .append("), scrollValue:")
+ .append(mScrollValue == SCROLL_VALUE_NONE ? "none" :
+ mScrollValue == SCROLL_VALUE_SCROLL_UP ? "scroll_up" :
+ "INVALID")
+ .append("}");
+ return res.toString();
+ }
+}
+
+/** @hide */
+class TextTrackCue extends SubtitleTrack.Cue {
+ final static int WRITING_DIRECTION_HORIZONTAL = 100;
+ final static int WRITING_DIRECTION_VERTICAL_RL = 101;
+ final static int WRITING_DIRECTION_VERTICAL_LR = 102;
+
+ final static int ALIGNMENT_MIDDLE = 200;
+ final static int ALIGNMENT_START = 201;
+ final static int ALIGNMENT_END = 202;
+ final static int ALIGNMENT_LEFT = 203;
+ final static int ALIGNMENT_RIGHT = 204;
+ private static final String TAG = "TTCue";
+
+ String mId;
+ boolean mPauseOnExit;
+ int mWritingDirection;
+ String mRegionId;
+ boolean mSnapToLines;
+ Integer mLinePosition; // null means AUTO
+ boolean mAutoLinePosition;
+ int mTextPosition;
+ int mSize;
+ int mAlignment;
+ // Vector<String> mText;
+ String[] mStrings;
+ TextTrackCueSpan[][] mLines;
+ TextTrackRegion mRegion;
+
+ TextTrackCue() {
+ mId = "";
+ mPauseOnExit = false;
+ mWritingDirection = WRITING_DIRECTION_HORIZONTAL;
+ mRegionId = "";
+ mSnapToLines = true;
+ mLinePosition = null /* AUTO */;
+ mTextPosition = 50;
+ mSize = 100;
+ mAlignment = ALIGNMENT_MIDDLE;
+ mLines = null;
+ mRegion = null;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof TextTrackCue)) {
+ return false;
+ }
+ if (this == o) {
+ return true;
+ }
+
+ try {
+ TextTrackCue cue = (TextTrackCue) o;
+ boolean res = mId.equals(cue.mId) &&
+ mPauseOnExit == cue.mPauseOnExit &&
+ mWritingDirection == cue.mWritingDirection &&
+ mRegionId.equals(cue.mRegionId) &&
+ mSnapToLines == cue.mSnapToLines &&
+ mAutoLinePosition == cue.mAutoLinePosition &&
+ (mAutoLinePosition || mLinePosition == cue.mLinePosition) &&
+ mTextPosition == cue.mTextPosition &&
+ mSize == cue.mSize &&
+ mAlignment == cue.mAlignment &&
+ mLines.length == cue.mLines.length;
+ if (res == true) {
+ for (int line = 0; line < mLines.length; line++) {
+ if (!Arrays.equals(mLines[line], cue.mLines[line])) {
+ return false;
+ }
+ }
+ }
+ return res;
+ } catch(IncompatibleClassChangeError e) {
+ return false;
+ }
+ }
+
+ public StringBuilder appendStringsToBuilder(StringBuilder builder) {
+ if (mStrings == null) {
+ builder.append("null");
+ } else {
+ builder.append("[");
+ boolean first = true;
+ for (String s: mStrings) {
+ if (!first) {
+ builder.append(", ");
+ }
+ if (s == null) {
+ builder.append("null");
+ } else {
+ builder.append("\"");
+ builder.append(s);
+ builder.append("\"");
+ }
+ first = false;
+ }
+ builder.append("]");
+ }
+ return builder;
+ }
+
+ public StringBuilder appendLinesToBuilder(StringBuilder builder) {
+ if (mLines == null) {
+ builder.append("null");
+ } else {
+ builder.append("[");
+ boolean first = true;
+ for (TextTrackCueSpan[] spans: mLines) {
+ if (!first) {
+ builder.append(", ");
+ }
+ if (spans == null) {
+ builder.append("null");
+ } else {
+ builder.append("\"");
+ boolean innerFirst = true;
+ long lastTimestamp = -1;
+ for (TextTrackCueSpan span: spans) {
+ if (!innerFirst) {
+ builder.append(" ");
+ }
+ if (span.mTimestampMs != lastTimestamp) {
+ builder.append("<")
+ .append(WebVttParser.timeToString(
+ span.mTimestampMs))
+ .append(">");
+ lastTimestamp = span.mTimestampMs;
+ }
+ builder.append(span.mText);
+ innerFirst = false;
+ }
+ builder.append("\"");
+ }
+ first = false;
+ }
+ builder.append("]");
+ }
+ return builder;
+ }
+
+ public String toString() {
+ StringBuilder res = new StringBuilder();
+
+ res.append(WebVttParser.timeToString(mStartTimeMs))
+ .append(" --> ").append(WebVttParser.timeToString(mEndTimeMs))
+ .append(" {id:\"").append(mId)
+ .append("\", pauseOnExit:").append(mPauseOnExit)
+ .append(", direction:")
+ .append(mWritingDirection == WRITING_DIRECTION_HORIZONTAL ? "horizontal" :
+ mWritingDirection == WRITING_DIRECTION_VERTICAL_LR ? "vertical_lr" :
+ mWritingDirection == WRITING_DIRECTION_VERTICAL_RL ? "vertical_rl" :
+ "INVALID")
+ .append(", regionId:\"").append(mRegionId)
+ .append("\", snapToLines:").append(mSnapToLines)
+ .append(", linePosition:").append(mAutoLinePosition ? "auto" :
+ mLinePosition)
+ .append(", textPosition:").append(mTextPosition)
+ .append(", size:").append(mSize)
+ .append(", alignment:")
+ .append(mAlignment == ALIGNMENT_END ? "end" :
+ mAlignment == ALIGNMENT_LEFT ? "left" :
+ mAlignment == ALIGNMENT_MIDDLE ? "middle" :
+ mAlignment == ALIGNMENT_RIGHT ? "right" :
+ mAlignment == ALIGNMENT_START ? "start" : "INVALID")
+ .append(", text:");
+ appendStringsToBuilder(res).append("}");
+ return res.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return toString().hashCode();
+ }
+
+ @Override
+ public void onTime(long timeMs) {
+ for (TextTrackCueSpan[] line: mLines) {
+ for (TextTrackCueSpan span: line) {
+ span.mEnabled = timeMs >= span.mTimestampMs;
+ }
+ }
+ }
+}
+
+/** @hide */
+class WebVttParser {
+ private static final String TAG = "WebVttParser";
+ private Phase mPhase;
+ private TextTrackCue mCue;
+ private Vector<String> mCueTexts;
+ private WebVttCueListener mListener;
+ private String mBuffer;
+
+ WebVttParser(WebVttCueListener listener) {
+ mPhase = mParseStart;
+ mBuffer = ""; /* mBuffer contains up to 1 incomplete line */
+ mListener = listener;
+ mCueTexts = new Vector<String>();
+ }
+
+ /* parsePercentageString */
+ public static float parseFloatPercentage(String s)
+ throws NumberFormatException {
+ if (!s.endsWith("%")) {
+ throw new NumberFormatException("does not end in %");
+ }
+ s = s.substring(0, s.length() - 1);
+ // parseFloat allows an exponent or a sign
+ if (s.matches(".*[^0-9.].*")) {
+ throw new NumberFormatException("contains an invalid character");
+ }
+
+ try {
+ float value = Float.parseFloat(s);
+ if (value < 0.0f || value > 100.0f) {
+ throw new NumberFormatException("is out of range");
+ }
+ return value;
+ } catch (NumberFormatException e) {
+ throw new NumberFormatException("is not a number");
+ }
+ }
+
+ public static int parseIntPercentage(String s) throws NumberFormatException {
+ if (!s.endsWith("%")) {
+ throw new NumberFormatException("does not end in %");
+ }
+ s = s.substring(0, s.length() - 1);
+ // parseInt allows "-0" that returns 0, so check for non-digits
+ if (s.matches(".*[^0-9].*")) {
+ throw new NumberFormatException("contains an invalid character");
+ }
+
+ try {
+ int value = Integer.parseInt(s);
+ if (value < 0 || value > 100) {
+ throw new NumberFormatException("is out of range");
+ }
+ return value;
+ } catch (NumberFormatException e) {
+ throw new NumberFormatException("is not a number");
+ }
+ }
+
+ public static long parseTimestampMs(String s) throws NumberFormatException {
+ if (!s.matches("(\\d+:)?[0-5]\\d:[0-5]\\d\\.\\d{3}")) {
+ throw new NumberFormatException("has invalid format");
+ }
+
+ String[] parts = s.split("\\.", 2);
+ long value = 0;
+ for (String group: parts[0].split(":")) {
+ value = value * 60 + Long.parseLong(group);
+ }
+ return value * 1000 + Long.parseLong(parts[1]);
+ }
+
+ public static String timeToString(long timeMs) {
+ return String.format("%d:%02d:%02d.%03d",
+ timeMs / 3600000, (timeMs / 60000) % 60,
+ (timeMs / 1000) % 60, timeMs % 1000);
+ }
+
+ public void parse(String s) {
+ boolean trailingCR = false;
+ mBuffer = (mBuffer + s.replace("\0", "\ufffd")).replace("\r\n", "\n");
+
+ /* keep trailing '\r' in case matching '\n' arrives in next packet */
+ if (mBuffer.endsWith("\r")) {
+ trailingCR = true;
+ mBuffer = mBuffer.substring(0, mBuffer.length() - 1);
+ }
+
+ String[] lines = mBuffer.split("[\r\n]");
+ for (int i = 0; i < lines.length - 1; i++) {
+ mPhase.parse(lines[i]);
+ }
+
+ mBuffer = lines[lines.length - 1];
+ if (trailingCR)
+ mBuffer += "\r";
+ }
+
+ public void eos() {
+ if (mBuffer.endsWith("\r")) {
+ mBuffer = mBuffer.substring(0, mBuffer.length() - 1);
+ }
+
+ mPhase.parse(mBuffer);
+ mBuffer = "";
+
+ yieldCue();
+ mPhase = mParseStart;
+ }
+
+ public void yieldCue() {
+ if (mCue != null && mCueTexts.size() > 0) {
+ mCue.mStrings = new String[mCueTexts.size()];
+ mCueTexts.toArray(mCue.mStrings);
+ mCueTexts.clear();
+ mListener.onCueParsed(mCue);
+ }
+ mCue = null;
+ }
+
+ interface Phase {
+ void parse(String line);
+ }
+
+ final private Phase mSkipRest = new Phase() {
+ @Override
+ public void parse(String line) { }
+ };
+
+ final private Phase mParseStart = new Phase() { // 5-9
+ @Override
+ public void parse(String line) {
+ if (!line.equals("WEBVTT") &&
+ !line.startsWith("WEBVTT ") &&
+ !line.startsWith("WEBVTT\t")) {
+ log_warning("Not a WEBVTT header", line);
+ mPhase = mSkipRest;
+ } else {
+ mPhase = mParseHeader;
+ }
+ }
+ };
+
+ final private Phase mParseHeader = new Phase() { // 10-13
+ TextTrackRegion parseRegion(String s) {
+ TextTrackRegion region = new TextTrackRegion();
+ for (String setting: s.split(" +")) {
+ int equalAt = setting.indexOf('=');
+ if (equalAt <= 0 || equalAt == setting.length() - 1) {
+ continue;
+ }
+
+ String name = setting.substring(0, equalAt);
+ String value = setting.substring(equalAt + 1);
+ if (name.equals("id")) {
+ region.mId = value;
+ } else if (name.equals("width")) {
+ try {
+ region.mWidth = parseFloatPercentage(value);
+ } catch (NumberFormatException e) {
+ log_warning("region setting", name,
+ "has invalid value", e.getMessage(), value);
+ }
+ } else if (name.equals("lines")) {
+ try {
+ int lines = Integer.parseInt(value);
+ if (lines >= 0) {
+ region.mLines = lines;
+ } else {
+ log_warning("region setting", name, "is negative", value);
+ }
+ } catch (NumberFormatException e) {
+ log_warning("region setting", name, "is not numeric", value);
+ }
+ } else if (name.equals("regionanchor") ||
+ name.equals("viewportanchor")) {
+ int commaAt = value.indexOf(",");
+ if (commaAt < 0) {
+ log_warning("region setting", name, "contains no comma", value);
+ continue;
+ }
+
+ String anchorX = value.substring(0, commaAt);
+ String anchorY = value.substring(commaAt + 1);
+ float x, y;
+
+ try {
+ x = parseFloatPercentage(anchorX);
+ } catch (NumberFormatException e) {
+ log_warning("region setting", name,
+ "has invalid x component", e.getMessage(), anchorX);
+ continue;
+ }
+ try {
+ y = parseFloatPercentage(anchorY);
+ } catch (NumberFormatException e) {
+ log_warning("region setting", name,
+ "has invalid y component", e.getMessage(), anchorY);
+ continue;
+ }
+
+ if (name.charAt(0) == 'r') {
+ region.mAnchorPointX = x;
+ region.mAnchorPointY = y;
+ } else {
+ region.mViewportAnchorPointX = x;
+ region.mViewportAnchorPointY = y;
+ }
+ } else if (name.equals("scroll")) {
+ if (value.equals("up")) {
+ region.mScrollValue =
+ TextTrackRegion.SCROLL_VALUE_SCROLL_UP;
+ } else {
+ log_warning("region setting", name, "has invalid value", value);
+ }
+ }
+ }
+ return region;
+ }
+
+ @Override
+ public void parse(String line) {
+ if (line.length() == 0) {
+ mPhase = mParseCueId;
+ } else if (line.contains("-->")) {
+ mPhase = mParseCueTime;
+ mPhase.parse(line);
+ } else {
+ int colonAt = line.indexOf(':');
+ if (colonAt <= 0 || colonAt >= line.length() - 1) {
+ log_warning("meta data header has invalid format", line);
+ }
+ String name = line.substring(0, colonAt);
+ String value = line.substring(colonAt + 1);
+
+ if (name.equals("Region")) {
+ TextTrackRegion region = parseRegion(value);
+ mListener.onRegionParsed(region);
+ }
+ }
+ }
+ };
+
+ final private Phase mParseCueId = new Phase() {
+ @Override
+ public void parse(String line) {
+ if (line.length() == 0) {
+ return;
+ }
+
+ assert(mCue == null);
+
+ if (line.equals("NOTE") || line.startsWith("NOTE ")) {
+ mPhase = mParseCueText;
+ }
+
+ mCue = new TextTrackCue();
+ mCueTexts.clear();
+
+ mPhase = mParseCueTime;
+ if (line.contains("-->")) {
+ mPhase.parse(line);
+ } else {
+ mCue.mId = line;
+ }
+ }
+ };
+
+ final private Phase mParseCueTime = new Phase() {
+ @Override
+ public void parse(String line) {
+ int arrowAt = line.indexOf("-->");
+ if (arrowAt < 0) {
+ mCue = null;
+ mPhase = mParseCueId;
+ return;
+ }
+
+ String start = line.substring(0, arrowAt).trim();
+ // convert only initial and first other white-space to space
+ String rest = line.substring(arrowAt + 3)
+ .replaceFirst("^\\s+", "").replaceFirst("\\s+", " ");
+ int spaceAt = rest.indexOf(' ');
+ String end = spaceAt > 0 ? rest.substring(0, spaceAt) : rest;
+ rest = spaceAt > 0 ? rest.substring(spaceAt + 1) : "";
+
+ mCue.mStartTimeMs = parseTimestampMs(start);
+ mCue.mEndTimeMs = parseTimestampMs(end);
+ for (String setting: rest.split(" +")) {
+ int colonAt = setting.indexOf(':');
+ if (colonAt <= 0 || colonAt == setting.length() - 1) {
+ continue;
+ }
+ String name = setting.substring(0, colonAt);
+ String value = setting.substring(colonAt + 1);
+
+ if (name.equals("region")) {
+ mCue.mRegionId = value;
+ } else if (name.equals("vertical")) {
+ if (value.equals("rl")) {
+ mCue.mWritingDirection =
+ TextTrackCue.WRITING_DIRECTION_VERTICAL_RL;
+ } else if (value.equals("lr")) {
+ mCue.mWritingDirection =
+ TextTrackCue.WRITING_DIRECTION_VERTICAL_LR;
+ } else {
+ log_warning("cue setting", name, "has invalid value", value);
+ }
+ } else if (name.equals("line")) {
+ try {
+ int linePosition;
+ /* TRICKY: we know that there are no spaces in value */
+ assert(value.indexOf(' ') < 0);
+ if (value.endsWith("%")) {
+ linePosition = Integer.parseInt(
+ value.substring(0, value.length() - 1));
+ if (linePosition < 0 || linePosition > 100) {
+ log_warning("cue setting", name, "is out of range", value);
+ continue;
+ }
+ mCue.mSnapToLines = false;
+ mCue.mLinePosition = linePosition;
+ } else {
+ mCue.mSnapToLines = true;
+ mCue.mLinePosition = Integer.parseInt(value);
+ }
+ } catch (NumberFormatException e) {
+ log_warning("cue setting", name,
+ "is not numeric or percentage", value);
+ }
+ } else if (name.equals("position")) {
+ try {
+ mCue.mTextPosition = parseIntPercentage(value);
+ } catch (NumberFormatException e) {
+ log_warning("cue setting", name,
+ "is not numeric or percentage", value);
+ }
+ } else if (name.equals("size")) {
+ try {
+ mCue.mSize = parseIntPercentage(value);
+ } catch (NumberFormatException e) {
+ log_warning("cue setting", name,
+ "is not numeric or percentage", value);
+ }
+ } else if (name.equals("align")) {
+ if (value.equals("start")) {
+ mCue.mAlignment = TextTrackCue.ALIGNMENT_START;
+ } else if (value.equals("middle")) {
+ mCue.mAlignment = TextTrackCue.ALIGNMENT_MIDDLE;
+ } else if (value.equals("end")) {
+ mCue.mAlignment = TextTrackCue.ALIGNMENT_END;
+ } else if (value.equals("left")) {
+ mCue.mAlignment = TextTrackCue.ALIGNMENT_LEFT;
+ } else if (value.equals("right")) {
+ mCue.mAlignment = TextTrackCue.ALIGNMENT_RIGHT;
+ } else {
+ log_warning("cue setting", name, "has invalid value", value);
+ continue;
+ }
+ }
+ }
+
+ if (mCue.mLinePosition != null ||
+ mCue.mSize != 100 ||
+ (mCue.mWritingDirection !=
+ TextTrackCue.WRITING_DIRECTION_HORIZONTAL)) {
+ mCue.mRegionId = "";
+ }
+
+ mPhase = mParseCueText;
+ }
+ };
+
+ /* also used for notes */
+ final private Phase mParseCueText = new Phase() {
+ @Override
+ public void parse(String line) {
+ if (line.length() == 0) {
+ yieldCue();
+ mPhase = mParseCueId;
+ return;
+ } else if (mCue != null) {
+ mCueTexts.add(line);
+ }
+ }
+ };
+
+ private void log_warning(
+ String nameType, String name, String message,
+ String subMessage, String value) {
+ Log.w(this.getClass().getName(), nameType + " '" + name + "' " +
+ message + " ('" + value + "' " + subMessage + ")");
+ }
+
+ private void log_warning(
+ String nameType, String name, String message, String value) {
+ Log.w(this.getClass().getName(), nameType + " '" + name + "' " +
+ message + " ('" + value + "')");
+ }
+
+ private void log_warning(String message, String value) {
+ Log.w(this.getClass().getName(), message + " ('" + value + "')");
+ }
+}
+
+/** @hide */
+interface WebVttCueListener {
+ void onCueParsed(TextTrackCue cue);
+ void onRegionParsed(TextTrackRegion region);
+}
+
+/** @hide */
+class WebVttTrack extends SubtitleTrack implements WebVttCueListener {
+ private static final String TAG = "WebVttTrack";
+
+ private final TextView mTextView;
+
+ private final WebVttParser mParser = new WebVttParser(this);
+ private final UnstyledTextExtractor mExtractor =
+ new UnstyledTextExtractor();
+ private final Tokenizer mTokenizer = new Tokenizer(mExtractor);
+ private final Vector<Long> mTimestamps = new Vector<Long>();
+
+ private final Map<String, TextTrackRegion> mRegions =
+ new HashMap<String, TextTrackRegion>();
+ private Long mCurrentRunID;
+
+ WebVttTrack(MediaFormat format, TextView textView) {
+ super(format);
+ mTextView = textView;
+ }
+
+ @Override
+ public View getView() {
+ return mTextView;
+ }
+
+ @Override
+ public void onData(String data, boolean eos, long runID) {
+ // implement intermixing restriction for WebVTT only for now
+ synchronized(mParser) {
+ if (mCurrentRunID != null && runID != mCurrentRunID) {
+ throw new IllegalStateException(
+ "Run #" + mCurrentRunID +
+ " in progress. Cannot process run #" + runID);
+ }
+ mCurrentRunID = runID;
+ mParser.parse(data);
+ if (eos) {
+ finishedRun(runID);
+ mParser.eos();
+ mRegions.clear();
+ mCurrentRunID = null;
+ }
+ }
+ }
+
+ @Override
+ public void onCueParsed(TextTrackCue cue) {
+ synchronized (mParser) {
+ // resolve region
+ if (cue.mRegionId.length() != 0) {
+ cue.mRegion = mRegions.get(cue.mRegionId);
+ }
+
+ if (DEBUG) Log.v(TAG, "adding cue " + cue);
+
+ // tokenize text track string-lines into lines of spans
+ mTokenizer.reset();
+ for (String s: cue.mStrings) {
+ mTokenizer.tokenize(s);
+ }
+ cue.mLines = mExtractor.getText();
+ if (DEBUG) Log.v(TAG, cue.appendLinesToBuilder(
+ cue.appendStringsToBuilder(
+ new StringBuilder()).append(" simplified to: "))
+ .toString());
+
+ // extract inner timestamps
+ for (TextTrackCueSpan[] line: cue.mLines) {
+ for (TextTrackCueSpan span: line) {
+ if (span.mTimestampMs > cue.mStartTimeMs &&
+ span.mTimestampMs < cue.mEndTimeMs &&
+ !mTimestamps.contains(span.mTimestampMs)) {
+ mTimestamps.add(span.mTimestampMs);
+ }
+ }
+ }
+
+ if (mTimestamps.size() > 0) {
+ cue.mInnerTimesMs = new long[mTimestamps.size()];
+ for (int ix=0; ix < mTimestamps.size(); ++ix) {
+ cue.mInnerTimesMs[ix] = mTimestamps.get(ix);
+ }
+ mTimestamps.clear();
+ } else {
+ cue.mInnerTimesMs = null;
+ }
+
+ cue.mRunID = mCurrentRunID;
+ }
+
+ addCue(cue);
+ }
+
+ @Override
+ public void onRegionParsed(TextTrackRegion region) {
+ synchronized(mParser) {
+ mRegions.put(region.mId, region);
+ }
+ }
+
+ public void updateView(Vector<SubtitleTrack.Cue> activeCues) {
+ if (!mVisible) {
+ // don't keep the state if we are not visible
+ return;
+ }
+
+ if (DEBUG && mTimeProvider != null) {
+ try {
+ Log.d(TAG, "at " +
+ (mTimeProvider.getCurrentTimeUs(false, true) / 1000) +
+ " ms the active cues are:");
+ } catch (IllegalStateException e) {
+ Log.d(TAG, "at (illegal state) the active cues are:");
+ }
+ }
+ StringBuilder text = new StringBuilder();
+ StringBuilder lineBuilder = new StringBuilder();
+ for (Cue o: activeCues) {
+ TextTrackCue cue = (TextTrackCue)o;
+ if (DEBUG) Log.d(TAG, cue.toString());
+ for (TextTrackCueSpan[] line: cue.mLines) {
+ for (TextTrackCueSpan span: line) {
+ if (!span.mEnabled) {
+ continue;
+ }
+ lineBuilder.append(span.mText);
+ }
+ if (lineBuilder.length() > 0) {
+ text.append(lineBuilder.toString()).append("\n");
+ lineBuilder.delete(0, lineBuilder.length());
+ }
+ }
+ }
+
+ if (mTextView != null) {
+ if (DEBUG) Log.d(TAG, "updating to " + text.toString());
+ mTextView.setText(text.toString());
+ mTextView.postInvalidate();
+ }
+ }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
index 926719c..9621f92 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
@@ -50,12 +50,20 @@ public class RationalTest extends junit.framework.TestCase {
assertEquals(1, r.getNumerator());
assertEquals(2, r.getDenominator());
- // Dividing by zero is not allowed
- try {
- r = new Rational(1, 0);
- fail("Expected Rational constructor to throw an IllegalArgumentException");
- } catch(IllegalArgumentException e) {
- }
+ // Infinity.
+ r = new Rational(1, 0);
+ assertEquals(0, r.getNumerator());
+ assertEquals(0, r.getDenominator());
+
+ // Negative infinity.
+ r = new Rational(-1, 0);
+ assertEquals(0, r.getNumerator());
+ assertEquals(0, r.getDenominator());
+
+ // NaN.
+ r = new Rational(0, 0);
+ assertEquals(0, r.getNumerator());
+ assertEquals(0, r.getDenominator());
}
@SmallTest
@@ -110,5 +118,34 @@ public class RationalTest extends junit.framework.TestCase {
assertEquals(moreComplicated, moreComplicated2);
assertEquals(moreComplicated2, moreComplicated);
+ Rational nan = new Rational(0, 0);
+ Rational nan2 = new Rational(0, 0);
+ assertTrue(nan.equals(nan));
+ assertTrue(nan.equals(nan2));
+ assertTrue(nan2.equals(nan));
+ assertFalse(nan.equals(r));
+ assertFalse(r.equals(nan));
+
+ // Infinities of the same sign are equal.
+ Rational posInf = new Rational(1, 0);
+ Rational posInf2 = new Rational(2, 0);
+ Rational negInf = new Rational(-1, 0);
+ Rational negInf2 = new Rational(-2, 0);
+ assertEquals(posInf, posInf);
+ assertEquals(negInf, negInf);
+ assertEquals(posInf, posInf2);
+ assertEquals(negInf, negInf2);
+
+ // Infinities aren't equal to anything else.
+ assertFalse(posInf.equals(negInf));
+ assertFalse(negInf.equals(posInf));
+ assertFalse(negInf.equals(r));
+ assertFalse(posInf.equals(r));
+ assertFalse(r.equals(negInf));
+ assertFalse(r.equals(posInf));
+ assertFalse(posInf.equals(nan));
+ assertFalse(negInf.equals(nan));
+ assertFalse(nan.equals(posInf));
+ assertFalse(nan.equals(negInf));
}
-} \ No newline at end of file
+}
diff --git a/packages/InputDevices/Android.mk b/packages/InputDevices/Android.mk
index 095655c..f537022 100644
--- a/packages/InputDevices/Android.mk
+++ b/packages/InputDevices/Android.mk
@@ -30,14 +30,20 @@ include $(BUILD_PACKAGE)
# Validate all key maps.
include $(CLEAR_VARS)
-validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
-files := frameworks/base/packages/InputDevices/res/raw/*.kcm
-
LOCAL_MODULE := validate_input_devices_keymaps
-LOCAL_MODULE_TAGS := optional
-LOCAL_REQUIRED_MODULES := validatekeymaps
+intermediates := $(call intermediates-dir-for,ETC,$(LOCAL_MODULE),,COMMON)
+LOCAL_BUILT_MODULE := $(intermediates)/stamp
-validate_input_devices_keymaps: $(files)
- $(hide) $(validatekeymaps) $(files)
-
-include $(BUILD_PHONY_PACKAGE)
+validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
+input_devices_keymaps := $(wildcard $(LOCAL_PATH)/res/raw/*.kcm)
+$(LOCAL_BUILT_MODULE): PRIVATE_VALIDATEKEYMAPS := $(validatekeymaps)
+$(LOCAL_BUILT_MODULE) : $(input_devices_keymaps) | $(validatekeymaps)
+ $(hide) $(PRIVATE_VALIDATEKEYMAPS) $^
+ $(hide) mkdir -p $(dir $@) && touch $@
+
+# Run validatekeymaps unconditionally for platform build.
+droidcore all_modules : $(LOCAL_BUILT_MODULE)
+
+# Reset temp vars.
+validatekeymaps :=
+input_devices_keymaps :=
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index eedb7d0..00124b0 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -24,6 +24,7 @@ import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.AlertDialog;
+import android.app.PendingIntent;
import android.app.SearchManager;
import android.app.admin.DevicePolicyManager;
import android.appwidget.AppWidgetHost;
@@ -40,6 +41,7 @@ import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.media.RemoteControlClient;
+import android.os.Bundle;
import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
@@ -47,6 +49,9 @@ import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.speech.hotword.HotwordRecognitionListener;
+import android.speech.hotword.HotwordRecognizer;
+import android.telephony.TelephonyManager;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Slog;
@@ -63,6 +68,11 @@ import java.util.List;
public class KeyguardHostView extends KeyguardViewBase {
private static final String TAG = "KeyguardHostView";
+ // Don't enable hotword on limited-memory devices.
+ private static final boolean ENABLE_HOTWORD = !ActivityManager.isLowRamDeviceStatic();
+ // Indicates if hotword is enabled, should it also be available on secure keyguard(s).
+ private static final boolean ENABLE_HOTWORD_SECURE = false;
+
// Transport control states.
static final int TRANSPORT_GONE = 0;
static final int TRANSPORT_INVISIBLE = 1;
@@ -77,6 +87,13 @@ public class KeyguardHostView extends KeyguardViewBase {
// Found in KeyguardAppWidgetPickActivity.java
static final int APPWIDGET_HOST_ID = 0x4B455947;
+ // TODO: Fix this to be non-static.
+ // We need to be careful here to make stopRecognition calls on the same instance
+ // that started it. Since KeyguardHostView is a view, it keeps getting
+ // recreated every now and then, and unless we figure out a better way,
+ // this needs to be a static field.
+ private static HotwordRecognizer sHotwordClient;
+
private final int MAX_WIDGETS = 5;
private AppWidgetHost mAppWidgetHost;
@@ -117,6 +134,8 @@ public class KeyguardHostView extends KeyguardViewBase {
private KeyguardMultiUserSelectorView mKeyguardMultiUserSelectorView;
+ private boolean mIsScreenOn;
+
protected int mClientGeneration;
protected boolean mShowSecurityWhenReturn;
@@ -198,6 +217,11 @@ public class KeyguardHostView extends KeyguardViewBase {
if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) {
Log.v(TAG, "Keyguard secure camera disabled by DPM");
}
+
+ // Create Hotword recognizer, for the first time.
+ if (ENABLE_HOTWORD && sHotwordClient == null) {
+ sHotwordClient = HotwordRecognizer.createHotwordRecognizer(getContext());
+ }
}
private void getInitialTransportState() {
@@ -295,6 +319,21 @@ public class KeyguardHostView extends KeyguardViewBase {
}
}
}
+ @Override
+ public void onPhoneStateChanged(int phoneState) {
+ // We need to stop hotword detection when a call state is not idle anymore.
+ if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)
+ && TelephonyManager.CALL_STATE_IDLE != phoneState) {
+ if (DEBUG) Log.d(TAG, "Stopping due to call state not being idle");
+ maybeStopHotwordDetector();
+ }
+ }
+ @Override
+ public void onUserSwitching(int userId) {
+ if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
+ maybeStopHotwordDetector();
+ }
+ }
};
private static final boolean isMusicPlaying(int playbackState) {
@@ -778,6 +817,9 @@ public class KeyguardHostView extends KeyguardViewBase {
// If the alternate unlock was suppressed, it can now be safely
// enabled because the user has left keyguard.
KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
+ if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)){
+ maybeStopHotwordDetector();
+ }
// If there's a pending runnable because the user interacted with a widget
// and we're leaving keyguard, then run it.
@@ -942,6 +984,9 @@ public class KeyguardHostView extends KeyguardViewBase {
// Emulate Activity life cycle
if (oldView != null) {
+ if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
+ maybeStopHotwordDetector();
+ }
oldView.onPause();
oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
}
@@ -982,6 +1027,7 @@ public class KeyguardHostView extends KeyguardViewBase {
@Override
public void onScreenTurnedOn() {
if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
+ mIsScreenOn = true;
showPrimarySecurityScreen(false);
getSecurityView(mCurrentSecuritySelection).onResume(KeyguardSecurityView.SCREEN_ON);
@@ -993,6 +1039,12 @@ public class KeyguardHostView extends KeyguardViewBase {
if (mViewStateManager != null) {
mViewStateManager.showUsabilityHints();
}
+
+ // Start hotword detection on insecure Keyguard.
+ if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
+ maybeStartHotwordDetector();
+ }
+
requestFocus();
}
@@ -1000,6 +1052,7 @@ public class KeyguardHostView extends KeyguardViewBase {
public void onScreenTurnedOff() {
if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
+ mIsScreenOn = false;
// Once the screen turns off, we no longer consider this to be first boot and we want the
// biometric unlock to start next time keyguard is shown.
KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
@@ -1013,6 +1066,12 @@ public class KeyguardHostView extends KeyguardViewBase {
if (cameraPage != null) {
cameraPage.onScreenTurnedOff();
}
+
+ // Stop hotword detection on insecure Keyguard.
+ if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
+ maybeStopHotwordDetector();
+ }
+
clearFocus();
}
@@ -1097,6 +1156,9 @@ public class KeyguardHostView extends KeyguardViewBase {
new CameraWidgetFrame.Callbacks() {
@Override
public void onLaunchingCamera() {
+ if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
+ maybeStopHotwordDetector();
+ }
setSliderHandleAlpha(0);
}
@@ -1626,6 +1688,9 @@ public class KeyguardHostView extends KeyguardViewBase {
}
public void showAssistant() {
+ if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) {
+ maybeStopHotwordDetector();
+ }
final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
.getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
@@ -1640,4 +1705,130 @@ public class KeyguardHostView extends KeyguardViewBase {
mActivityLauncher.launchActivityWithAnimation(
intent, false, opts.toBundle(), null, null);
}
+
+
+ /**
+ * Start the hotword detector if:
+ * <li> ENABLE_HOTWORD is true and
+ * <li> Hotword detection is not already running and
+ * <li> TelephonyManager is in CALL_STATE_IDLE
+ * <li> and Screen is turned on.
+ */
+ private void maybeStartHotwordDetector() {
+ if (!ENABLE_HOTWORD) return;
+
+ if (sHotwordClient != null) {
+ if (DEBUG) Log.d(TAG, "maybeStartHotwordDetector()");
+ // Don't start hotword detection if the screen is off.
+ if (!mIsScreenOn) {
+ if (DEBUG) Log.d(TAG, "screen was off, not starting");
+ return;
+ }
+
+ KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext());
+ if (monitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE) {
+ if (DEBUG) Log.d(TAG, "Call underway, not starting");
+ return;
+ }
+
+ try {
+ sHotwordClient.startRecognition(mHotwordCallback);
+ } catch(Exception ex) {
+ // Don't allow hotword errors to make the keyguard unusable
+ Log.e(TAG, "Failed to start hotword recognition", ex);
+ sHotwordClient = null;
+ }
+ }
+ }
+
+ /**
+ * Stop hotword detector if:
+ * <li> ENABLE_HOTWORD is true
+ * <li> and hotword is running.
+ */
+ private void maybeStopHotwordDetector() {
+ if (!ENABLE_HOTWORD) return;
+
+ if (sHotwordClient != null) {
+ if (DEBUG) Log.d(TAG, "maybeStopHotwordDetector()");
+ try {
+ sHotwordClient.stopRecognition();
+ } catch(Exception ex) {
+ // Don't allow hotword errors to make the keyguard unusable
+ Log.e(TAG, "Failed to start hotword recognition", ex);
+ } finally {
+ sHotwordClient = null;
+ }
+ }
+ }
+
+ private final HotwordRecognitionListener mHotwordCallback = new HotwordRecognitionListener() {
+ private static final String TAG = "HotwordRecognitionListener";
+
+ public void onHotwordRecognitionStarted() {
+ if (DEBUG) Log.d(TAG, "onHotwordRecognitionStarted()");
+ }
+
+ public void onHotwordRecognitionStopped() {
+ if (DEBUG) Log.d(TAG, "onHotwordRecognitionStopped()");
+ }
+
+ public void onHotwordEvent(int eventType, Bundle eventBundle) {
+ if (DEBUG) Log.d(TAG, "onHotwordEvent: " + eventType);
+ if (eventType == HotwordRecognizer.EVENT_TYPE_STATE_CHANGED) {
+ if (eventBundle != null && eventBundle.containsKey(HotwordRecognizer.PROMPT_TEXT)) {
+ new KeyguardMessageArea.Helper(
+ (View) getSecurityView(mCurrentSecuritySelection))
+ .setMessage(eventBundle.getString(HotwordRecognizer.PROMPT_TEXT),true);
+ }
+ }
+ }
+
+ public void onHotwordRecognized(final PendingIntent intent) {
+ if (DEBUG) Log.d(TAG, "onHotwordRecognized");
+ maybeStopHotwordDetector();
+ if (SecurityMode.None == mCurrentSecuritySelection) {
+ if (intent != null) {
+ try {
+ intent.send();
+ } catch (PendingIntent.CanceledException e) {
+ Log.w(TAG, "Failed to launch PendingIntent. Encountered CanceledException");
+ }
+ }
+ mCallback.userActivity(0);
+ mCallback.dismiss(false);
+ } else if (ENABLE_HOTWORD_SECURE && mLockPatternUtils.isSecure()) {
+ setOnDismissAction(new OnDismissAction() {
+ @Override
+ public boolean onDismiss() {
+ if (intent != null) {
+ try {
+ intent.send();
+ } catch (PendingIntent.CanceledException e) {
+ Log.w(TAG, "Failed to launch PendingIntent."
+ + "Encountered CanceledException");
+ }
+ }
+ return false;
+ }
+ });
+ getSecurityView(mCurrentSecuritySelection).showBouncer(0);
+ }
+ }
+
+ public void onHotwordError(int errorCode) {
+ if (DEBUG) Log.d(TAG, "onHotwordError: " + errorCode);
+ // TODO: Inspect the error code and handle the errors appropriately
+ // instead of blindly failing.
+ maybeStopHotwordDetector();
+ }
+ };
+
+ private boolean shouldRunHotwordInSecurityMode(SecurityMode mode) {
+ // Enable hotoword for insecure keyguard,
+ // and for pattern unlock if ENABLE_HOTWORD_SECURE is true.
+ return ENABLE_HOTWORD
+ && ((SecurityMode.None == mode)
+ || (ENABLE_HOTWORD_SECURE && mLockPatternUtils.isSecure()));
+ }
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
index 40d55cf..63be102 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
@@ -28,8 +28,6 @@ import android.os.Bundle;
import android.os.PowerManager;
import android.os.UserHandle;
import android.provider.Settings;
-import android.speech.hotword.HotwordRecognitionListener;
-import android.speech.hotword.HotwordRecognizer;
import android.telephony.TelephonyManager;
import android.util.AttributeSet;
import android.util.Log;
@@ -48,12 +46,6 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
private static final String ASSIST_ICON_METADATA_NAME =
"com.android.systemui.action_assist_icon";
- // Don't enable hotword on limited-memory devices.
- private static final boolean ENABLE_HOTWORD = !ActivityManager.isLowRamDeviceStatic();
-
- // TODO: Fix this to be non-static.
- private static HotwordRecognizer sHotwordClient;
-
private KeyguardSecurityCallback mCallback;
private GlowPadView mGlowPadView;
private ObjectAnimator mAnim;
@@ -69,7 +61,6 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
public void onTrigger(View v, int target) {
final int resId = mGlowPadView.getResourceIdForTarget(target);
- maybeStopHotwordDetector();
switch (resId) {
case R.drawable.ic_action_assist_generic:
@@ -129,22 +120,6 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
public void onSimStateChanged(State simState) {
updateTargets();
}
-
- @Override
- public void onPhoneStateChanged(int phoneState) {
- if (ENABLE_HOTWORD) {
- // We need to stop hotword detection when a call state is not idle anymore.
- if (phoneState != TelephonyManager.CALL_STATE_IDLE) {
- if (DEBUG) Log.d(TAG, "Stopping due to call state not being idle");
- maybeStopHotwordDetector();
- }
- }
- }
-
- @Override
- public void onUserSwitching(int userId) {
- maybeStopHotwordDetector();
- }
};
private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() {
@@ -183,9 +158,6 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
View bouncerFrameView = findViewById(R.id.keyguard_selector_view_frame);
mBouncerFrame = bouncerFrameView.getBackground();
- if (ENABLE_HOTWORD && sHotwordClient == null) {
- sHotwordClient = HotwordRecognizer.createHotwordRecognizer(getContext());
- }
}
public void setCarrierArea(View carrierArea) {
@@ -289,20 +261,11 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
@Override
public void onPause() {
KeyguardUpdateMonitor.getInstance(getContext()).removeCallback(mUpdateCallback);
- maybeStopHotwordDetector();
}
@Override
public void onResume(int reason) {
KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mUpdateCallback);
- // TODO: Figure out if there's a better way to do it.
- // onResume gets called multiple times, however we are interested in
- // the reason to figure out when to start/stop hotword detection.
- if (reason == SCREEN_ON) {
- if (!KeyguardUpdateMonitor.getInstance(getContext()).isSwitchingUser()) {
- maybeStartHotwordDetector();
- }
- }
}
@Override
@@ -323,100 +286,4 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
KeyguardSecurityViewHelper.
hideBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration);
}
-
- /**
- * Start the hotword detector if:
- * <li> FLAG_HOTWORD is true and
- * <li> Hotword detection is not already running and
- * <li> TelephonyManager is in CALL_STATE_IDLE
- *
- * If this method is called when the screen is off,
- * it attempts to stop hotword detection if it's running.
- */
- private void maybeStartHotwordDetector() {
- if (ENABLE_HOTWORD && sHotwordClient != null) {
- if (DEBUG) Log.d(TAG, "maybeStartHotwordDetector()");
- // Don't start it if the screen is off or not showing
- PowerManager powerManager = (PowerManager) getContext().getSystemService(
- Context.POWER_SERVICE);
- if (!powerManager.isScreenOn()) {
- if (DEBUG) Log.d(TAG, "screen was off, not starting");
- return;
- }
-
- KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext());
- if (monitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE) {
- if (DEBUG) Log.d(TAG, "Call underway, not starting");
- return;
- }
-
- try {
- sHotwordClient.startRecognition(mHotwordCallback);
- } catch(Exception ex) {
- // Don't allow hotword errors to make the keyguard unusable
- Log.e(TAG, "Failed to start hotword recognition", ex);
- sHotwordClient = null;
- }
- }
- }
-
- /**
- * Stop hotword detector if HOTWORDING_ENABLED is true.
- */
- private void maybeStopHotwordDetector() {
- if (ENABLE_HOTWORD && sHotwordClient != null) {
- if (DEBUG) Log.d(TAG, "maybeStopHotwordDetector()");
- try {
- sHotwordClient.stopRecognition();
- } catch(Exception ex) {
- // Don't allow hotword errors to make the keyguard unusable
- Log.e(TAG, "Failed to start hotword recognition", ex);
- } finally {
- sHotwordClient = null;
- }
- }
- }
-
- private final HotwordRecognitionListener mHotwordCallback = new HotwordRecognitionListener() {
- private static final String TAG = "HotwordRecognitionListener";
-
- public void onHotwordRecognitionStarted() {
- if (DEBUG) Log.d(TAG, "onHotwordRecognitionStarted()");
- }
-
- public void onHotwordRecognitionStopped() {
- if (DEBUG) Log.d(TAG, "onHotwordRecognitionStopped()");
- }
-
- public void onHotwordEvent(int eventType, Bundle eventBundle) {
- if (DEBUG) Log.d(TAG, "onHotwordEvent: " + eventType);
- if (eventType == HotwordRecognizer.EVENT_TYPE_STATE_CHANGED) {
- if (eventBundle != null && eventBundle.containsKey(HotwordRecognizer.PROMPT_TEXT)) {
- mSecurityMessageDisplay.setMessage(
- eventBundle.getString(HotwordRecognizer.PROMPT_TEXT), true);
- }
- }
- }
-
- public void onHotwordRecognized(PendingIntent intent) {
- if (DEBUG) Log.d(TAG, "onHotwordRecognized");
- maybeStopHotwordDetector();
- if (intent != null) {
- try {
- intent.send();
- } catch (PendingIntent.CanceledException e) {
- Log.w(TAG, "Failed to launch PendingIntent. Encountered CanceledException");
- }
- }
- mCallback.userActivity(0);
- mCallback.dismiss(false);
- }
-
- public void onHotwordError(int errorCode) {
- if (DEBUG) Log.d(TAG, "onHotwordError: " + errorCode);
- // TODO: Inspect the error code and handle the errors appropriately
- // instead of blindly failing.
- maybeStopHotwordDetector();
- }
- };
}
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index f58872a..2c06aec 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -20,7 +20,7 @@
<drawable name="notification_number_text_color">#ffffffff</drawable>
<drawable name="ticker_background_color">#ff1d1d1d</drawable>
<drawable name="status_bar_background">#ff000000</drawable>
- <color name="status_bar_background_semi_transparent">#55000000</color>
+ <color name="status_bar_background_semi_transparent">#66000000</color>
<color name="status_bar_background_transparent">#00000000</color>
<color name="navigation_bar_background_transparent_start">#7f000000</color>
<color name="navigation_bar_background_transparent_end">#00000000</color>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index b9c6fef..0d591ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -640,10 +640,10 @@ class QuickSettings {
@Override
public boolean onLongClick(View v) {
boolean newLocationEnabledState = !mLocationController.isLocationEnabled();
- mLocationController.setLocationEnabled(newLocationEnabledState);
- if (newLocationEnabledState) {
- // Close the notifications tray so that the network location provider
- // consent dialog can be shown.
+ if (mLocationController.setLocationEnabled(newLocationEnabledState)
+ && newLocationEnabledState) {
+ // If we've successfully switched from location off to on, close the
+ // notifications tray to show the network location provider consent dialog.
Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
mContext.sendBroadcast(closeDialog);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
index 7e75584..3070a3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.policy;
+import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
@@ -26,6 +27,7 @@ import android.content.IntentFilter;
import android.database.ContentObserver;
import android.location.LocationManager;
import android.os.Handler;
+import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -81,18 +83,18 @@ public class LocationController extends BroadcastReceiver {
mStatusBarManager
= (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE);
- // Register to listen for changes to the location settings
- context.getContentResolver().registerContentObserver(
- Settings.Secure.getUriFor(Settings.Secure.LOCATION_PROVIDERS_ALLOWED), true,
- new ContentObserver(new Handler()) {
- @Override
- public void onChange(boolean selfChange) {
- boolean isEnabled = isLocationEnabled();
- for (LocationSettingsChangeCallback cb : mSettingsChangeCallbacks) {
- cb.onLocationSettingsChanged(isEnabled);
- }
- }
- });
+ // Register to listen for changes in location settings.
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(LocationManager.MODE_CHANGED_ACTION);
+ context.registerReceiverAsUser(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (LocationManager.MODE_CHANGED_ACTION.equals(action)) {
+ locationSettingsChanged();
+ }
+ }
+ }, UserHandle.ALL, intentFilter, null, new Handler());
// Examine the current location state and initialize the status view.
updateActiveLocationRequests();
@@ -114,31 +116,49 @@ public class LocationController extends BroadcastReceiver {
*
* <p>If enabling, a user consent dialog will pop up prompting the user to accept.
* If the user doesn't accept, network location won't be enabled.
+ *
+ * @return true if attempt to change setting was successful.
*/
- public void setLocationEnabled(boolean enabled) {
- final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
- if (um.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION)) {
- return;
+ public boolean setLocationEnabled(boolean enabled) {
+ int currentUserId = ActivityManager.getCurrentUser();
+ if (isUserLocationRestricted(currentUserId)) {
+ return false;
}
final ContentResolver cr = mContext.getContentResolver();
// When enabling location, a user consent dialog will pop up, and the
// setting won't be fully enabled until the user accepts the agreement.
int mode = enabled
? Settings.Secure.LOCATION_MODE_HIGH_ACCURACY : Settings.Secure.LOCATION_MODE_OFF;
- Settings.Secure.putInt(cr, Settings.Secure.LOCATION_MODE, mode);
+ return Settings.Secure
+ .putIntForUser(cr, Settings.Secure.LOCATION_MODE, mode, currentUserId);
}
/**
* Returns true if location isn't disabled in settings.
*/
public boolean isLocationEnabled() {
+ int currentUserId = ActivityManager.getCurrentUser();
+ if (isUserLocationRestricted(currentUserId)) {
+ return false;
+ }
+
ContentResolver resolver = mContext.getContentResolver();
- int mode = Settings.Secure.getInt(resolver, Settings.Secure.LOCATION_MODE,
- Settings.Secure.LOCATION_MODE_OFF);
+ int mode = Settings.Secure.getIntForUser(resolver, Settings.Secure.LOCATION_MODE,
+ Settings.Secure.LOCATION_MODE_OFF, currentUserId);
return mode != Settings.Secure.LOCATION_MODE_OFF;
}
/**
+ * Returns true if the current user is restricted from using location.
+ */
+ private boolean isUserLocationRestricted(int userId) {
+ final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ return um.hasUserRestriction(
+ UserManager.DISALLOW_SHARE_LOCATION,
+ new UserHandle(userId));
+ }
+
+ /**
* Returns true if there currently exist active high power location requests.
*/
private boolean areActiveHighPowerLocationRequests() {
@@ -188,6 +208,13 @@ public class LocationController extends BroadcastReceiver {
}
}
+ private void locationSettingsChanged() {
+ boolean isEnabled = isLocationEnabled();
+ for (LocationSettingsChangeCallback cb : mSettingsChangeCallbacks) {
+ cb.onLocationSettingsChanged(isEnabled);
+ }
+ }
+
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 95c768f..de29155 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -1156,6 +1156,8 @@ public class LocationManagerService extends ILocationManager.Stub {
if (changesMade) {
mContext.sendBroadcastAsUser(new Intent(LocationManager.PROVIDERS_CHANGED_ACTION),
UserHandle.ALL);
+ mContext.sendBroadcastAsUser(new Intent(LocationManager.MODE_CHANGED_ACTION),
+ UserHandle.ALL);
}
}
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index 12cad7b..0dd950e 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -481,7 +481,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
private void dumpHelp(PrintWriter pw) {
pw.println("Battery stats (batterystats) dump options:");
- pw.println(" [--checkin] [--unplugged] [--reset] [--write] [-h] [<package.name>]");
+ pw.println(" [--checkin] [-c] [--unplugged] [--reset] [--write] [-h] [<package.name>]");
pw.println(" --checkin: format output for a checkin report.");
pw.println(" --unplugged: only output data since last unplugged.");
pw.println(" --reset: reset the stats, clearing all current data.");
@@ -501,6 +501,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
}
boolean isCheckin = false;
+ boolean includeHistory = false;
boolean isUnpluggedOnly = false;
boolean noOutput = false;
int reqUid = -1;
@@ -508,6 +509,9 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
for (String arg : args) {
if ("--checkin".equals(arg)) {
isCheckin = true;
+ } else if ("-c".equals(arg)) {
+ isCheckin = true;
+ includeHistory = true;
} else if ("--unplugged".equals(arg)) {
isUnpluggedOnly = true;
} else if ("--reset".equals(arg)) {
@@ -550,7 +554,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
if (isCheckin) {
List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
synchronized (mStats) {
- mStats.dumpCheckinLocked(pw, apps, isUnpluggedOnly);
+ mStats.dumpCheckinLocked(pw, apps, isUnpluggedOnly, includeHistory);
}
} else {
synchronized (mStats) {
diff --git a/services/java/com/android/server/am/ProcessStatsService.java b/services/java/com/android/server/am/ProcessStatsService.java
index 4ba26fb..55409c2 100644
--- a/services/java/com/android/server/am/ProcessStatsService.java
+++ b/services/java/com/android/server/am/ProcessStatsService.java
@@ -677,11 +677,9 @@ public final class ProcessStatsService extends IProcessStats.Stub {
if (checkedIn) pw.print(" (checked in)");
pw.println(":");
// Don't really need to lock because we uniquely own this object.
- if (dumpDetails) {
- processStats.dumpLocked(pw, reqPackage, now, dumpAll);
- } else {
- processStats.dumpSummaryLocked(pw, reqPackage, now);
- }
+ // Always dump summary here, dumping all details is just too
+ // much crud.
+ processStats.dumpSummaryLocked(pw, reqPackage, now);
}
if (isCheckin) {
// Rename file suffix to mark that it has checked in.
diff --git a/services/java/com/android/server/display/WifiDisplayController.java b/services/java/com/android/server/display/WifiDisplayController.java
index cd201f5..9a4cfb7 100644
--- a/services/java/com/android/server/display/WifiDisplayController.java
+++ b/services/java/com/android/server/display/WifiDisplayController.java
@@ -150,6 +150,8 @@ final class WifiDisplayController implements DumpUtils.Dump {
// Certification
private boolean mWifiDisplayCertMode;
+ private int mWifiDisplayWpsConfig = WpsInfo.INVALID;
+
private WifiP2pDevice mThisDevice;
public WifiDisplayController(Context context, Handler handler, Listener listener) {
@@ -179,6 +181,8 @@ final class WifiDisplayController implements DumpUtils.Dump {
Settings.Global.WIFI_DISPLAY_ON), false, settingsObserver);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON), false, settingsObserver);
+ resolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.WIFI_DISPLAY_WPS_CONFIG), false, settingsObserver);
updateSettings();
}
@@ -189,6 +193,12 @@ final class WifiDisplayController implements DumpUtils.Dump {
mWifiDisplayCertMode = Settings.Global.getInt(resolver,
Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON, 0) != 0;
+ mWifiDisplayWpsConfig = WpsInfo.INVALID;
+ if (mWifiDisplayCertMode) {
+ mWifiDisplayWpsConfig = Settings.Global.getInt(resolver,
+ Settings.Global.WIFI_DISPLAY_WPS_CONFIG, WpsInfo.INVALID);
+ }
+
updateWfdEnableState();
}
@@ -286,6 +296,25 @@ final class WifiDisplayController implements DumpUtils.Dump {
}
} else {
// WFD should be disabled.
+ if (mWfdEnabled || mWfdEnabling) {
+ WifiP2pWfdInfo wfdInfo = new WifiP2pWfdInfo();
+ wfdInfo.setWfdEnabled(false);
+ mWifiP2pManager.setWFDInfo(mWifiP2pChannel, wfdInfo, new ActionListener() {
+ @Override
+ public void onSuccess() {
+ if (DEBUG) {
+ Slog.d(TAG, "Successfully set WFD info.");
+ }
+ }
+
+ @Override
+ public void onFailure(int reason) {
+ if (DEBUG) {
+ Slog.d(TAG, "Failed to set WFD info with reason " + reason + ".");
+ }
+ }
+ });
+ }
mWfdEnabling = false;
mWfdEnabled = false;
reportFeatureState();
@@ -589,7 +618,9 @@ final class WifiDisplayController implements DumpUtils.Dump {
mConnectingDevice = mDesiredDevice;
WifiP2pConfig config = new WifiP2pConfig();
WpsInfo wps = new WpsInfo();
- if (mConnectingDevice.wpsPbcSupported()) {
+ if (mWifiDisplayWpsConfig != WpsInfo.INVALID) {
+ wps.setup = mWifiDisplayWpsConfig;
+ } else if (mConnectingDevice.wpsPbcSupported()) {
wps.setup = WpsInfo.PBC;
} else if (mConnectingDevice.wpsDisplaySupported()) {
// We do keypad if peer does display
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index c661b00..4be11b8 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -96,6 +96,7 @@ public class DctConstants {
public static final int CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA = BASE + 36;
public static final int CMD_ENABLE_MOBILE_PROVISIONING = BASE + 37;
public static final int CMD_IS_PROVISIONING_APN = BASE + 38;
+ public static final int EVENT_PROVISIONING_APN_ALARM = BASE + 39;
/***** Constants *****/
diff --git a/tests/TransitionTests/res/scene/incorrect_password_scene.xml b/tests/TransitionTests/res/scene/incorrect_password_scene.xml
deleted file mode 100644
index a31ad22..0000000
--- a/tests/TransitionTests/res/scene/incorrect_password_scene.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<scene xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout="@layout/incorrect_password"/> \ No newline at end of file
diff --git a/tests/TransitionTests/res/scene/login_scene.xml b/tests/TransitionTests/res/scene/login_scene.xml
deleted file mode 100644
index b258303..0000000
--- a/tests/TransitionTests/res/scene/login_scene.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<scene xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout="@layout/activity_login"/> \ No newline at end of file
diff --git a/tests/TransitionTests/res/scene/new_user_scene.xml b/tests/TransitionTests/res/scene/new_user_scene.xml
deleted file mode 100644
index d6e5f0f..0000000
--- a/tests/TransitionTests/res/scene/new_user_scene.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<scene xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout="@layout/new_user"/> \ No newline at end of file
diff --git a/tests/TransitionTests/res/scene/password_scene.xml b/tests/TransitionTests/res/scene/password_scene.xml
deleted file mode 100644
index 99a0038..0000000
--- a/tests/TransitionTests/res/scene/password_scene.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<scene xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout="@layout/login_password"/> \ No newline at end of file
diff --git a/tests/TransitionTests/res/scene/results_scene.xml b/tests/TransitionTests/res/scene/results_scene.xml
deleted file mode 100644
index 9c9fc69..0000000
--- a/tests/TransitionTests/res/scene/results_scene.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<scene xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout="@layout/results_screen">
-</scene> \ No newline at end of file
diff --git a/tests/TransitionTests/res/scene/search_scene.xml b/tests/TransitionTests/res/scene/search_scene.xml
deleted file mode 100644
index 742cd57..0000000
--- a/tests/TransitionTests/res/scene/search_scene.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<scene xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout="@layout/search_screen">
-</scene> \ No newline at end of file
diff --git a/tests/TransitionTests/res/scene/success_scene.xml b/tests/TransitionTests/res/scene/success_scene.xml
deleted file mode 100644
index 3d76d89..0000000
--- a/tests/TransitionTests/res/scene/success_scene.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<scene xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout="@layout/success"/> \ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/colorizer_transition.xml b/tests/TransitionTests/res/transition/colorizer_transition.xml
index 731d7ee..12f4be7 100644
--- a/tests/TransitionTests/res/transition/colorizer_transition.xml
+++ b/tests/TransitionTests/res/transition/colorizer_transition.xml
@@ -1,6 +1,6 @@
-<recolor xmlns:android="http://schemas.android.com/apk/res/android">>
+<recolor xmlns:android="http://schemas.android.com/apk/res/android">
<targets>
- <target android:targetID="@id/password"/>
- <target android:targetID="@id/passwordEdit"/>
+ <target android:targetId="@id/password"/>
+ <target android:targetId="@id/passwordEdit"/>
</targets>
</recolor> \ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/login_slider_transition.xml b/tests/TransitionTests/res/transition/login_slider_transition.xml
index dbdd6e9..2317857 100644
--- a/tests/TransitionTests/res/transition/login_slider_transition.xml
+++ b/tests/TransitionTests/res/transition/login_slider_transition.xml
@@ -1,21 +1,21 @@
-<transitionGroup xmlns:android="http://schemas.android.com/apk/res/android">
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<slide>
<targets>
- <target android:targetID="@id/retype"/>
- <target android:targetID="@id/retypeEdit"/>
+ <target android:targetId="@id/retype"/>
+ <target android:targetId="@id/retypeEdit"/>
</targets>
</slide>
<recolor>
<targets>
- <target android:targetID="@id/password"/>
- <target android:targetID="@id/passwordEdit"/>
+ <target android:targetId="@id/password"/>
+ <target android:targetId="@id/passwordEdit"/>
</targets>
</recolor>
<fade/>
-</transitionGroup>
+</transitionSet>
<!--
- TransitionGroup slider = new TransitionGroup();
+ TransitionSet slider = new TransitionSet();
slider.addTransition(new Slide(R.id.retype, R.id.retypeEdit));
slider.addTransition(new Recolor(R.id.password, R.id.passwordEdit));
slider.addTransition(new Fade());
diff --git a/tests/TransitionTests/res/transition/login_transition_mgr.xml b/tests/TransitionTests/res/transition/login_transition_mgr.xml
index 8a8b9e9..5d07be0 100644
--- a/tests/TransitionTests/res/transition/login_transition_mgr.xml
+++ b/tests/TransitionTests/res/transition/login_transition_mgr.xml
@@ -1,39 +1,14 @@
<transitionManager xmlns:android="http://schemas.android.com/apk/res/android">
- <transition fromScene="@scene/login_scene" toScene="@scene/new_user_scene"
- transition="@transition/login_slider_transition"/>
- <transition fromScene="@scene/password_scene" toScene="@scene/new_user_scene"
- transition="@transition/login_slider_transition"/>
- <transition fromScene="@scene/new_user_scene" toScene="@scene/login_scene"
- transition="@transition/login_slider_transition"/>
- <transition fromScene="@scene/new_user_scene" toScene="@scene/password_scene"
- transition="@transition/login_slider_transition"/>
- <transition fromScene="@scene/login_scene" toScene="@scene/password_scene"
- transition="@transition/colorizer_transition"/>
- <transition fromScene="@scene/password_scene" toScene="@scene/login_scene"
- transition="@transition/colorizer_transition"/>
+ <transition android:fromScene="@layout/activity_login" android:toScene="@layout/new_user"
+ android:transition="@transition/login_slider_transition"/>
+ <transition android:fromScene="@layout/login_password" android:toScene="@layout/new_user"
+ android:transition="@transition/login_slider_transition"/>
+ <transition android:fromScene="@layout/new_user" android:toScene="@layout/activity_login"
+ android:transition="@transition/login_slider_transition"/>
+ <transition android:fromScene="@layout/new_user" android:toScene="@layout/login_password"
+ android:transition="@transition/login_slider_transition"/>
+ <transition android:fromScene="@layout/activity_login" android:toScene="@layout/login_password"
+ android:transition="@transition/colorizer_transition"/>
+ <transition android:fromScene="@layout/login_password" android:toScene="@layout/activity_login"
+ android:transition="@transition/colorizer_transition"/>
</transitionManager>
-
- <!--
- mLoginScene = new Scene(this, mSceneRoot, R.layout.activity_login);
- mPasswordScene = new Scene(this, mSceneRoot, R.layout.login_password);
- mIncorrectPasswordScene = new Scene(this, mSceneRoot, R.layout.incorrect_password);
- mUsernameTakenScene = new Scene(this, mSceneRoot, R.layout.username_taken);
- mSuccessScene = new Scene(this, mSceneRoot, R.layout.success);
- mNewUserScene = new Scene(this, mSceneRoot, R.layout.new_user);
-
- mTransitionManager = new TransitionManager();
- // Custom transitions in/out of NewUser screen - slide in the 2nd password UI
- TransitionGroup slider = new TransitionGroup();
- slider.addTransition(new Slide(R.id.retype, R.id.retypeEdit));
- slider.addTransition(new Recolor(R.id.password, R.id.passwordEdit));
- slider.addTransition(new Fade());
- mTransitionManager.setTransition(mLoginScene, mNewUserScene, slider);
- mTransitionManager.setTransition(mPasswordScene, mNewUserScene, slider);
- mTransitionManager.setTransition(mNewUserScene, mLoginScene, slider);
- mTransitionManager.setTransition(mNewUserScene, mPasswordScene, slider);
-
- // Custom transitions with recoloring password field
- Transition colorizer = new Recolor(R.id.password, R.id.passwordEdit);
- mTransitionManager.setTransition(mLoginScene, mPasswordScene, colorizer);
- mTransitionManager.setTransition(mPasswordScene, mLoginScene, colorizer);
---> \ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/mover.xml b/tests/TransitionTests/res/transition/mover.xml
index 3c47606..b23d2a5 100644
--- a/tests/TransitionTests/res/transition/mover.xml
+++ b/tests/TransitionTests/res/transition/mover.xml
@@ -1 +1 @@
-<move/> \ No newline at end of file
+<changeBounds/> \ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/mover_fader.xml b/tests/TransitionTests/res/transition/mover_fader.xml
index 8b805e9..ef11676 100644
--- a/tests/TransitionTests/res/transition/mover_fader.xml
+++ b/tests/TransitionTests/res/transition/mover_fader.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<transitionGroup xmlns:android="http://schemas.android.com/apk/res/android">
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<fade/>
- <move/>
-</transitionGroup> \ No newline at end of file
+ <changeBounds/>
+</transitionSet> \ No newline at end of file
diff --git a/tests/TransitionTests/res/scene/my_scene.xml b/tests/TransitionTests/res/transition/my_scene.xml
index b8278c9..b8278c9 100644
--- a/tests/TransitionTests/res/scene/my_scene.xml
+++ b/tests/TransitionTests/res/transition/my_scene.xml
diff --git a/tests/TransitionTests/res/transition/my_transition.xml b/tests/TransitionTests/res/transition/my_transition.xml
index 14c91b9..022313c 100644
--- a/tests/TransitionTests/res/transition/my_transition.xml
+++ b/tests/TransitionTests/res/transition/my_transition.xml
@@ -1,20 +1,20 @@
-<transitionGroup xmlns:android="http://schemas.android.com/apk/res/android">
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<fade></fade>
- <transitionGroup>
- <move android:duration="500">
+ <transitionSet>
+ <changeBounds android:duration="500">
<targets>
- <target android:targetID="@id/container"/>
- <target android:targetID="@id/resultsList"/>
+ <target android:targetId="@id/container"/>
+ <target android:targetId="@id/resultsList"/>
</targets>
- </move>
- <transitionGroup>
+ </changeBounds>
+ <transitionSet>
<targets>
- <target android:targetID="@id/container"/>
- <target android:targetID="@id/resultsList"/>
+ <target android:targetId="@id/container"/>
+ <target android:targetId="@id/resultsList"/>
</targets>
<fade android:startOffset="25"/>
- </transitionGroup>
+ </transitionSet>
<recolor/>
- </transitionGroup>
- <move/>
-</transitionGroup> \ No newline at end of file
+ </transitionSet>
+ <changeBounds/>
+</transitionSet> \ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/my_transition_mgr.xml b/tests/TransitionTests/res/transition/my_transition_mgr.xml
index ca9705a..5d8f799 100644
--- a/tests/TransitionTests/res/transition/my_transition_mgr.xml
+++ b/tests/TransitionTests/res/transition/my_transition_mgr.xml
@@ -1,6 +1,6 @@
<transitionManager xmlns:android="http://schemas.android.com/apk/res/android">
- <transition fromScene="@scene/search_scene" toScene="@scene/results_scene"
- transition="@transition/mover_fader"/>
- <transition fromScene="@scene/results_scene" toScene="@scene/search_scene"
- transition="@transition/mover_fader"/>
+ <transition android:fromScene="@layout/search_screen" android:toScene="@layout/results_screen"
+ android:transition="@transition/mover_fader"/>
+ <transition android:fromScene="@layout/results_screen" android:toScene="@layout/search_screen"
+ android:transition="@transition/mover_fader"/>
</transitionManager> \ No newline at end of file
diff --git a/tests/TransitionTests/res/scene/username_taken_scene.xml b/tests/TransitionTests/res/transition/username_taken_scene.xml
index b2f050e..b2f050e 100644
--- a/tests/TransitionTests/res/scene/username_taken_scene.xml
+++ b/tests/TransitionTests/res/transition/username_taken_scene.xml
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ChangingText.java b/tests/TransitionTests/src/com/android/transitiontests/ChangingText.java
index 05bed5f..a1ddd74 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ChangingText.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ChangingText.java
@@ -19,42 +19,43 @@ import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Scene;
-import android.widget.Button;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.TextChange;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.ChangeBounds;
+import android.transition.TextChange;
+import android.transition.TransitionManager;
public class ChangingText extends Activity {
Scene mScene1, mScene2;
ViewGroup mSceneRoot;
- TransitionGroup mChanger;
+ TransitionSet mChanger;
+ Scene mCurrentScene;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.changing_text_1);
- View container = (View) findViewById(R.id.container);
+ View container = findViewById(R.id.container);
mSceneRoot = (ViewGroup) container.getParent();
- mScene1 = new Scene(mSceneRoot, R.layout.changing_text_1, this);
- mScene2 = new Scene(mSceneRoot, R.layout.changing_text_2, this);
+ mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.changing_text_1, this);
+ mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.changing_text_2, this);
- mChanger = new TransitionGroup(TransitionGroup.TOGETHER);
- mChanger.addTransitions(new Move(), new TextChange());
+ mChanger = new TransitionSet().setOrdering(TransitionSet.ORDERING_TOGETHER);
+ mChanger.addTransition(new ChangeBounds()).addTransition(new TextChange());
- mSceneRoot.setCurrentScene(mScene1);
+ mCurrentScene = mScene1;
}
public void sendMessage(View view) {
- if (mSceneRoot.getCurrentScene() == mScene1) {
+ if (mCurrentScene == mScene1) {
TransitionManager.go(mScene2, mChanger);
+ mCurrentScene = mScene2;
} else {
TransitionManager.go(mScene1, mChanger);
+ mCurrentScene = mScene1;
}
}
}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ClippingText.java b/tests/TransitionTests/src/com/android/transitiontests/ClippingText.java
index c3201f2..85702fa 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ClippingText.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ClippingText.java
@@ -17,15 +17,15 @@ package com.android.transitiontests;
import android.app.Activity;
import android.os.Bundle;
+import android.transition.ChangeBounds;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Scene;
+import android.transition.Scene;
import android.widget.Button;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.TextChange;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.TextChange;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
public class ClippingText extends Activity {
@@ -34,7 +34,8 @@ public class ClippingText extends Activity {
ViewGroup mSceneRoot;
// static Fade sFade = new Fade(R.id.removingButton, R.id.invisibleButton, R.id.goneButton);
Fade fader;
- TransitionGroup mChanger;
+ TransitionSet mChanger;
+ Scene mCurrentScene;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -44,22 +45,24 @@ public class ClippingText extends Activity {
View container = (View) findViewById(R.id.container);
mSceneRoot = (ViewGroup) container.getParent();
- mScene1 = new Scene(mSceneRoot, R.layout.clipping_text_1, this);
- mScene2 = new Scene(mSceneRoot, R.layout.clipping_text_2, this);
+ mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.clipping_text_1, this);
+ mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.clipping_text_2, this);
- mChanger = new TransitionGroup(TransitionGroup.TOGETHER);
- Move move = new Move();
- move.setResizeClip(true);
- mChanger.addTransitions(move, new TextChange());
+ mChanger = new TransitionSet().setOrdering(TransitionSet.ORDERING_TOGETHER);
+ ChangeBounds changeBounds = new ChangeBounds();
+ changeBounds.setResizeClip(true);
+ mChanger.addTransition(changeBounds).addTransition(new TextChange());
- mSceneRoot.setCurrentScene(mScene1);
+ mCurrentScene = mScene1;
}
public void sendMessage(View view) {
- if (mSceneRoot.getCurrentScene() == mScene1) {
+ if (mCurrentScene == mScene1) {
TransitionManager.go(mScene2, mChanger);
+ mCurrentScene = mScene2;
} else {
TransitionManager.go(mScene1, mChanger);
+ mCurrentScene = mScene1;
}
}
}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java b/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java
index c7da6a3..482dc05 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java
@@ -18,19 +18,19 @@ package com.android.transitiontests;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
+import android.transition.ChangeBounds;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Fade;
-import android.view.transition.Scene;
-import android.view.transition.Transition;
+import android.transition.Fade;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionSet;
import android.widget.ImageView;
import android.widget.TextView;
-import android.view.transition.Crossfade;
-import android.view.transition.Move;
-import android.view.transition.Rotate;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Crossfade;
+import android.transition.Rotate;
+import android.transition.TransitionManager;
public class ContactsExpansion extends Activity {
@@ -42,7 +42,8 @@ public class ContactsExpansion extends Activity {
View currentItem = null;
- TransitionGroup mMyAutoTransition = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
+ TransitionSet mMyAutoTransition = new TransitionSet().
+ setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -73,11 +74,12 @@ public class ContactsExpansion extends Activity {
((TextView)contactItem.findViewById(R.id.contact_email)).setText(contactsData[dataIndex++]);
container.addView(contactItem);
- final TransitionGroup myTransition = new TransitionGroup();
- myTransition.addTransitions(new Fade(Fade.IN),
- new Rotate().setTargetIds(R.id.contact_arrow),
- new Move(), new Fade(Fade.OUT),
- new Crossfade().setTargetIds(R.id.contact_picture));
+ final TransitionSet myTransition = new TransitionSet();
+ myTransition.addTransition(new Fade(Fade.IN)).
+ addTransition(new Rotate().addTargetId(R.id.contact_arrow)).
+ addTransition(new ChangeBounds()).
+ addTransition(new Fade(Fade.OUT)).
+ addTransition(new Crossfade().addTargetId(R.id.contact_picture));
final ToggleScene toggleScene = new ToggleScene(container, myTransition);
contactItem.setOnClickListener(new View.OnClickListener() {
@Override
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java b/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
index d5f6a28..eb799ec 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
@@ -17,13 +17,13 @@ package com.android.transitiontests;
import android.app.Activity;
import android.os.Bundle;
+import android.transition.ChangeBounds;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Crossfade;
-import android.view.transition.Move;
-import android.view.transition.Scene;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Crossfade;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
public class CrossFadeDemo extends Activity {
@@ -41,16 +41,17 @@ public class CrossFadeDemo extends Activity {
View container = (View) findViewById(R.id.container);
mSceneRoot = (ViewGroup) container.getParent();
- mScene1 = new Scene(mSceneRoot, R.layout.crossfade, this);
- mScene2 = new Scene(mSceneRoot, R.layout.crossfade_1, this);
+ mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.crossfade, this);
+ mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.crossfade_1, this);
Crossfade crossfade = new Crossfade();
crossfade.setFadeBehavior(Crossfade.FADE_BEHAVIOR_CROSSFADE);
crossfade.setResizeBehavior(Crossfade.RESIZE_BEHAVIOR_NONE);
- crossfade.setTargetIds(R.id.textview, R.id.textview1, R.id.textview2);
+ crossfade.addTargetId(R.id.textview).addTargetId(R.id.textview1).
+ addTargetId(R.id.textview2);
mTransitionManager = new TransitionManager();
- TransitionGroup moveCrossFade = new TransitionGroup();
- moveCrossFade.addTransitions(crossfade, new Move());
+ TransitionSet moveCrossFade = new TransitionSet();
+ moveCrossFade.addTransition(crossfade).addTransition(new ChangeBounds());
mTransitionManager.setTransition(mScene1, moveCrossFade);
mTransitionManager.setTransition(mScene2, moveCrossFade);
mCurrentScene = 1;
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java
index 28e055f..09b495f 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java
@@ -19,12 +19,12 @@ import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Crossfade;
-import android.view.transition.Move;
-import android.view.transition.Scene;
-import android.view.transition.Transition;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Crossfade;
+import android.transition.ChangeBounds;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
import android.widget.ImageView;
public class CrossfadeImage extends Activity {
@@ -48,11 +48,11 @@ public class CrossfadeImage extends Activity {
mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
Crossfade mCrossfade = new Crossfade();
- mCrossfade.setTargetIds(R.id.contact_picture);
+ mCrossfade.addTargetId(R.id.contact_picture);
- TransitionGroup group = new TransitionGroup();
+ TransitionSet group = new TransitionSet();
group.setDuration(1500);
- group.addTransitions(mCrossfade, new Move());
+ group.addTransition(mCrossfade).addTransition(new ChangeBounds());
mTransition = group;
}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java
index b82dbd8..c118398 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java
@@ -17,14 +17,14 @@ package com.android.transitiontests;
import android.app.Activity;
import android.os.Bundle;
+import android.transition.ChangeBounds;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Crossfade;
-import android.view.transition.Move;
-import android.view.transition.TextChange;
-import android.view.transition.Transition;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Crossfade;
+import android.transition.TextChange;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
@@ -40,9 +40,9 @@ public class CrossfadeMultiple extends Activity {
TextView mTextView;
Button mButton;
Crossfade mCrossfade;
- TransitionGroup mCrossfadeGroup;
- TransitionGroup mTextChangeGroup1, mTextChangeGroup2;
- TransitionGroup mInOutGroup;
+ TransitionSet mCrossfadeGroup;
+ TransitionSet mTextChangeGroup1, mTextChangeGroup2;
+ TransitionSet mInOutGroup;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -57,34 +57,35 @@ public class CrossfadeMultiple extends Activity {
mTextView = (TextView) findViewById(R.id.textview);
mCrossfade = new Crossfade();
- mCrossfade.setTargetIds(R.id.button, R.id.textview, R.id.imageview);
+ mCrossfade.addTargetId(R.id.button).addTargetId(R.id.textview).addTargetId(R.id.imageview);
- mCrossfadeGroup = new TransitionGroup();
+ mCrossfadeGroup = new TransitionSet();
mCrossfadeGroup.setDuration(300);
- mCrossfadeGroup.addTransitions(mCrossfade, new Move());
+ mCrossfadeGroup.addTransition(mCrossfade).addTransition(new ChangeBounds());
mTransition = mCrossfadeGroup;
- mInOutGroup = new TransitionGroup();
+ mInOutGroup = new TransitionSet();
Crossfade inOut = new Crossfade();
inOut.setDuration(300);
inOut.setFadeBehavior(Crossfade.FADE_BEHAVIOR_OUT_IN);
- Move move = new Move();
- move.setStartDelay(150);
- move.setDuration(0);
- mInOutGroup.addTransitions(inOut, move);
+ ChangeBounds changeBounds = new ChangeBounds();
+ changeBounds.setStartDelay(150);
+ changeBounds.setDuration(0);
+ mInOutGroup.addTransition(inOut).addTransition(changeBounds);
- mTextChangeGroup1 = new TransitionGroup();
+ mTextChangeGroup1 = new TransitionSet();
TextChange textChangeInOut = new TextChange();
textChangeInOut.setChangeBehavior(TextChange.CHANGE_BEHAVIOR_OUT_IN);
- mTextChangeGroup1.addTransitions(textChangeInOut, new Move());
+ mTextChangeGroup1.addTransition(textChangeInOut).addTransition(new ChangeBounds());
- mTextChangeGroup2 = new TransitionGroup();
- mTextChangeGroup2.setOrdering(TransitionGroup.SEQUENTIALLY);
+ mTextChangeGroup2 = new TransitionSet();
+ mTextChangeGroup2.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
TextChange textChangeOut = new TextChange();
textChangeOut.setChangeBehavior(TextChange.CHANGE_BEHAVIOR_OUT);
TextChange textChangeIn = new TextChange();
textChangeIn.setChangeBehavior(TextChange.CHANGE_BEHAVIOR_IN);
- mTextChangeGroup2.addTransitions(textChangeOut, new Move(), textChangeIn);
+ mTextChangeGroup2.addTransition(textChangeOut).addTransition(new ChangeBounds()).
+ addTransition(textChangeIn);
}
public void sendMessage(View view) {
diff --git a/tests/TransitionTests/src/com/android/transitiontests/DelayedTransition.java b/tests/TransitionTests/src/com/android/transitiontests/DelayedTransition.java
index f05ea78..fe5f05a 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/DelayedTransition.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/DelayedTransition.java
@@ -19,7 +19,7 @@ import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.TransitionManager;
+import android.transition.TransitionManager;
import android.widget.Button;
import android.widget.LinearLayout;
import static android.widget.LinearLayout.LayoutParams;
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo1.java b/tests/TransitionTests/src/com/android/transitiontests/Demo1.java
index ce7f439..5c0cd45 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo1.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo1.java
@@ -21,11 +21,11 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.Scene;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.ChangeBounds;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
public class Demo1 extends Activity {
@@ -69,9 +69,10 @@ public class Demo1 extends Activity {
public void sendMessage(View view) {
if (mFirstTime) {
mFirstTime = false;
- TransitionGroup transition = new TransitionGroup();
- transition.addTransitions(new Fade().setTargetIds(R.id.resultsText, R.id.resultsList),
- new Move().setTargetIds(R.id.searchContainer));
+ TransitionSet transition = new TransitionSet();
+ transition.addTransition(new Fade().addTargetId(R.id.resultsText).
+ addTargetId(R.id.resultsList)).
+ addTransition(new ChangeBounds().addTargetId(R.id.searchContainer));
mTransitionManager = new TransitionManager();
mTransitionManager.setTransition(mSearchScreen, transition);
mTransitionManager.setTransition(mResultsScreen, transition);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo2.java b/tests/TransitionTests/src/com/android/transitiontests/Demo2.java
index 7e1afab..334b777 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo2.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo2.java
@@ -19,13 +19,12 @@ import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.Recolor;
-import android.view.transition.Scene;
-import android.view.transition.TransitionInflater;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.ChangeBounds;
+import android.transition.Recolor;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
public class Demo2 extends Activity {
ViewGroup mSceneRoot;
@@ -51,18 +50,17 @@ public class Demo2 extends Activity {
// mSearchScreen = new Scene(this, mSceneRoot, R.layout.search_screen);
// mResultsScreen = new Scene(this, mSceneRoot, R.layout.results_screen);
try {
- mSearchScreen = TransitionInflater.from(this).
- inflateScene(R.scene.search_scene, mSceneRoot);
- mResultsScreen = TransitionInflater.from(this).
- inflateScene(R.scene.results_scene, mSceneRoot);
+ mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+ mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
} catch (Exception e) {
System.out.println("Problem loading scene resource: " + e);
}
- TransitionGroup transition = new TransitionGroup();
- transition.addTransitions(new Fade().setTargetIds(R.id.resultsText, R.id.resultsList),
- new Move().setTargetIds(R.id.searchContainer),
- new Recolor().setTargetIds(R.id.container));
+ TransitionSet transition = new TransitionSet();
+ transition.addTransition(new Fade().addTargetId(R.id.resultsText).
+ addTargetId(R.id.resultsList)).
+ addTransition(new ChangeBounds().addTargetId(R.id.searchContainer)).
+ addTransition(new Recolor().addTargetId(R.id.container));
mTransitionManager = new TransitionManager();
mTransitionManager.setTransition(mSearchScreen, transition);
mTransitionManager.setTransition(mResultsScreen, transition);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo3.java b/tests/TransitionTests/src/com/android/transitiontests/Demo3.java
index b8daff5..0ffa1f5 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo3.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo3.java
@@ -17,14 +17,14 @@ package com.android.transitiontests;
import android.app.Activity;
import android.os.Bundle;
+import android.transition.ChangeBounds;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.Recolor;
-import android.view.transition.Scene;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.Recolor;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
public class Demo3 extends Activity {
@@ -41,11 +41,11 @@ public class Demo3 extends Activity {
View container = (View) findViewById(R.id.container);
mSceneRoot = (ViewGroup) container.getParent();
- mSearchScreen = new Scene(mSceneRoot, R.layout.search_screen, this);
- mResultsScreen = new Scene(mSceneRoot, R.layout.results_screen, this);
+ mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+ mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
- TransitionGroup transition = new TransitionGroup();
- transition.addTransitions(new Fade(), new Move(), new Recolor());
+ TransitionSet transition = new TransitionSet();
+ transition.addTransition(new Fade()).addTransition(new ChangeBounds()).addTransition(new Recolor());
mTransitionManager = new TransitionManager();
mTransitionManager.setTransition(mSearchScreen, transition);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo4.java b/tests/TransitionTests/src/com/android/transitiontests/Demo4.java
index 8be54f5..d1c3358 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo4.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo4.java
@@ -17,14 +17,14 @@ package com.android.transitiontests;
import android.app.Activity;
import android.os.Bundle;
+import android.transition.ChangeBounds;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.Recolor;
-import android.view.transition.Scene;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.Recolor;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
public class Demo4 extends Activity {
@@ -41,20 +41,22 @@ public class Demo4 extends Activity {
View container = (View) findViewById(R.id.container);
mSceneRoot = (ViewGroup) container.getParent();
- mSearchScreen = new Scene(mSceneRoot, R.layout.search_screen, this);
- mResultsScreen = new Scene(mSceneRoot, R.layout.results_screen, this);
+ mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+ mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
- TransitionGroup transitionToResults = new TransitionGroup();
+ TransitionSet transitionToResults = new TransitionSet();
Fade fade = new Fade();
- fade.setTargetIds(R.id.resultsText, R.id.resultsList);
+ fade.addTargetId(R.id.resultsText).addTargetId(R.id.resultsList);
fade.setStartDelay(300);
fade.setDuration(1000);
- transitionToResults.addTransitions(fade, new Move().setTargetIds(R.id.searchContainer),
- new Recolor().setTargetIds(R.id.container));
+ transitionToResults.addTransition(fade).
+ addTransition(new ChangeBounds().addTargetId(R.id.searchContainer)).
+ addTransition(new Recolor().addTargetId(R.id.container));
- TransitionGroup transitionToSearch = new TransitionGroup();
- transitionToSearch.addTransitions(fade, new Move().setTargetIds(R.id.searchContainer),
- new Recolor().setTargetIds(R.id.container));
+ TransitionSet transitionToSearch = new TransitionSet();
+ transitionToSearch.addTransition(fade).
+ addTransition(new ChangeBounds().addTargetId(R.id.searchContainer)).
+ addTransition(new Recolor().addTargetId(R.id.container));
mTransitionManager = new TransitionManager();
mTransitionManager.setTransition(mSearchScreen, transitionToSearch);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo5.java b/tests/TransitionTests/src/com/android/transitiontests/Demo5.java
index e64511e..c36abda 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo5.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo5.java
@@ -19,8 +19,8 @@ import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Scene;
-import android.view.transition.TransitionManager;
+import android.transition.Scene;
+import android.transition.TransitionManager;
public class Demo5 extends Activity {
@@ -36,8 +36,8 @@ public class Demo5 extends Activity {
View container = (View) findViewById(R.id.container);
mSceneRoot = (ViewGroup) container.getParent();
- mSearchScreen = new Scene(mSceneRoot, R.layout.search_screen, this);
- mResultsScreen = new Scene(mSceneRoot, R.layout.results_screen, this);
+ mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+ mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java b/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java
index e0fe379..d497abe 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java
@@ -19,8 +19,7 @@ import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Scene;
-import android.view.transition.TransitionManager;
+import android.transition.TransitionManager;
import android.widget.Button;
public class FadingHierarchy extends Activity {
diff --git a/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java b/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java
index 400e994..000ea9b 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java
@@ -19,10 +19,10 @@ import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Scene;
+import android.transition.Scene;
import android.widget.Button;
-import android.view.transition.Fade;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.TransitionManager;
public class FadingTest extends Activity {
@@ -31,9 +31,11 @@ public class FadingTest extends Activity {
Scene mScene1, mScene2;
ViewGroup mSceneRoot;
static Fade sFade = new Fade();
+ Scene mCurrentScene;
static {
- sFade.setTargetIds(R.id.removingButton, R.id.invisibleButton, R.id.goneButton);
+ sFade.addTargetId(R.id.removingButton).addTargetId(R.id.invisibleButton).
+ addTargetId(R.id.goneButton);
}
@Override
@@ -56,17 +58,19 @@ public class FadingTest extends Activity {
}
});
- mScene1 = new Scene(mSceneRoot, R.layout.fading_test, this);
- mScene2 = new Scene(mSceneRoot, R.layout.fading_test_scene_2, this);
+ mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test, this);
+ mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test_scene_2, this);
- mSceneRoot.setCurrentScene(mScene1);
+ mCurrentScene = mScene1;
}
public void sendMessage(View view) {
- if (mSceneRoot.getCurrentScene() == mScene1) {
+ if (mCurrentScene == mScene1) {
TransitionManager.go(mScene2);
+ mCurrentScene = mScene2;
} else {
TransitionManager.go(mScene1);
+ mCurrentScene = mScene1;
}
}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/HierarchicalMove.java b/tests/TransitionTests/src/com/android/transitiontests/HierarchicalMove.java
index 093d7c1..1146e20 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/HierarchicalMove.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/HierarchicalMove.java
@@ -17,12 +17,12 @@ package com.android.transitiontests;
import android.app.Activity;
import android.os.Bundle;
+import android.transition.ChangeBounds;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Move;
-import android.view.transition.Transition;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
import android.widget.Button;
import static android.widget.LinearLayout.LayoutParams;
@@ -59,33 +59,37 @@ public class HierarchicalMove extends Activity {
// group (sequentially)
// Move 3
// Move 4/5
- TransitionGroup rootTransition = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
+ TransitionSet rootTransition = new TransitionSet().
+ setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
// button0
- Transition move0 = new Move();
- move0.setTargets(buttons[0]);
+ Transition move0 = new ChangeBounds();
+ move0.addTarget(buttons[0]);
// buttons 1/2/3/4/5
- TransitionGroup group12345 = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
+ TransitionSet group12345 = new TransitionSet().
+ setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
// buttons 1/2
- TransitionGroup group12 = new TransitionGroup(TransitionGroup.TOGETHER);
- Move move1 = new Move();
- move1.setTargets(buttons[1]);
- Move move2 = new Move();
- move2.setTargets(buttons[2]);
- group12.addTransitions(move1, move2);
-
- TransitionGroup group345 = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
- Move move3 = new Move();
- move3.setTargets(buttons[3]);
- Move move45 = new Move();
- move45.setTargets(buttons[4], buttons[5]);
- group345.addTransitions(move3, move45);
-
- group12345.addTransitions(move0, group12, group345);
-
- rootTransition.addTransitions(group12345);
+ TransitionSet group12 = new TransitionSet().
+ setOrdering(TransitionSet.ORDERING_TOGETHER);
+ ChangeBounds changeBounds1 = new ChangeBounds();
+ changeBounds1.addTarget(buttons[1]);
+ ChangeBounds changeBounds2 = new ChangeBounds();
+ changeBounds2.addTarget(buttons[2]);
+ group12.addTransition(changeBounds1).addTransition(changeBounds2);
+
+ TransitionSet group345 = new TransitionSet().
+ setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+ ChangeBounds changeBounds3 = new ChangeBounds();
+ changeBounds3.addTarget(buttons[3]);
+ ChangeBounds changeBounds45 = new ChangeBounds();
+ changeBounds45.addTarget(buttons[4]).addTarget(buttons[5]);
+ group345.addTransition(changeBounds3).addTransition(changeBounds45);
+
+ group12345.addTransition(move0).addTransition(group12).addTransition(group345);
+
+ rootTransition.addTransition(group12345);
rootTransition.setDuration(1000);
mTransition = rootTransition;
diff --git a/tests/TransitionTests/src/com/android/transitiontests/InstanceTargets.java b/tests/TransitionTests/src/com/android/transitiontests/InstanceTargets.java
index cf4ea9a..a06ba8f 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/InstanceTargets.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/InstanceTargets.java
@@ -16,16 +16,12 @@
package com.android.transitiontests;
import android.app.Activity;
-import android.content.Context;
import android.os.Bundle;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Move;
-import android.view.transition.Scene;
-import android.view.transition.TransitionManager;
+import android.transition.ChangeBounds;
+import android.transition.TransitionManager;
import android.widget.Button;
-import android.widget.RelativeLayout;
import static android.widget.RelativeLayout.ALIGN_PARENT_LEFT;
import static android.widget.RelativeLayout.ALIGN_PARENT_RIGHT;
@@ -46,23 +42,19 @@ public class InstanceTargets extends Activity {
}
public void sendMessage(final View view) {
- TransitionManager.go(mSceneRoot, new Runnable() {
- @Override
- public void run() {
- for (int i = 0; i < mSceneRoot.getChildCount(); ++i) {
- Button button = (Button) mSceneRoot.getChildAt(i);
- LayoutParams params = (LayoutParams) button.getLayoutParams();
- int rules[] = params.getRules();
- if (rules[ALIGN_PARENT_RIGHT] != 0) {
- params.removeRule(ALIGN_PARENT_RIGHT);
- params.addRule(ALIGN_PARENT_LEFT);
- } else {
- params.removeRule(ALIGN_PARENT_LEFT);
- params.addRule(ALIGN_PARENT_RIGHT);
- }
- button.setLayoutParams(params);
- }
+ TransitionManager.beginDelayedTransition(mSceneRoot, new ChangeBounds().addTarget(view));
+ for (int i = 0; i < mSceneRoot.getChildCount(); ++i) {
+ Button button = (Button) mSceneRoot.getChildAt(i);
+ LayoutParams params = (LayoutParams) button.getLayoutParams();
+ int rules[] = params.getRules();
+ if (rules[ALIGN_PARENT_RIGHT] != 0) {
+ params.removeRule(ALIGN_PARENT_RIGHT);
+ params.addRule(ALIGN_PARENT_LEFT);
+ } else {
+ params.removeRule(ALIGN_PARENT_LEFT);
+ params.addRule(ALIGN_PARENT_RIGHT);
}
- }, new Move().setTargets(view));
+ button.setLayoutParams(params);
+ }
}
}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java b/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java
index b380225..70257bb 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java
@@ -17,15 +17,12 @@ package com.android.transitiontests;
import android.app.Activity;
import android.os.Bundle;
+import android.transition.ChangeBounds;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.AutoTransition;
-import android.view.transition.Move;
-import android.view.transition.Scene;
-import android.view.transition.TextChange;
-import android.view.transition.Transition;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
import android.widget.RadioButton;
public class InterruptionTest extends Activity {
@@ -35,7 +32,8 @@ public class InterruptionTest extends Activity {
private Scene mScene2;
private Scene mScene3;
private Scene mScene4;
- TransitionGroup mSequencedMove = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
+ TransitionSet mSequencedMove = new TransitionSet().
+ setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -44,24 +42,22 @@ public class InterruptionTest extends Activity {
ViewGroup sceneRoot = (ViewGroup) findViewById(R.id.sceneRoot);
- mScene1 = new Scene(sceneRoot, R.layout.interruption_inner_1, this);
- mScene2 = new Scene(sceneRoot, R.layout.interruption_inner_2, this);
- mScene3 = new Scene(sceneRoot, R.layout.interruption_inner_3, this);
- mScene4 = new Scene(sceneRoot, R.layout.interruption_inner_4, this);
+ mScene1 = Scene.getSceneForLayout(sceneRoot, R.layout.interruption_inner_1, this);
+ mScene2 = Scene.getSceneForLayout(sceneRoot, R.layout.interruption_inner_2, this);
+ mScene3 = Scene.getSceneForLayout(sceneRoot, R.layout.interruption_inner_3, this);
+ mScene4 = Scene.getSceneForLayout(sceneRoot, R.layout.interruption_inner_4, this);
mScene1RB = (RadioButton) findViewById(R.id.scene1RB);
mScene2RB = (RadioButton) findViewById(R.id.scene2RB);
mScene3RB = (RadioButton) findViewById(R.id.scene3RB);
mScene4RB = (RadioButton) findViewById(R.id.scene4RB);
- sceneRoot.setCurrentScene(mScene1);
+ ChangeBounds changeBounds1 = new ChangeBounds();
+ changeBounds1.addTargetId(R.id.button);
+ ChangeBounds changeBounds2 = new ChangeBounds();
+ changeBounds2.addTargetId(R.id.button1);
- Move move1 = new Move();
- move1.setTargetIds(R.id.button);
- Move move2 = new Move();
- move2.setTargetIds(R.id.button1);
-
- mSequencedMove.addTransitions(move1, move2);
+ mSequencedMove.addTransition(changeBounds1).addTransition(changeBounds2);
mSequencedMove.setDuration(1000);
}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java b/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
index 87ee874..6629770 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
@@ -20,18 +20,18 @@ import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.ViewTreeObserver;
-import android.view.transition.Fade;
-import android.view.transition.Scene;
+import android.transition.Fade;
+import android.transition.Scene;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
-import android.view.transition.AutoTransition;
-import android.view.transition.Move;
-import android.view.transition.Transition;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.AutoTransition;
+import android.transition.ChangeBounds;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
import java.util.ArrayList;
import java.util.HashMap;
@@ -78,10 +78,11 @@ public class ListViewAddRemove extends Activity {
}
});
final Transition myTransition = new AutoTransition();
- final TransitionGroup noFadeIn = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
+ final TransitionSet noFadeIn = new TransitionSet().
+ setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
Fade fadeIn = new Fade(Fade.IN);
fadeIn.setDuration(50);
- noFadeIn.addTransitions(new Fade(Fade.OUT), new Move(), fadeIn);
+ noFadeIn.addTransition(new Fade(Fade.OUT)).addTransition(new ChangeBounds()).addTransition(fadeIn);
myTransition.addListener(new Transition.TransitionListenerAdapter() {
@Override
diff --git a/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java b/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java
index 06fa9f4..34ec6cc 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java
@@ -19,14 +19,14 @@ import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Scene;
+import android.transition.Scene;
import android.widget.TextView;
-import android.view.transition.Fade;
-import android.view.transition.Recolor;
-import android.view.transition.Slide;
-import android.view.transition.Transition;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.Recolor;
+import android.transition.Slide;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
public class LoginActivity extends Activity {
@@ -43,32 +43,33 @@ public class LoginActivity extends Activity {
View container = (View) findViewById(R.id.container);
mSceneRoot = (ViewGroup) container.getParent();
- mLoginScene = new Scene(mSceneRoot, R.layout.activity_login, this);
- mPasswordScene = new Scene(mSceneRoot, R.layout.login_password, this);
- mIncorrectPasswordScene = new Scene(mSceneRoot, R.layout.incorrect_password, this);
- mUsernameTakenScene = new Scene(mSceneRoot, R.layout.username_taken, this);
- mSuccessScene = new Scene(mSceneRoot, R.layout.success, this);
- mNewUserScene = new Scene(mSceneRoot, R.layout.new_user, this);
+ mLoginScene = Scene.getSceneForLayout(mSceneRoot, R.layout.activity_login, this);
+ mPasswordScene = Scene.getSceneForLayout(mSceneRoot, R.layout.login_password, this);
+ mIncorrectPasswordScene = Scene.getSceneForLayout(mSceneRoot, R.layout.incorrect_password, this);
+ mUsernameTakenScene = Scene.getSceneForLayout(mSceneRoot, R.layout.username_taken, this);
+ mSuccessScene = Scene.getSceneForLayout(mSceneRoot, R.layout.success, this);
+ mNewUserScene = Scene.getSceneForLayout(mSceneRoot, R.layout.new_user, this);
mTransitionManager = new TransitionManager();
// Custom transitions in/out of NewUser screen - slide in the 2nd password UI
- TransitionGroup slider = new TransitionGroup();
- slider.addTransitions(new Slide().setTargetIds(R.id.retype, R.id.retypeEdit));
- slider.addTransitions(new Recolor().setTargetIds(R.id.password, R.id.passwordEdit));
- slider.addTransitions(new Fade());
+ TransitionSet slider = new TransitionSet();
+ slider.addTransition(new Slide().addTargetId(R.id.retype).addTargetId(R.id.retypeEdit));
+ slider.addTransition(new Recolor().addTargetId(R.id.password).
+ addTargetId(R.id.passwordEdit));
+ slider.addTransition(new Fade());
mTransitionManager.setTransition(mLoginScene, mNewUserScene, slider);
mTransitionManager.setTransition(mPasswordScene, mNewUserScene, slider);
mTransitionManager.setTransition(mNewUserScene, mLoginScene, slider);
mTransitionManager.setTransition(mNewUserScene, mPasswordScene, slider);
// Custom transitions with recoloring password field
- Transition colorizer = new Recolor().setTargetIds(R.id.password, R.id.passwordEdit);
+ Transition colorizer = new Recolor().addTargetId(R.id.password).
+ addTargetId(R.id.passwordEdit);
mTransitionManager.setTransition(mLoginScene, mPasswordScene, colorizer);
mTransitionManager.setTransition(mPasswordScene, mLoginScene, colorizer);
mCurrentScene = mLoginScene;
- mSceneRoot.setCurrentScene(mLoginScene);
}
public void applyScene(Scene scene) {
diff --git a/tests/TransitionTests/src/com/android/transitiontests/LoginActivityFromResources.java b/tests/TransitionTests/src/com/android/transitiontests/LoginActivityFromResources.java
index ff617aa..600c791 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/LoginActivityFromResources.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/LoginActivityFromResources.java
@@ -19,10 +19,10 @@ import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Scene;
-import android.view.transition.TransitionInflater;
+import android.transition.Scene;
+import android.transition.TransitionInflater;
import android.widget.TextView;
-import android.view.transition.TransitionManager;
+import android.transition.TransitionManager;
public class LoginActivityFromResources extends Activity {
@@ -36,7 +36,7 @@ public class LoginActivityFromResources extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
- View container = (View) findViewById(R.id.container);
+ View container = findViewById(R.id.container);
mSceneRoot = (ViewGroup) container.getParent();
}
@@ -50,21 +50,19 @@ public class LoginActivityFromResources extends Activity {
if (mTransitionManager == null) {
TransitionInflater inflater = TransitionInflater.from(this);
- mLoginScene = inflater.inflateScene(R.scene.login_scene, mSceneRoot);
- mPasswordScene = inflater.inflateScene(R.scene.password_scene, mSceneRoot);
- mIncorrectPasswordScene =
- inflater.inflateScene(R.scene.incorrect_password_scene,mSceneRoot);
- mUsernameTakenScene =
- inflater.inflateScene(R.scene.username_taken_scene, mSceneRoot);
- mSuccessScene = inflater.inflateScene(R.scene.success_scene, mSceneRoot);
- mNewUserScene = inflater.inflateScene(R.scene.new_user_scene, mSceneRoot);
+ mLoginScene = Scene.getSceneForLayout(mSceneRoot, R.layout.activity_login, this);
+ mPasswordScene = Scene.getSceneForLayout(mSceneRoot, R.layout.login_password, this);
+ mIncorrectPasswordScene = Scene.getSceneForLayout(mSceneRoot, R.layout
+ .incorrect_password, this);
+ mUsernameTakenScene = Scene.getSceneForLayout(mSceneRoot, R.layout.username_taken, this);
+ mSuccessScene = Scene.getSceneForLayout(mSceneRoot, R.layout.success, this);
+ mNewUserScene = Scene.getSceneForLayout(mSceneRoot, R.layout.new_user, this);
mTransitionManager =
inflater.inflateTransitionManager(R.transition.login_transition_mgr,
mSceneRoot);
mCurrentScene = mLoginScene;
- mSceneRoot.setCurrentScene(mLoginScene);
}
TextView textView = (TextView) view;
CharSequence text = textView.getText();
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Reparenting.java b/tests/TransitionTests/src/com/android/transitiontests/Reparenting.java
index e559c72..1ee8621 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Reparenting.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Reparenting.java
@@ -17,11 +17,11 @@ package com.android.transitiontests;
import android.app.Activity;
import android.os.Bundle;
+import android.transition.ChangeBounds;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Move;
-import android.view.transition.Scene;
-import android.view.transition.TransitionManager;
+import android.transition.Scene;
+import android.transition.TransitionManager;
import android.widget.Button;
public class Reparenting extends Activity {
@@ -67,7 +67,7 @@ public class Reparenting extends Activity {
newParent.addView(v);
}
});
- Move reparent = new Move();
+ ChangeBounds reparent = new ChangeBounds();
reparent.setReparent(true);
TransitionManager.go(newScene, reparent);
}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ResourceLoadingTest.java b/tests/TransitionTests/src/com/android/transitiontests/ResourceLoadingTest.java
index 3d7bd9b..1aee258 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ResourceLoadingTest.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ResourceLoadingTest.java
@@ -19,10 +19,10 @@ import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Scene;
-import android.view.transition.TransitionInflater;
-import android.view.transition.Transition;
-import android.view.transition.TransitionManager;
+import android.transition.Scene;
+import android.transition.TransitionInflater;
+import android.transition.Transition;
+import android.transition.TransitionManager;
public class ResourceLoadingTest extends Activity {
@@ -54,7 +54,7 @@ public class ResourceLoadingTest extends Activity {
mTransitionManager =
inflater.inflateTransitionManager(R.transition.my_transition_mgr,
mSceneRoot);
- Scene loadedScene = inflater.inflateScene(R.scene.my_scene, mSceneRoot);
+ Scene loadedScene = new Scene(mSceneRoot);
System.out.println("loadedScene = " + loadedScene);
Transition loadedTransition = inflater.inflateTransition(R.transition.my_transition);
System.out.println("loadedTransition = " + loadedTransition);
@@ -63,11 +63,11 @@ public class ResourceLoadingTest extends Activity {
}
}
if (mCurrentScene == RESULTS_SCREEN) {
- Scene scene = mInflater.inflateScene(R.scene.search_scene, mSceneRoot);
+ Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
mTransitionManager.transitionTo(scene);
mCurrentScene = SEARCH_SCREEN;
} else {
- Scene scene = mInflater.inflateScene(R.scene.results_scene, mSceneRoot);
+ Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
mTransitionManager.transitionTo(scene);
mCurrentScene = RESULTS_SCREEN;
}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTargets.java b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTargets.java
index 374a9ab..7504058 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTargets.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTargets.java
@@ -18,14 +18,14 @@ package com.android.transitiontests;
import android.app.Activity;
import android.os.Bundle;
+import android.transition.ChangeBounds;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.Recolor;
-import android.view.transition.Scene;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.Recolor;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
public class ScenesTestAutoTargets extends Activity {
@@ -42,11 +42,11 @@ public class ScenesTestAutoTargets extends Activity {
View container = (View) findViewById(R.id.container);
mSceneRoot = (ViewGroup) container.getParent();
- mSearchScreen = new Scene(mSceneRoot, R.layout.search_screen, this);
- mResultsScreen = new Scene(mSceneRoot, R.layout.results_screen, this);
+ mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+ mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
- TransitionGroup transition = new TransitionGroup();
- transition.addTransitions(new Fade(), new Move(), new Recolor());
+ TransitionSet transition = new TransitionSet();
+ transition.addTransition(new Fade()).addTransition(new ChangeBounds()).addTransition(new Recolor());
mTransitionManager = new TransitionManager();
mTransitionManager.setTransition(mSearchScreen, transition);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition.java b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition.java
index fb1ba07..23b28ec 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition.java
@@ -20,10 +20,10 @@ import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.AutoTransition;
-import android.view.transition.Scene;
-import android.view.transition.Transition;
-import android.view.transition.TransitionManager;
+import android.transition.AutoTransition;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionManager;
public class ScenesTestAutoTransition extends Activity {
@@ -40,8 +40,8 @@ public class ScenesTestAutoTransition extends Activity {
View container = (View) findViewById(R.id.container);
mSceneRoot = (ViewGroup) container.getParent();
- mSearchScreen = new Scene(mSceneRoot, R.layout.search_screen, this);
- mResultsScreen = new Scene(mSceneRoot, R.layout.results_screen, this);
+ mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+ mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
}
public void sendMessage(View view) {
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition2.java b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition2.java
index c75d419..5a9fa9d 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition2.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition2.java
@@ -20,8 +20,8 @@ import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Scene;
-import android.view.transition.TransitionManager;
+import android.transition.Scene;
+import android.transition.TransitionManager;
public class ScenesTestAutoTransition2 extends Activity {
@@ -38,8 +38,8 @@ public class ScenesTestAutoTransition2 extends Activity {
View container = (View) findViewById(R.id.container);
mSceneRoot = (ViewGroup) container.getParent();
- mSearchScreen = new Scene(mSceneRoot, R.layout.search_screen, this);
- mResultsScreen = new Scene(mSceneRoot, R.layout.results_screen, this);
+ mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+ mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
}
public void sendMessage(View view) {
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java
index 399c2be..c6011f2 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java
@@ -18,14 +18,14 @@ package com.android.transitiontests;
import android.app.Activity;
import android.os.Bundle;
+import android.transition.ChangeBounds;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.Recolor;
-import android.view.transition.Scene;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.Recolor;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
public class ScenesTestv21 extends Activity {
@@ -42,21 +42,22 @@ public class ScenesTestv21 extends Activity {
View container = (View) findViewById(R.id.container);
mSceneRoot = (ViewGroup) container.getParent();
- mSearchScreen = new Scene(mSceneRoot, R.layout.search_screen, this);
- mResultsScreen = new Scene(mSceneRoot, R.layout.results_screen, this);
+ mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+ mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
- TransitionGroup transitionToResults = new TransitionGroup();
+ TransitionSet transitionToResults = new TransitionSet();
Fade fade = new Fade();
- fade.setTargetIds(R.id.resultsText, R.id.resultsList);
+ fade.addTargetId(R.id.resultsText).addTargetId(R.id.resultsList);
fade.setStartDelay(300);
- transitionToResults.addTransitions(fade);
- transitionToResults.addTransitions(new Move().setTargetIds(R.id.searchContainer));
- transitionToResults.addTransitions(new Recolor().setTargetIds(R.id.container));
+ transitionToResults.addTransition(fade);
+ transitionToResults.addTransition(new ChangeBounds().addTargetId(R.id.searchContainer));
+ transitionToResults.addTransition(new Recolor().addTargetId(R.id.container));
- TransitionGroup transitionToSearch = new TransitionGroup();
- transitionToSearch.addTransitions(new Fade().setTargetIds(R.id.resultsText, R.id.resultsList));
- transitionToSearch.addTransitions(new Move().setTargetIds(R.id.searchContainer));
- transitionToSearch.addTransitions(new Recolor().setTargetIds(R.id.container));
+ TransitionSet transitionToSearch = new TransitionSet();
+ transitionToSearch.addTransition(new Fade().addTargetId(R.id.resultsText).
+ addTargetId(R.id.resultsList));
+ transitionToSearch.addTransition(new ChangeBounds().addTargetId(R.id.searchContainer));
+ transitionToSearch.addTransition(new Recolor().addTargetId(R.id.container));
mTransitionManager = new TransitionManager();
mTransitionManager.setTransition(mSearchScreen, transitionToSearch);
mTransitionManager.setTransition(mResultsScreen, transitionToResults);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java b/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java
index 6b34420..ab1dc26 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java
@@ -19,13 +19,13 @@ import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Scene;
-import android.view.transition.Transition;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionSet;
import android.widget.Button;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.ChangeBounds;
+import android.transition.TransitionManager;
public class SequenceTest extends Activity {
@@ -33,7 +33,8 @@ public class SequenceTest extends Activity {
Button mRemovingButton, mInvisibleButton, mGoneButton;
Scene mScene1, mScene2;
ViewGroup mSceneRoot;
- TransitionGroup sequencedFade, reverseSequencedFade;
+ TransitionSet sequencedFade, reverseSequencedFade;
+ Scene mCurrentScene;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -47,27 +48,33 @@ public class SequenceTest extends Activity {
mInvisibleButton = (Button) findViewById(R.id.invisibleButton);
mGoneButton = (Button) findViewById(R.id.goneButton);
- mScene1 = new Scene(mSceneRoot, R.layout.fading_test, this);
- mScene2 = new Scene(mSceneRoot, R.layout.fading_test_scene_2, this);
+ mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test, this);
+ mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test_scene_2, this);
- Transition fade1 = new Fade().setTargetIds(R.id.removingButton);
- Transition fade2 = new Fade().setTargetIds(R.id.invisibleButton);
- Transition fade3 = new Fade().setTargetIds(R.id.goneButton);
- TransitionGroup fader = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
- fader.addTransitions(fade1, fade2, fade3, new Move());
+ Transition fade1 = new Fade().addTargetId(R.id.removingButton);
+ Transition fade2 = new Fade().addTargetId(R.id.invisibleButton);
+ Transition fade3 = new Fade().addTargetId(R.id.goneButton);
+ TransitionSet fader = new TransitionSet().
+ setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+ fader.addTransition(fade1).addTransition(fade2).addTransition(fade3).
+ addTransition(new ChangeBounds());
sequencedFade = fader;
- reverseSequencedFade = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
- reverseSequencedFade.addTransitions(new Move(), fade3, fade2, fade1);
+ reverseSequencedFade = new TransitionSet().
+ setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+ reverseSequencedFade.addTransition(new ChangeBounds()).addTransition(fade3).addTransition(fade2).
+ addTransition(fade1);
- mSceneRoot.setCurrentScene(mScene1);
+ mCurrentScene = mScene1;
}
public void sendMessage(View view) {
- if (mSceneRoot.getCurrentScene() == mScene1) {
+ if (mCurrentScene == mScene1) {
TransitionManager.go(mScene2, sequencedFade);
+ mCurrentScene = mScene2;
} else {
TransitionManager.go(mScene1, reverseSequencedFade);
+ mCurrentScene = mScene1;
}
}
}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java b/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java
index 972d30e..52c21c9 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java
@@ -17,15 +17,15 @@ package com.android.transitiontests;
import android.app.Activity;
import android.os.Bundle;
+import android.transition.ChangeBounds;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Scene;
+import android.transition.Scene;
+import android.transition.TransitionSet;
import android.widget.Button;
-import android.view.transition.Fade;
-import android.view.transition.Move;
-import android.view.transition.Transition;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Fade;
+import android.transition.Transition;
+import android.transition.TransitionManager;
public class SequenceTestSimple extends Activity {
@@ -34,7 +34,8 @@ public class SequenceTestSimple extends Activity {
Scene mScene1, mScene2;
ViewGroup mSceneRoot;
Transition sequencedFade;
- TransitionGroup sequencedFadeReverse;
+ TransitionSet sequencedFadeReverse;
+ Scene mCurrentScene;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -46,25 +47,29 @@ public class SequenceTestSimple extends Activity {
mRemovingButton = (Button) findViewById(R.id.removingButton);
- mScene1 = new Scene(mSceneRoot, R.layout.fading_test_simple, this);
- mScene2 = new Scene(mSceneRoot, R.layout.fading_test_simple2, this);
+ mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test_simple, this);
+ mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test_simple2, this);
- TransitionGroup fader = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
- fader.addTransitions(new Fade().setTargetIds(R.id.removingButton));
- fader.addTransitions(new Move().setTargetIds(R.id.sceneSwitchButton));
+ TransitionSet fader = new TransitionSet().
+ setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+ fader.addTransition(new Fade().addTargetId(R.id.removingButton));
+ fader.addTransition(new ChangeBounds().addTargetId(R.id.sceneSwitchButton));
sequencedFade = fader;
- sequencedFadeReverse = new TransitionGroup(TransitionGroup.SEQUENTIALLY);
- sequencedFadeReverse.addTransitions(new Move().setTargetIds(R.id.sceneSwitchButton));
- sequencedFadeReverse.addTransitions(new Fade().setTargetIds(R.id.removingButton));
+ sequencedFadeReverse = new TransitionSet().
+ setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+ sequencedFadeReverse.addTransition(new ChangeBounds().addTargetId(R.id.sceneSwitchButton));
+ sequencedFadeReverse.addTransition(new Fade().addTargetId(R.id.removingButton));
- mSceneRoot.setCurrentScene(mScene1);
+ mCurrentScene = mScene1;
}
public void sendMessage(View view) {
- if (mSceneRoot.getCurrentScene() == mScene1) {
+ if (mCurrentScene == mScene1) {
TransitionManager.go(mScene2, sequencedFade);
+ mCurrentScene = mScene2;
} else {
TransitionManager.go(mScene1, sequencedFadeReverse);
+ mCurrentScene = mScene1;
}
}}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java b/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java
index aa76923..05af044 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java
@@ -27,11 +27,11 @@ import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Crossfade;
-import android.view.transition.Move;
-import android.view.transition.Scene;
-import android.view.transition.TransitionGroup;
-import android.view.transition.TransitionManager;
+import android.transition.Crossfade;
+import android.transition.ChangeBounds;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
import android.widget.Button;
import static android.widget.LinearLayout.LayoutParams;
@@ -66,8 +66,9 @@ public class SurfaceAndTextureViews extends Activity {
mTextureView.setLayoutParams(new LayoutParams(SMALL_SIZE, SMALL_SIZE));
container.addView(mTextureView);
- final TransitionGroup transition = new TransitionGroup();
- transition.addTransitions(new Move(), new Crossfade().setTargetIds(0, 1, 2));
+ final TransitionSet transition = new TransitionSet();
+ transition.addTransition(new ChangeBounds()).addTransition(new Crossfade().addTargetId(0).
+ addTargetId(1).addTargetId(2));
toggleButton.setOnClickListener(new View.OnClickListener() {
@Override
diff --git a/tests/TransitionTests/src/com/android/transitiontests/UniqueIds.java b/tests/TransitionTests/src/com/android/transitiontests/UniqueIds.java
index 433a91c..c824956 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/UniqueIds.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/UniqueIds.java
@@ -20,11 +20,11 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.transition.Scene;
-import android.view.transition.Transition;
+import android.transition.Scene;
+import android.transition.Transition;
import android.widget.Button;
import android.widget.LinearLayout;
-import android.view.transition.TransitionManager;
+import android.transition.TransitionManager;
import java.util.HashMap;
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index d617928..08ad7a0 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -172,7 +172,7 @@ private:
bool isValidResourceType(const String8& type)
{
return type == "anim" || type == "animator" || type == "interpolator"
- || type == "transition" || type == "scene"
+ || type == "transition"
|| type == "drawable" || type == "layout"
|| type == "values" || type == "xml" || type == "raw"
|| type == "color" || type == "menu" || type == "mipmap";
@@ -934,7 +934,6 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets)
sp<ResourceTypeSet> animators;
sp<ResourceTypeSet> interpolators;
sp<ResourceTypeSet> transitions;
- sp<ResourceTypeSet> scenes;
sp<ResourceTypeSet> xmls;
sp<ResourceTypeSet> raws;
sp<ResourceTypeSet> colors;
@@ -947,7 +946,6 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets)
ASSIGN_IT(animator);
ASSIGN_IT(interpolator);
ASSIGN_IT(transition);
- ASSIGN_IT(scene);
ASSIGN_IT(xml);
ASSIGN_IT(raw);
ASSIGN_IT(color);
@@ -971,7 +969,6 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets)
!applyFileOverlay(bundle, assets, &animators, "animator") ||
!applyFileOverlay(bundle, assets, &interpolators, "interpolator") ||
!applyFileOverlay(bundle, assets, &transitions, "transition") ||
- !applyFileOverlay(bundle, assets, &scenes, "scene") ||
!applyFileOverlay(bundle, assets, &xmls, "xml") ||
!applyFileOverlay(bundle, assets, &raws, "raw") ||
!applyFileOverlay(bundle, assets, &colors, "color") ||
@@ -1038,13 +1035,6 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets)
}
}
- if (scenes != NULL) {
- err = makeFileResources(bundle, assets, &table, scenes, "scene");
- if (err != NO_ERROR) {
- hasErrors = true;
- }
- }
-
if (interpolators != NULL) {
err = makeFileResources(bundle, assets, &table, interpolators, "interpolator");
if (err != NO_ERROR) {
@@ -1204,21 +1194,6 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets)
err = NO_ERROR;
}
- if (scenes != NULL) {
- ResourceDirIterator it(scenes, String8("scene"));
- while ((err=it.next()) == NO_ERROR) {
- err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
- if (err != NO_ERROR) {
- hasErrors = true;
- }
- }
-
- if (err < NO_ERROR) {
- hasErrors = true;
- }
- err = NO_ERROR;
- }
-
if (xmls != NULL) {
ResourceDirIterator it(xmls, String8("xml"));
while ((err=it.next()) == NO_ERROR) {