summaryrefslogtreecommitdiffstats
path: root/v4
diff options
context:
space:
mode:
Diffstat (limited to 'v4')
-rw-r--r--v4/Android.mk58
-rw-r--r--v4/api/23.0.0.txt (renamed from v4/api/23.txt)0
-rw-r--r--v4/api/23.1.0.txt3520
-rw-r--r--v4/api/current.txt178
-rw-r--r--v4/api21/android/content/pm/ParceledListSlice.java70
-rw-r--r--v4/api21/android/service/media/IMediaBrowserService.java65
-rw-r--r--v4/api21/android/service/media/IMediaBrowserServiceCallbacks.java91
-rw-r--r--v4/api21/android/support/v4/app/ActivityCompat21.java5
-rw-r--r--v4/api21/android/support/v4/graphics/drawable/DrawableCompatLollipop.java42
-rw-r--r--v4/api21/android/support/v4/graphics/drawable/DrawableWrapperLollipop.java52
-rw-r--r--v4/api21/android/support/v4/media/MediaBrowserCompatApi21.java153
-rw-r--r--v4/api21/android/support/v4/media/MediaBrowserServiceCompatApi21.java165
-rw-r--r--v4/api21/android/support/v4/media/MediaDescriptionCompatApi21.java4
-rw-r--r--v4/api21/android/support/v4/media/MediaMetadataCompatApi21.java9
-rw-r--r--v4/api21/android/support/v4/media/session/MediaSessionCompatApi21.java2
-rw-r--r--v4/api22/android/support/v4/graphics/drawable/DrawableCompatApi22.java4
-rw-r--r--v4/api23/android/support/v4/app/AppOpsManagerCompat23.java2
-rw-r--r--v4/api23/android/support/v4/content/ResourcesCompatApi23.java33
-rw-r--r--v4/api23/android/support/v4/media/MediaBrowserCompatApi23.java57
-rw-r--r--v4/api23/android/support/v4/media/MediaBrowserServiceCompatApi23.java86
-rw-r--r--v4/api23/android/support/v4/text/ICUCompatApi23.java2
-rw-r--r--v4/api23/android/support/v4/view/ViewCompatMarshmallow.java33
-rw-r--r--v4/api23/android/support/v4/widget/TextViewCompatApi23.java27
-rw-r--r--v4/build.gradle25
-rw-r--r--v4/donut/android/support/v4/animation/ValueAnimatorCompat.java2
-rw-r--r--v4/donut/android/support/v4/graphics/drawable/DrawableCompatBase.java6
-rw-r--r--v4/donut/android/support/v4/graphics/drawable/DrawableWrapper.java6
-rw-r--r--v4/donut/android/support/v4/graphics/drawable/DrawableWrapperDonut.java52
-rw-r--r--v4/froyo/android/support/v4/media/session/MediaSessionCompatApi8.java2
-rw-r--r--v4/gingerbread/android/support/v4/widget/ScrollerCompatGingerbread.java5
-rw-r--r--v4/honeycomb/android/support/v4/content/ExecutorCompatHoneycomb.java31
-rw-r--r--v4/ics-mr1/android/support/v4/view/ViewCompatICSMr1.java32
-rw-r--r--v4/ics/android/support/v4/media/session/MediaSessionCompatApi14.java4
-rw-r--r--v4/ics/android/support/v4/view/ViewParentCompatICS.java2
-rw-r--r--v4/java/android/support/v4/animation/AnimatorCompatHelper.java11
-rw-r--r--v4/java/android/support/v4/app/FragmentActivity.java36
-rw-r--r--v4/java/android/support/v4/app/FragmentManager.java65
-rw-r--r--v4/java/android/support/v4/app/NotificationCompat.java2
-rw-r--r--v4/java/android/support/v4/content/ContextCompat.java4
-rw-r--r--v4/java/android/support/v4/content/ParallelExecutorCompat.java36
-rw-r--r--v4/java/android/support/v4/content/res/ResourcesCompat.java89
-rw-r--r--v4/java/android/support/v4/graphics/ColorUtils.java40
-rw-r--r--v4/java/android/support/v4/graphics/drawable/DrawableCompat.java2
-rw-r--r--v4/java/android/support/v4/media/MediaBrowserCompat.java1243
-rw-r--r--v4/java/android/support/v4/media/MediaBrowserProtocol.java126
-rw-r--r--v4/java/android/support/v4/media/MediaBrowserServiceCompat.java803
-rw-r--r--v4/java/android/support/v4/media/MediaMetadataCompat.java79
-rw-r--r--v4/java/android/support/v4/media/session/MediaButtonReceiver.java129
-rw-r--r--v4/java/android/support/v4/media/session/MediaControllerCompat.java16
-rw-r--r--v4/java/android/support/v4/media/session/MediaSessionCompat.java93
-rw-r--r--v4/java/android/support/v4/os/IResultReceiver.aidl24
-rw-r--r--v4/java/android/support/v4/os/ResultReceiver.aidl19
-rw-r--r--v4/java/android/support/v4/os/ResultReceiver.java143
-rw-r--r--v4/java/android/support/v4/view/ActionProvider.java57
-rw-r--r--v4/java/android/support/v4/view/PagerAdapter.java14
-rw-r--r--v4/java/android/support/v4/view/ViewCompat.java198
-rw-r--r--v4/java/android/support/v4/view/ViewPager.java84
-rw-r--r--v4/java/android/support/v4/widget/DrawerLayout.java194
-rw-r--r--v4/java/android/support/v4/widget/NestedScrollView.java110
-rw-r--r--v4/java/android/support/v4/widget/ScrollerCompat.java31
-rw-r--r--v4/java/android/support/v4/widget/SwipeRefreshLayout.java160
-rw-r--r--v4/java/android/support/v4/widget/TextViewCompat.java90
-rw-r--r--v4/java/android/support/v4/widget/TextViewCompatDonut.java98
-rw-r--r--v4/jellybean-mr1/android/support/v4/text/TextUtilsCompatJellybeanMr1.java2
-rw-r--r--v4/jellybean-mr2/android/support/v4/media/TransportMediatorJellybeanMR2.java33
-rw-r--r--v4/jellybean-mr2/android/support/v4/media/session/MediaSessionCompatApi18.java38
-rw-r--r--v4/jellybean/android/support/v4/widget/TextViewCompatJb.java31
-rw-r--r--v4/kitkat/android/support/v4/media/session/MediaSessionCompatApi19.java3
-rw-r--r--v4/kitkat/android/support/v4/view/ViewPropertyAnimatorCompatKK.java16
-rw-r--r--v4/tests/AndroidManifest.xml32
-rw-r--r--v4/tests/java/android/support/v4/graphics/ColorUtilsTest.java76
-rw-r--r--v4/tests/java/android/support/v4/widget/TestActivity.java35
-rw-r--r--v4/tests/java/android/support/v4/widget/TextViewCompatTest.java79
-rw-r--r--v4/tests/java/android/support/v4/widget/test/TextViewTestActivity.java24
74 files changed, 8739 insertions, 451 deletions
diff --git a/v4/Android.mk b/v4/Android.mk
index 2050725c2a..4336e40928 100644
--- a/v4/Android.mk
+++ b/v4/Android.mk
@@ -22,6 +22,9 @@ LOCAL_SRC_FILES := $(call all-java-files-under, donut)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-annotations
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files := $(LOCAL_SRC_FILES)
+support_module_java_libraries := android-support-annotations
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of Eclair APIs.
@@ -32,6 +35,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, eclair)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-donut
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of Eclair MR1 APIs.
@@ -42,6 +47,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, eclair-mr1)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-eclair
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of Froyo APIs.
@@ -52,6 +59,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, froyo)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-eclair-mr1
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of Gingerbread APIs.
@@ -62,6 +71,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, gingerbread)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-froyo
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of Honeycomb APIs.
@@ -72,6 +83,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, honeycomb)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-gingerbread
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of Honeycomb MR1 APIs.
@@ -82,6 +95,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, honeycomb_mr1)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-honeycomb
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of Honeycomb MR2 APIs.
@@ -92,6 +107,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, honeycomb_mr2)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-honeycomb-mr1
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of Ice Cream Sandwich APIs.
@@ -102,6 +119,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, ics)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-honeycomb-mr2
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of Ice Cream Sandwich MR1 APIs.
@@ -112,6 +131,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, ics-mr1)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-ics
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of JellyBean APIs.
@@ -122,6 +143,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, jellybean)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-ics-mr1
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of JellyBean MR1 APIs.
@@ -132,6 +155,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, jellybean-mr1)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-jellybean
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of JellyBean MR2 APIs.
@@ -142,6 +167,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, jellybean-mr2)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-jellybean-mr1
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of KitKat APIs.
@@ -152,6 +179,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, kitkat)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-jellybean-mr2
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of V20 APIs.
@@ -162,16 +191,33 @@ LOCAL_SRC_FILES := $(call all-java-files-under, api20)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-kitkat
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
+# -----------------------------------------------------------------------
+
+# A helper sub-library that allows to use Lollipop internal APIs.
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-v4-api21-internal
+LOCAL_SDK_VERSION := 21
+LOCAL_SRC_FILES := \
+ $(call all-java-files-under, api21/android/content/pm) \
+ $(call all-java-files-under, api21/android/service/media)
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_JAVA_LIBRARY)
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of Lollipop APIs.
include $(CLEAR_VARS)
LOCAL_MODULE := android-support-v4-api21
LOCAL_SDK_VERSION := 21
-LOCAL_SRC_FILES := $(call all-java-files-under, api21)
+LOCAL_SRC_FILES := $(call all-java-files-under, api21/android/support)
+LOCAL_JAVA_LIBRARIES := android-support-v4-api21-internal
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-api20
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of V22 APIs.
@@ -182,6 +228,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, api22)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-api21
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
# -----------------------------------------------------------------------
# A helper sub-library that makes direct use of V23 APIs.
@@ -189,9 +237,12 @@ include $(CLEAR_VARS)
LOCAL_MODULE := android-support-v4-api23
LOCAL_SDK_VERSION := current
LOCAL_SRC_FILES := $(call all-java-files-under, api23)
+LOCAL_JAVA_LIBRARIES := android-support-v4-api21-internal
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4-api22
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+
# -----------------------------------------------------------------------
# Here is the final static library that apps can link against.
@@ -204,11 +255,12 @@ LOCAL_SRC_FILES := $(call all-java-files-under, java) \
LOCAL_STATIC_JAVA_LIBRARIES += android-support-v4-api23
include $(BUILD_STATIC_JAVA_LIBRARY)
+support_module_src_files += $(LOCAL_SRC_FILES)
+support_module_aidl_includes := $(LOCAL_AIDL_INCLUDES)
+
# API Check
# ---------------------------------------------
support_module := $(LOCAL_MODULE)
support_module_api_dir := $(LOCAL_PATH)/api
-support_module_src_files := $(LOCAL_SRC_FILES)
-support_module_java_libraries := android-support-v4
support_module_java_packages := android.support.v4.*
include $(SUPPORT_API_CHECK)
diff --git a/v4/api/23.txt b/v4/api/23.0.0.txt
index 27d5993e8b..27d5993e8b 100644
--- a/v4/api/23.txt
+++ b/v4/api/23.0.0.txt
diff --git a/v4/api/23.1.0.txt b/v4/api/23.1.0.txt
new file mode 100644
index 0000000000..ccefe22f49
--- /dev/null
+++ b/v4/api/23.1.0.txt
@@ -0,0 +1,3520 @@
+package android.support.v4.accessibilityservice {
+
+ public class AccessibilityServiceInfoCompat {
+ method public static java.lang.String capabilityToString(int);
+ method public static java.lang.String feedbackTypeToString(int);
+ method public static java.lang.String flagToString(int);
+ method public static boolean getCanRetrieveWindowContent(android.accessibilityservice.AccessibilityServiceInfo);
+ method public static int getCapabilities(android.accessibilityservice.AccessibilityServiceInfo);
+ method public static java.lang.String getDescription(android.accessibilityservice.AccessibilityServiceInfo);
+ method public static java.lang.String getId(android.accessibilityservice.AccessibilityServiceInfo);
+ method public static android.content.pm.ResolveInfo getResolveInfo(android.accessibilityservice.AccessibilityServiceInfo);
+ method public static java.lang.String getSettingsActivityName(android.accessibilityservice.AccessibilityServiceInfo);
+ field public static final int CAPABILITY_CAN_FILTER_KEY_EVENTS = 8; // 0x8
+ field public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
+ field public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 2; // 0x2
+ field public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 1; // 0x1
+ field public static final int DEFAULT = 1; // 0x1
+ field public static final int FEEDBACK_ALL_MASK = -1; // 0xffffffff
+ field public static final int FEEDBACK_BRAILLE = 32; // 0x20
+ field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
+ field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
+ field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
+ field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
+ field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
+ }
+
+}
+
+package android.support.v4.animation {
+
+ public abstract class AnimatorCompatHelper {
+ method public static void clearInterpolator(android.view.View);
+ method public static android.support.v4.animation.ValueAnimatorCompat emptyValueAnimator();
+ }
+
+ public abstract interface AnimatorListenerCompat {
+ method public abstract void onAnimationCancel(android.support.v4.animation.ValueAnimatorCompat);
+ method public abstract void onAnimationEnd(android.support.v4.animation.ValueAnimatorCompat);
+ method public abstract void onAnimationRepeat(android.support.v4.animation.ValueAnimatorCompat);
+ method public abstract void onAnimationStart(android.support.v4.animation.ValueAnimatorCompat);
+ }
+
+ public abstract interface AnimatorUpdateListenerCompat {
+ method public abstract void onAnimationUpdate(android.support.v4.animation.ValueAnimatorCompat);
+ }
+
+ public abstract interface ValueAnimatorCompat {
+ method public abstract void addListener(android.support.v4.animation.AnimatorListenerCompat);
+ method public abstract void addUpdateListener(android.support.v4.animation.AnimatorUpdateListenerCompat);
+ method public abstract void cancel();
+ method public abstract float getAnimatedFraction();
+ method public abstract void setDuration(long);
+ method public abstract void setTarget(android.view.View);
+ method public abstract void start();
+ }
+
+}
+
+package android.support.v4.app {
+
+ public deprecated class ActionBarDrawerToggle implements android.support.v4.widget.DrawerLayout.DrawerListener {
+ ctor public ActionBarDrawerToggle(android.app.Activity, android.support.v4.widget.DrawerLayout, int, int, int);
+ ctor public ActionBarDrawerToggle(android.app.Activity, android.support.v4.widget.DrawerLayout, boolean, int, int, int);
+ method public boolean isDrawerIndicatorEnabled();
+ method public void onConfigurationChanged(android.content.res.Configuration);
+ method public void onDrawerClosed(android.view.View);
+ method public void onDrawerOpened(android.view.View);
+ method public void onDrawerSlide(android.view.View, float);
+ method public void onDrawerStateChanged(int);
+ method public boolean onOptionsItemSelected(android.view.MenuItem);
+ method public void setDrawerIndicatorEnabled(boolean);
+ method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable);
+ method public void setHomeAsUpIndicator(int);
+ method public void syncState();
+ }
+
+ public static abstract interface ActionBarDrawerToggle.Delegate {
+ method public abstract android.graphics.drawable.Drawable getThemeUpIndicator();
+ method public abstract void setActionBarDescription(int);
+ method public abstract void setActionBarUpIndicator(android.graphics.drawable.Drawable, int);
+ }
+
+ public static abstract interface ActionBarDrawerToggle.DelegateProvider {
+ method public abstract android.support.v4.app.ActionBarDrawerToggle.Delegate getDrawerToggleDelegate();
+ }
+
+ public class ActivityCompat extends android.support.v4.content.ContextCompat {
+ ctor public ActivityCompat();
+ method public static void finishAffinity(android.app.Activity);
+ method public static void finishAfterTransition(android.app.Activity);
+ method public android.net.Uri getReferrer(android.app.Activity);
+ method public static boolean invalidateOptionsMenu(android.app.Activity);
+ method public static void postponeEnterTransition(android.app.Activity);
+ method public static void requestPermissions(android.app.Activity, java.lang.String[], int);
+ method public static void setEnterSharedElementCallback(android.app.Activity, android.support.v4.app.SharedElementCallback);
+ method public static void setExitSharedElementCallback(android.app.Activity, android.support.v4.app.SharedElementCallback);
+ method public static boolean shouldShowRequestPermissionRationale(android.app.Activity, java.lang.String);
+ method public static void startActivity(android.app.Activity, android.content.Intent, android.os.Bundle);
+ method public static void startActivityForResult(android.app.Activity, android.content.Intent, int, android.os.Bundle);
+ method public static void startPostponedEnterTransition(android.app.Activity);
+ }
+
+ public static abstract interface ActivityCompat.OnRequestPermissionsResultCallback {
+ method public abstract void onRequestPermissionsResult(int, java.lang.String[], int[]);
+ }
+
+ public final class ActivityManagerCompat {
+ method public static boolean isLowRamDevice(android.app.ActivityManager);
+ }
+
+ public class ActivityOptionsCompat {
+ ctor protected ActivityOptionsCompat();
+ method public static android.support.v4.app.ActivityOptionsCompat makeCustomAnimation(android.content.Context, int, int);
+ method public static android.support.v4.app.ActivityOptionsCompat makeScaleUpAnimation(android.view.View, int, int, int, int);
+ method public static android.support.v4.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, android.view.View, java.lang.String);
+ method public static android.support.v4.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, android.support.v4.util.Pair<android.view.View, java.lang.String>...);
+ method public static android.support.v4.app.ActivityOptionsCompat makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
+ method public android.os.Bundle toBundle();
+ method public void update(android.support.v4.app.ActivityOptionsCompat);
+ }
+
+ public class AppOpsManagerCompat {
+ ctor public AppOpsManagerCompat();
+ method public static int noteOp(android.content.Context, java.lang.String, int, java.lang.String);
+ method public static int noteProxyOp(android.content.Context, java.lang.String, java.lang.String);
+ method public static java.lang.String permissionToOp(java.lang.String);
+ field public static final int MODE_ALLOWED = 0; // 0x0
+ field public static final int MODE_DEFAULT = 3; // 0x3
+ field public static final int MODE_IGNORED = 1; // 0x1
+ }
+
+ abstract class BaseFragmentActivityDonut extends android.app.Activity {
+ }
+
+ abstract class BaseFragmentActivityHoneycomb extends android.support.v4.app.BaseFragmentActivityDonut {
+ }
+
+ public class BundleCompat {
+ ctor public BundleCompat();
+ method public static android.os.IBinder getBinder(android.os.Bundle, java.lang.String);
+ method public static void putBinder(android.os.Bundle, java.lang.String, android.os.IBinder);
+ }
+
+ public class DialogFragment extends android.support.v4.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
+ ctor public DialogFragment();
+ method public void dismiss();
+ method public void dismissAllowingStateLoss();
+ method public android.app.Dialog getDialog();
+ method public boolean getShowsDialog();
+ method public int getTheme();
+ method public boolean isCancelable();
+ method public void onCancel(android.content.DialogInterface);
+ method public android.app.Dialog onCreateDialog(android.os.Bundle);
+ method public void onDismiss(android.content.DialogInterface);
+ method public void setCancelable(boolean);
+ method public void setShowsDialog(boolean);
+ method public void setStyle(int, int);
+ method public void show(android.support.v4.app.FragmentManager, java.lang.String);
+ method public int show(android.support.v4.app.FragmentTransaction, java.lang.String);
+ field public static final int STYLE_NORMAL = 0; // 0x0
+ field public static final int STYLE_NO_FRAME = 2; // 0x2
+ field public static final int STYLE_NO_INPUT = 3; // 0x3
+ field public static final int STYLE_NO_TITLE = 1; // 0x1
+ }
+
+ public class Fragment implements android.content.ComponentCallbacks android.view.View.OnCreateContextMenuListener {
+ ctor public Fragment();
+ method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public final boolean equals(java.lang.Object);
+ method public final android.support.v4.app.FragmentActivity getActivity();
+ method public boolean getAllowEnterTransitionOverlap();
+ method public boolean getAllowReturnTransitionOverlap();
+ method public final android.os.Bundle getArguments();
+ method public final android.support.v4.app.FragmentManager getChildFragmentManager();
+ method public android.content.Context getContext();
+ method public java.lang.Object getEnterTransition();
+ method public java.lang.Object getExitTransition();
+ method public final android.support.v4.app.FragmentManager getFragmentManager();
+ method public final java.lang.Object getHost();
+ method public final int getId();
+ method public android.support.v4.app.LoaderManager getLoaderManager();
+ method public final android.support.v4.app.Fragment getParentFragment();
+ method public java.lang.Object getReenterTransition();
+ method public final android.content.res.Resources getResources();
+ method public final boolean getRetainInstance();
+ method public java.lang.Object getReturnTransition();
+ method public java.lang.Object getSharedElementEnterTransition();
+ method public java.lang.Object getSharedElementReturnTransition();
+ method public final java.lang.String getString(int);
+ method public final java.lang.String getString(int, java.lang.Object...);
+ method public final java.lang.String getTag();
+ method public final android.support.v4.app.Fragment getTargetFragment();
+ method public final int getTargetRequestCode();
+ method public final java.lang.CharSequence getText(int);
+ method public boolean getUserVisibleHint();
+ method public android.view.View getView();
+ method public final int hashCode();
+ method public static android.support.v4.app.Fragment instantiate(android.content.Context, java.lang.String);
+ method public static android.support.v4.app.Fragment instantiate(android.content.Context, java.lang.String, android.os.Bundle);
+ method public final boolean isAdded();
+ method public final boolean isDetached();
+ method public final boolean isHidden();
+ method public final boolean isInLayout();
+ method public final boolean isRemoving();
+ method public final boolean isResumed();
+ method public final boolean isVisible();
+ method public void onActivityCreated(android.os.Bundle);
+ method public void onActivityResult(int, int, android.content.Intent);
+ method public void onAttach(android.content.Context);
+ method public deprecated void onAttach(android.app.Activity);
+ method public void onConfigurationChanged(android.content.res.Configuration);
+ method public boolean onContextItemSelected(android.view.MenuItem);
+ method public void onCreate(android.os.Bundle);
+ method public android.view.animation.Animation onCreateAnimation(int, boolean, int);
+ method public void onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo);
+ method public void onCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
+ method public android.view.View onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+ method public void onDestroy();
+ method public void onDestroyOptionsMenu();
+ method public void onDestroyView();
+ method public void onDetach();
+ method public void onHiddenChanged(boolean);
+ method public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle);
+ method public deprecated void onInflate(android.app.Activity, android.util.AttributeSet, android.os.Bundle);
+ method public void onLowMemory();
+ method public boolean onOptionsItemSelected(android.view.MenuItem);
+ method public void onOptionsMenuClosed(android.view.Menu);
+ method public void onPause();
+ method public void onPrepareOptionsMenu(android.view.Menu);
+ method public void onRequestPermissionsResult(int, java.lang.String[], int[]);
+ method public void onResume();
+ method public void onSaveInstanceState(android.os.Bundle);
+ method public void onStart();
+ method public void onStop();
+ method public void onViewCreated(android.view.View, android.os.Bundle);
+ method public void onViewStateRestored(android.os.Bundle);
+ method public void registerForContextMenu(android.view.View);
+ method public final void requestPermissions(java.lang.String[], int);
+ method public void setAllowEnterTransitionOverlap(boolean);
+ method public void setAllowReturnTransitionOverlap(boolean);
+ method public void setArguments(android.os.Bundle);
+ method public void setEnterSharedElementCallback(android.support.v4.app.SharedElementCallback);
+ method public void setEnterTransition(java.lang.Object);
+ method public void setExitSharedElementCallback(android.support.v4.app.SharedElementCallback);
+ method public void setExitTransition(java.lang.Object);
+ method public void setHasOptionsMenu(boolean);
+ method public void setInitialSavedState(android.support.v4.app.Fragment.SavedState);
+ method public void setMenuVisibility(boolean);
+ method public void setReenterTransition(java.lang.Object);
+ method public void setRetainInstance(boolean);
+ method public void setReturnTransition(java.lang.Object);
+ method public void setSharedElementEnterTransition(java.lang.Object);
+ method public void setSharedElementReturnTransition(java.lang.Object);
+ method public void setTargetFragment(android.support.v4.app.Fragment, int);
+ method public void setUserVisibleHint(boolean);
+ method public boolean shouldShowRequestPermissionRationale(java.lang.String);
+ method public void startActivity(android.content.Intent);
+ method public void startActivityForResult(android.content.Intent, int);
+ method public void unregisterForContextMenu(android.view.View);
+ }
+
+ public static class Fragment.InstantiationException extends java.lang.RuntimeException {
+ ctor public Fragment.InstantiationException(java.lang.String, java.lang.Exception);
+ }
+
+ public static class Fragment.SavedState implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.app.Fragment.SavedState> CREATOR;
+ }
+
+ public class FragmentActivity extends android.support.v4.app.BaseFragmentActivityHoneycomb implements android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback {
+ ctor public FragmentActivity();
+ method public java.lang.Object getLastCustomNonConfigurationInstance();
+ method public android.support.v4.app.FragmentManager getSupportFragmentManager();
+ method public android.support.v4.app.LoaderManager getSupportLoaderManager();
+ method public final android.support.v4.media.session.MediaControllerCompat getSupportMediaController();
+ method public void onAttachFragment(android.support.v4.app.Fragment);
+ method protected void onResumeFragments();
+ method public java.lang.Object onRetainCustomNonConfigurationInstance();
+ method public final java.lang.Object onRetainNonConfigurationInstance();
+ method public void setEnterSharedElementCallback(android.support.v4.app.SharedElementCallback);
+ method public void setExitSharedElementCallback(android.support.v4.app.SharedElementCallback);
+ method public final void setSupportMediaController(android.support.v4.media.session.MediaControllerCompat);
+ method public void startActivityFromFragment(android.support.v4.app.Fragment, android.content.Intent, int);
+ method public void supportFinishAfterTransition();
+ method public void supportInvalidateOptionsMenu();
+ method public void supportPostponeEnterTransition();
+ method public void supportStartPostponedEnterTransition();
+ method public final void validateRequestPermissionsRequestCode(int);
+ }
+
+ public abstract class FragmentContainer {
+ ctor public FragmentContainer();
+ method public abstract android.view.View onFindViewById(int);
+ method public abstract boolean onHasView();
+ }
+
+ public class FragmentController {
+ method public void attachHost(android.support.v4.app.Fragment);
+ method public static final android.support.v4.app.FragmentController createController(android.support.v4.app.FragmentHostCallback<?>);
+ method public void dispatchActivityCreated();
+ method public void dispatchConfigurationChanged(android.content.res.Configuration);
+ method public boolean dispatchContextItemSelected(android.view.MenuItem);
+ method public void dispatchCreate();
+ method public boolean dispatchCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
+ method public void dispatchDestroy();
+ method public void dispatchDestroyView();
+ method public void dispatchLowMemory();
+ method public boolean dispatchOptionsItemSelected(android.view.MenuItem);
+ method public void dispatchOptionsMenuClosed(android.view.Menu);
+ method public void dispatchPause();
+ method public boolean dispatchPrepareOptionsMenu(android.view.Menu);
+ method public void dispatchReallyStop();
+ method public void dispatchResume();
+ method public void dispatchStart();
+ method public void dispatchStop();
+ method public void doLoaderDestroy();
+ method public void doLoaderRetain();
+ method public void doLoaderStart();
+ method public void doLoaderStop(boolean);
+ method public void dumpLoaders(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public boolean execPendingActions();
+ method public java.util.List<android.support.v4.app.Fragment> getActiveFragments(java.util.List<android.support.v4.app.Fragment>);
+ method public int getActiveFragmentsCount();
+ method public android.support.v4.app.FragmentManager getSupportFragmentManager();
+ method public android.support.v4.app.LoaderManager getSupportLoaderManager();
+ method public void noteStateNotSaved();
+ method public android.view.View onCreateView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet);
+ method public void reportLoaderStart();
+ method public void restoreAllState(android.os.Parcelable, java.util.List<android.support.v4.app.Fragment>);
+ method public void restoreLoaderNonConfig(android.support.v4.util.SimpleArrayMap<java.lang.String, android.support.v4.app.LoaderManager>);
+ method public android.support.v4.util.SimpleArrayMap<java.lang.String, android.support.v4.app.LoaderManager> retainLoaderNonConfig();
+ method public java.util.List<android.support.v4.app.Fragment> retainNonConfig();
+ method public android.os.Parcelable saveAllState();
+ }
+
+ public abstract class FragmentHostCallback extends android.support.v4.app.FragmentContainer {
+ ctor public FragmentHostCallback(android.content.Context, android.os.Handler, int);
+ method public void onDump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public android.view.View onFindViewById(int);
+ method public abstract E onGetHost();
+ method public android.view.LayoutInflater onGetLayoutInflater();
+ method public int onGetWindowAnimations();
+ method public boolean onHasView();
+ method public boolean onHasWindowAnimations();
+ method public void onRequestPermissionsFromFragment(android.support.v4.app.Fragment, java.lang.String[], int);
+ method public boolean onShouldSaveFragmentState(android.support.v4.app.Fragment);
+ method public boolean onShouldShowRequestPermissionRationale(java.lang.String);
+ method public void onStartActivityFromFragment(android.support.v4.app.Fragment, android.content.Intent, int);
+ method public void onSupportInvalidateOptionsMenu();
+ }
+
+ public abstract class FragmentManager {
+ ctor public FragmentManager();
+ method public abstract void addOnBackStackChangedListener(android.support.v4.app.FragmentManager.OnBackStackChangedListener);
+ method public abstract android.support.v4.app.FragmentTransaction beginTransaction();
+ method public abstract void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public static void enableDebugLogging(boolean);
+ method public abstract boolean executePendingTransactions();
+ method public abstract android.support.v4.app.Fragment findFragmentById(int);
+ method public abstract android.support.v4.app.Fragment findFragmentByTag(java.lang.String);
+ method public abstract android.support.v4.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
+ method public abstract int getBackStackEntryCount();
+ method public abstract android.support.v4.app.Fragment getFragment(android.os.Bundle, java.lang.String);
+ method public abstract boolean isDestroyed();
+ method public abstract void popBackStack();
+ method public abstract void popBackStack(java.lang.String, int);
+ method public abstract void popBackStack(int, int);
+ method public abstract boolean popBackStackImmediate();
+ method public abstract boolean popBackStackImmediate(java.lang.String, int);
+ method public abstract boolean popBackStackImmediate(int, int);
+ method public abstract void putFragment(android.os.Bundle, java.lang.String, android.support.v4.app.Fragment);
+ method public abstract void removeOnBackStackChangedListener(android.support.v4.app.FragmentManager.OnBackStackChangedListener);
+ method public abstract android.support.v4.app.Fragment.SavedState saveFragmentInstanceState(android.support.v4.app.Fragment);
+ field public static final int POP_BACK_STACK_INCLUSIVE = 1; // 0x1
+ }
+
+ public static abstract interface FragmentManager.BackStackEntry {
+ method public abstract java.lang.CharSequence getBreadCrumbShortTitle();
+ method public abstract int getBreadCrumbShortTitleRes();
+ method public abstract java.lang.CharSequence getBreadCrumbTitle();
+ method public abstract int getBreadCrumbTitleRes();
+ method public abstract int getId();
+ method public abstract java.lang.String getName();
+ }
+
+ public static abstract interface FragmentManager.OnBackStackChangedListener {
+ method public abstract void onBackStackChanged();
+ }
+
+ public abstract class FragmentPagerAdapter extends android.support.v4.view.PagerAdapter {
+ ctor public FragmentPagerAdapter(android.support.v4.app.FragmentManager);
+ method public abstract android.support.v4.app.Fragment getItem(int);
+ method public long getItemId(int);
+ method public boolean isViewFromObject(android.view.View, java.lang.Object);
+ }
+
+ public abstract class FragmentStatePagerAdapter extends android.support.v4.view.PagerAdapter {
+ ctor public FragmentStatePagerAdapter(android.support.v4.app.FragmentManager);
+ method public abstract android.support.v4.app.Fragment getItem(int);
+ method public boolean isViewFromObject(android.view.View, java.lang.Object);
+ }
+
+ public class FragmentTabHost extends android.widget.TabHost implements android.widget.TabHost.OnTabChangeListener {
+ ctor public FragmentTabHost(android.content.Context);
+ ctor public FragmentTabHost(android.content.Context, android.util.AttributeSet);
+ method public void addTab(android.widget.TabHost.TabSpec, java.lang.Class<?>, android.os.Bundle);
+ method public void onTabChanged(java.lang.String);
+ method public void setup(android.content.Context, android.support.v4.app.FragmentManager);
+ method public void setup(android.content.Context, android.support.v4.app.FragmentManager, int);
+ }
+
+ public abstract class FragmentTransaction {
+ ctor public FragmentTransaction();
+ method public abstract android.support.v4.app.FragmentTransaction add(android.support.v4.app.Fragment, java.lang.String);
+ method public abstract android.support.v4.app.FragmentTransaction add(int, android.support.v4.app.Fragment);
+ method public abstract android.support.v4.app.FragmentTransaction add(int, android.support.v4.app.Fragment, java.lang.String);
+ method public abstract android.support.v4.app.FragmentTransaction addSharedElement(android.view.View, java.lang.String);
+ method public abstract android.support.v4.app.FragmentTransaction addToBackStack(java.lang.String);
+ method public abstract android.support.v4.app.FragmentTransaction attach(android.support.v4.app.Fragment);
+ method public abstract int commit();
+ method public abstract int commitAllowingStateLoss();
+ method public abstract android.support.v4.app.FragmentTransaction detach(android.support.v4.app.Fragment);
+ method public abstract android.support.v4.app.FragmentTransaction disallowAddToBackStack();
+ method public abstract android.support.v4.app.FragmentTransaction hide(android.support.v4.app.Fragment);
+ method public abstract boolean isAddToBackStackAllowed();
+ method public abstract boolean isEmpty();
+ method public abstract android.support.v4.app.FragmentTransaction remove(android.support.v4.app.Fragment);
+ method public abstract android.support.v4.app.FragmentTransaction replace(int, android.support.v4.app.Fragment);
+ method public abstract android.support.v4.app.FragmentTransaction replace(int, android.support.v4.app.Fragment, java.lang.String);
+ method public abstract android.support.v4.app.FragmentTransaction setBreadCrumbShortTitle(int);
+ method public abstract android.support.v4.app.FragmentTransaction setBreadCrumbShortTitle(java.lang.CharSequence);
+ method public abstract android.support.v4.app.FragmentTransaction setBreadCrumbTitle(int);
+ method public abstract android.support.v4.app.FragmentTransaction setBreadCrumbTitle(java.lang.CharSequence);
+ method public abstract android.support.v4.app.FragmentTransaction setCustomAnimations(int, int);
+ method public abstract android.support.v4.app.FragmentTransaction setCustomAnimations(int, int, int, int);
+ method public abstract android.support.v4.app.FragmentTransaction setTransition(int);
+ method public abstract android.support.v4.app.FragmentTransaction setTransitionStyle(int);
+ method public abstract android.support.v4.app.FragmentTransaction show(android.support.v4.app.Fragment);
+ field public static final int TRANSIT_ENTER_MASK = 4096; // 0x1000
+ field public static final int TRANSIT_EXIT_MASK = 8192; // 0x2000
+ field public static final int TRANSIT_FRAGMENT_CLOSE = 8194; // 0x2002
+ field public static final int TRANSIT_FRAGMENT_FADE = 4099; // 0x1003
+ field public static final int TRANSIT_FRAGMENT_OPEN = 4097; // 0x1001
+ field public static final int TRANSIT_NONE = 0; // 0x0
+ field public static final int TRANSIT_UNSET = -1; // 0xffffffff
+ }
+
+ public class ListFragment extends android.support.v4.app.Fragment {
+ ctor public ListFragment();
+ method public android.widget.ListAdapter getListAdapter();
+ method public android.widget.ListView getListView();
+ method public long getSelectedItemId();
+ method public int getSelectedItemPosition();
+ method public void onListItemClick(android.widget.ListView, android.view.View, int, long);
+ method public void setEmptyText(java.lang.CharSequence);
+ method public void setListAdapter(android.widget.ListAdapter);
+ method public void setListShown(boolean);
+ method public void setListShownNoAnimation(boolean);
+ method public void setSelection(int);
+ }
+
+ public abstract class LoaderManager {
+ ctor public LoaderManager();
+ method public abstract void destroyLoader(int);
+ method public abstract void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public static void enableDebugLogging(boolean);
+ method public abstract android.support.v4.content.Loader<D> getLoader(int);
+ method public boolean hasRunningLoaders();
+ method public abstract android.support.v4.content.Loader<D> initLoader(int, android.os.Bundle, android.support.v4.app.LoaderManager.LoaderCallbacks<D>);
+ method public abstract android.support.v4.content.Loader<D> restartLoader(int, android.os.Bundle, android.support.v4.app.LoaderManager.LoaderCallbacks<D>);
+ }
+
+ public static abstract interface LoaderManager.LoaderCallbacks {
+ method public abstract android.support.v4.content.Loader<D> onCreateLoader(int, android.os.Bundle);
+ method public abstract void onLoadFinished(android.support.v4.content.Loader<D>, D);
+ method public abstract void onLoaderReset(android.support.v4.content.Loader<D>);
+ }
+
+ public class NavUtils {
+ method public static android.content.Intent getParentActivityIntent(android.app.Activity);
+ method public static android.content.Intent getParentActivityIntent(android.content.Context, java.lang.Class<?>) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public static android.content.Intent getParentActivityIntent(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public static java.lang.String getParentActivityName(android.app.Activity);
+ method public static java.lang.String getParentActivityName(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public static void navigateUpFromSameTask(android.app.Activity);
+ method public static void navigateUpTo(android.app.Activity, android.content.Intent);
+ method public static boolean shouldUpRecreateTask(android.app.Activity, android.content.Intent);
+ field public static final java.lang.String PARENT_ACTIVITY = "android.support.PARENT_ACTIVITY";
+ }
+
+ public class NotificationCompat {
+ ctor public NotificationCompat();
+ method public static android.support.v4.app.NotificationCompat.Action getAction(android.app.Notification, int);
+ method public static int getActionCount(android.app.Notification);
+ method public static java.lang.String getCategory(android.app.Notification);
+ method public static android.os.Bundle getExtras(android.app.Notification);
+ method public static java.lang.String getGroup(android.app.Notification);
+ method public static boolean getLocalOnly(android.app.Notification);
+ method public static java.lang.String getSortKey(android.app.Notification);
+ method public static boolean isGroupSummary(android.app.Notification);
+ field public static final java.lang.String CATEGORY_ALARM = "alarm";
+ field public static final java.lang.String CATEGORY_CALL = "call";
+ field public static final java.lang.String CATEGORY_EMAIL = "email";
+ field public static final java.lang.String CATEGORY_ERROR = "err";
+ field public static final java.lang.String CATEGORY_EVENT = "event";
+ field public static final java.lang.String CATEGORY_MESSAGE = "msg";
+ field public static final java.lang.String CATEGORY_PROGRESS = "progress";
+ field public static final java.lang.String CATEGORY_PROMO = "promo";
+ field public static final java.lang.String CATEGORY_RECOMMENDATION = "recommendation";
+ field public static final java.lang.String CATEGORY_SERVICE = "service";
+ field public static final java.lang.String CATEGORY_SOCIAL = "social";
+ field public static final java.lang.String CATEGORY_STATUS = "status";
+ field public static final java.lang.String CATEGORY_SYSTEM = "sys";
+ field public static final java.lang.String CATEGORY_TRANSPORT = "transport";
+ field public static final int COLOR_DEFAULT = 0; // 0x0
+ field public static final int DEFAULT_ALL = -1; // 0xffffffff
+ field public static final int DEFAULT_LIGHTS = 4; // 0x4
+ field public static final int DEFAULT_SOUND = 1; // 0x1
+ field public static final int DEFAULT_VIBRATE = 2; // 0x2
+ field public static final java.lang.String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
+ field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
+ field public static final java.lang.String EXTRA_COMPACT_ACTIONS = "android.compactActions";
+ field public static final java.lang.String EXTRA_INFO_TEXT = "android.infoText";
+ field public static final java.lang.String EXTRA_LARGE_ICON = "android.largeIcon";
+ field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
+ field public static final java.lang.String EXTRA_MEDIA_SESSION = "android.mediaSession";
+ field public static final java.lang.String EXTRA_PEOPLE = "android.people";
+ field public static final java.lang.String EXTRA_PICTURE = "android.picture";
+ field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
+ field public static final java.lang.String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
+ field public static final java.lang.String EXTRA_PROGRESS_MAX = "android.progressMax";
+ field public static final java.lang.String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
+ field public static final java.lang.String EXTRA_SHOW_WHEN = "android.showWhen";
+ field public static final java.lang.String EXTRA_SMALL_ICON = "android.icon";
+ field public static final java.lang.String EXTRA_SUB_TEXT = "android.subText";
+ field public static final java.lang.String EXTRA_SUMMARY_TEXT = "android.summaryText";
+ field public static final java.lang.String EXTRA_TEMPLATE = "android.template";
+ field public static final java.lang.String EXTRA_TEXT = "android.text";
+ field public static final java.lang.String EXTRA_TEXT_LINES = "android.textLines";
+ field public static final java.lang.String EXTRA_TITLE = "android.title";
+ field public static final java.lang.String EXTRA_TITLE_BIG = "android.title.big";
+ field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
+ field public static final int FLAG_FOREGROUND_SERVICE = 64; // 0x40
+ field public static final int FLAG_GROUP_SUMMARY = 512; // 0x200
+ field public static final deprecated int FLAG_HIGH_PRIORITY = 128; // 0x80
+ field public static final int FLAG_INSISTENT = 4; // 0x4
+ field public static final int FLAG_LOCAL_ONLY = 256; // 0x100
+ field public static final int FLAG_NO_CLEAR = 32; // 0x20
+ field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
+ field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
+ field public static final int FLAG_SHOW_LIGHTS = 1; // 0x1
+ field public static final int PRIORITY_DEFAULT = 0; // 0x0
+ field public static final int PRIORITY_HIGH = 1; // 0x1
+ field public static final int PRIORITY_LOW = -1; // 0xffffffff
+ field public static final int PRIORITY_MAX = 2; // 0x2
+ field public static final int PRIORITY_MIN = -2; // 0xfffffffe
+ field public static final int STREAM_DEFAULT = -1; // 0xffffffff
+ field public static final int VISIBILITY_PRIVATE = 0; // 0x0
+ field public static final int VISIBILITY_PUBLIC = 1; // 0x1
+ field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
+ }
+
+ public static class NotificationCompat.Action extends android.support.v4.app.NotificationCompatBase.Action {
+ ctor public NotificationCompat.Action(int, java.lang.CharSequence, android.app.PendingIntent);
+ method public android.app.PendingIntent getActionIntent();
+ method public android.os.Bundle getExtras();
+ method public int getIcon();
+ method public android.support.v4.app.RemoteInput[] getRemoteInputs();
+ method public java.lang.CharSequence getTitle();
+ field public android.app.PendingIntent actionIntent;
+ field public int icon;
+ field public java.lang.CharSequence title;
+ }
+
+ public static final class NotificationCompat.Action.Builder {
+ ctor public NotificationCompat.Action.Builder(int, java.lang.CharSequence, android.app.PendingIntent);
+ ctor public NotificationCompat.Action.Builder(android.support.v4.app.NotificationCompat.Action);
+ method public android.support.v4.app.NotificationCompat.Action.Builder addExtras(android.os.Bundle);
+ method public android.support.v4.app.NotificationCompat.Action.Builder addRemoteInput(android.support.v4.app.RemoteInput);
+ method public android.support.v4.app.NotificationCompat.Action build();
+ method public android.support.v4.app.NotificationCompat.Action.Builder extend(android.support.v4.app.NotificationCompat.Action.Extender);
+ method public android.os.Bundle getExtras();
+ }
+
+ public static abstract interface NotificationCompat.Action.Extender {
+ method public abstract android.support.v4.app.NotificationCompat.Action.Builder extend(android.support.v4.app.NotificationCompat.Action.Builder);
+ }
+
+ public static final class NotificationCompat.Action.WearableExtender implements android.support.v4.app.NotificationCompat.Action.Extender {
+ ctor public NotificationCompat.Action.WearableExtender();
+ ctor public NotificationCompat.Action.WearableExtender(android.support.v4.app.NotificationCompat.Action);
+ method public android.support.v4.app.NotificationCompat.Action.WearableExtender clone();
+ method public android.support.v4.app.NotificationCompat.Action.Builder extend(android.support.v4.app.NotificationCompat.Action.Builder);
+ method public java.lang.CharSequence getCancelLabel();
+ method public java.lang.CharSequence getConfirmLabel();
+ method public java.lang.CharSequence getInProgressLabel();
+ method public boolean isAvailableOffline();
+ method public android.support.v4.app.NotificationCompat.Action.WearableExtender setAvailableOffline(boolean);
+ method public android.support.v4.app.NotificationCompat.Action.WearableExtender setCancelLabel(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.Action.WearableExtender setConfirmLabel(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.Action.WearableExtender setInProgressLabel(java.lang.CharSequence);
+ }
+
+ public static class NotificationCompat.BigPictureStyle extends android.support.v4.app.NotificationCompat.Style {
+ ctor public NotificationCompat.BigPictureStyle();
+ ctor public NotificationCompat.BigPictureStyle(android.support.v4.app.NotificationCompat.Builder);
+ method public android.support.v4.app.NotificationCompat.BigPictureStyle bigLargeIcon(android.graphics.Bitmap);
+ method public android.support.v4.app.NotificationCompat.BigPictureStyle bigPicture(android.graphics.Bitmap);
+ method public android.support.v4.app.NotificationCompat.BigPictureStyle setBigContentTitle(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.BigPictureStyle setSummaryText(java.lang.CharSequence);
+ }
+
+ public static class NotificationCompat.BigTextStyle extends android.support.v4.app.NotificationCompat.Style {
+ ctor public NotificationCompat.BigTextStyle();
+ ctor public NotificationCompat.BigTextStyle(android.support.v4.app.NotificationCompat.Builder);
+ method public android.support.v4.app.NotificationCompat.BigTextStyle bigText(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.BigTextStyle setBigContentTitle(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.BigTextStyle setSummaryText(java.lang.CharSequence);
+ }
+
+ public static class NotificationCompat.Builder {
+ ctor public NotificationCompat.Builder(android.content.Context);
+ method public android.support.v4.app.NotificationCompat.Builder addAction(int, java.lang.CharSequence, android.app.PendingIntent);
+ method public android.support.v4.app.NotificationCompat.Builder addAction(android.support.v4.app.NotificationCompat.Action);
+ method public android.support.v4.app.NotificationCompat.Builder addExtras(android.os.Bundle);
+ method public android.support.v4.app.NotificationCompat.Builder addPerson(java.lang.String);
+ method public android.app.Notification build();
+ method public android.support.v4.app.NotificationCompat.Builder extend(android.support.v4.app.NotificationCompat.Extender);
+ method public android.os.Bundle getExtras();
+ method public deprecated android.app.Notification getNotification();
+ method protected static java.lang.CharSequence limitCharSequenceLength(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.Builder setAutoCancel(boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setCategory(java.lang.String);
+ method public android.support.v4.app.NotificationCompat.Builder setColor(int);
+ method public android.support.v4.app.NotificationCompat.Builder setContent(android.widget.RemoteViews);
+ method public android.support.v4.app.NotificationCompat.Builder setContentInfo(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.Builder setContentIntent(android.app.PendingIntent);
+ method public android.support.v4.app.NotificationCompat.Builder setContentText(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.Builder setContentTitle(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.Builder setDefaults(int);
+ method public android.support.v4.app.NotificationCompat.Builder setDeleteIntent(android.app.PendingIntent);
+ method public android.support.v4.app.NotificationCompat.Builder setExtras(android.os.Bundle);
+ method public android.support.v4.app.NotificationCompat.Builder setFullScreenIntent(android.app.PendingIntent, boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setGroup(java.lang.String);
+ method public android.support.v4.app.NotificationCompat.Builder setGroupSummary(boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setLargeIcon(android.graphics.Bitmap);
+ method public android.support.v4.app.NotificationCompat.Builder setLights(int, int, int);
+ method public android.support.v4.app.NotificationCompat.Builder setLocalOnly(boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setNumber(int);
+ method public android.support.v4.app.NotificationCompat.Builder setOngoing(boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setOnlyAlertOnce(boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setPriority(int);
+ method public android.support.v4.app.NotificationCompat.Builder setProgress(int, int, boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setPublicVersion(android.app.Notification);
+ method public android.support.v4.app.NotificationCompat.Builder setShowWhen(boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setSmallIcon(int);
+ method public android.support.v4.app.NotificationCompat.Builder setSmallIcon(int, int);
+ method public android.support.v4.app.NotificationCompat.Builder setSortKey(java.lang.String);
+ method public android.support.v4.app.NotificationCompat.Builder setSound(android.net.Uri);
+ method public android.support.v4.app.NotificationCompat.Builder setSound(android.net.Uri, int);
+ method public android.support.v4.app.NotificationCompat.Builder setStyle(android.support.v4.app.NotificationCompat.Style);
+ method public android.support.v4.app.NotificationCompat.Builder setSubText(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.Builder setTicker(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
+ method public android.support.v4.app.NotificationCompat.Builder setUsesChronometer(boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setVibrate(long[]);
+ method public android.support.v4.app.NotificationCompat.Builder setVisibility(int);
+ method public android.support.v4.app.NotificationCompat.Builder setWhen(long);
+ field public java.util.ArrayList<java.lang.String> mPeople;
+ }
+
+ public static final class NotificationCompat.CarExtender implements android.support.v4.app.NotificationCompat.Extender {
+ ctor public NotificationCompat.CarExtender();
+ ctor public NotificationCompat.CarExtender(android.app.Notification);
+ method public android.support.v4.app.NotificationCompat.Builder extend(android.support.v4.app.NotificationCompat.Builder);
+ method public int getColor();
+ method public android.graphics.Bitmap getLargeIcon();
+ method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation getUnreadConversation();
+ method public android.support.v4.app.NotificationCompat.CarExtender setColor(int);
+ method public android.support.v4.app.NotificationCompat.CarExtender setLargeIcon(android.graphics.Bitmap);
+ method public android.support.v4.app.NotificationCompat.CarExtender setUnreadConversation(android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation);
+ }
+
+ public static class NotificationCompat.CarExtender.UnreadConversation extends android.support.v4.app.NotificationCompatBase.UnreadConversation {
+ method public long getLatestTimestamp();
+ method public java.lang.String[] getMessages();
+ method public java.lang.String getParticipant();
+ method public java.lang.String[] getParticipants();
+ method public android.app.PendingIntent getReadPendingIntent();
+ method public android.support.v4.app.RemoteInput getRemoteInput();
+ method public android.app.PendingIntent getReplyPendingIntent();
+ }
+
+ public static class NotificationCompat.CarExtender.UnreadConversation.Builder {
+ ctor public NotificationCompat.CarExtender.UnreadConversation.Builder(java.lang.String);
+ method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder addMessage(java.lang.String);
+ method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation build();
+ method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder setLatestTimestamp(long);
+ method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReadPendingIntent(android.app.PendingIntent);
+ method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReplyAction(android.app.PendingIntent, android.support.v4.app.RemoteInput);
+ }
+
+ public static abstract interface NotificationCompat.Extender {
+ method public abstract android.support.v4.app.NotificationCompat.Builder extend(android.support.v4.app.NotificationCompat.Builder);
+ }
+
+ public static class NotificationCompat.InboxStyle extends android.support.v4.app.NotificationCompat.Style {
+ ctor public NotificationCompat.InboxStyle();
+ ctor public NotificationCompat.InboxStyle(android.support.v4.app.NotificationCompat.Builder);
+ method public android.support.v4.app.NotificationCompat.InboxStyle addLine(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.InboxStyle setBigContentTitle(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.InboxStyle setSummaryText(java.lang.CharSequence);
+ }
+
+ public static abstract class NotificationCompat.Style {
+ ctor public NotificationCompat.Style();
+ method public android.app.Notification build();
+ method public void setBuilder(android.support.v4.app.NotificationCompat.Builder);
+ }
+
+ public static final class NotificationCompat.WearableExtender implements android.support.v4.app.NotificationCompat.Extender {
+ ctor public NotificationCompat.WearableExtender();
+ ctor public NotificationCompat.WearableExtender(android.app.Notification);
+ method public android.support.v4.app.NotificationCompat.WearableExtender addAction(android.support.v4.app.NotificationCompat.Action);
+ method public android.support.v4.app.NotificationCompat.WearableExtender addActions(java.util.List<android.support.v4.app.NotificationCompat.Action>);
+ method public android.support.v4.app.NotificationCompat.WearableExtender addPage(android.app.Notification);
+ method public android.support.v4.app.NotificationCompat.WearableExtender addPages(java.util.List<android.app.Notification>);
+ method public android.support.v4.app.NotificationCompat.WearableExtender clearActions();
+ method public android.support.v4.app.NotificationCompat.WearableExtender clearPages();
+ method public android.support.v4.app.NotificationCompat.WearableExtender clone();
+ method public android.support.v4.app.NotificationCompat.Builder extend(android.support.v4.app.NotificationCompat.Builder);
+ method public java.util.List<android.support.v4.app.NotificationCompat.Action> getActions();
+ method public android.graphics.Bitmap getBackground();
+ method public int getContentAction();
+ method public int getContentIcon();
+ method public int getContentIconGravity();
+ method public boolean getContentIntentAvailableOffline();
+ method public int getCustomContentHeight();
+ method public int getCustomSizePreset();
+ method public android.app.PendingIntent getDisplayIntent();
+ method public int getGravity();
+ method public boolean getHintAvoidBackgroundClipping();
+ method public boolean getHintHideIcon();
+ method public int getHintScreenTimeout();
+ method public boolean getHintShowBackgroundOnly();
+ method public java.util.List<android.app.Notification> getPages();
+ method public boolean getStartScrollBottom();
+ method public android.support.v4.app.NotificationCompat.WearableExtender setBackground(android.graphics.Bitmap);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setContentAction(int);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setContentIcon(int);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setContentIconGravity(int);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setContentIntentAvailableOffline(boolean);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setCustomContentHeight(int);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setCustomSizePreset(int);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setDisplayIntent(android.app.PendingIntent);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setGravity(int);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setHintAvoidBackgroundClipping(boolean);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setHintHideIcon(boolean);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setHintScreenTimeout(int);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setHintShowBackgroundOnly(boolean);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setStartScrollBottom(boolean);
+ field public static final int SCREEN_TIMEOUT_LONG = -1; // 0xffffffff
+ field public static final int SCREEN_TIMEOUT_SHORT = 0; // 0x0
+ field public static final int SIZE_DEFAULT = 0; // 0x0
+ field public static final int SIZE_FULL_SCREEN = 5; // 0x5
+ field public static final int SIZE_LARGE = 4; // 0x4
+ field public static final int SIZE_MEDIUM = 3; // 0x3
+ field public static final int SIZE_SMALL = 2; // 0x2
+ field public static final int SIZE_XSMALL = 1; // 0x1
+ field public static final int UNSET_ACTION_INDEX = -1; // 0xffffffff
+ }
+
+ public class NotificationCompatBase {
+ ctor public NotificationCompatBase();
+ }
+
+ public static abstract class NotificationCompatBase.Action {
+ ctor public NotificationCompatBase.Action();
+ method public abstract android.app.PendingIntent getActionIntent();
+ method public abstract android.os.Bundle getExtras();
+ method public abstract int getIcon();
+ method public abstract android.support.v4.app.RemoteInputCompatBase.RemoteInput[] getRemoteInputs();
+ method public abstract java.lang.CharSequence getTitle();
+ }
+
+ public static abstract class NotificationCompatBase.UnreadConversation {
+ ctor public NotificationCompatBase.UnreadConversation();
+ }
+
+ public final class NotificationCompatExtras {
+ field public static final java.lang.String EXTRA_ACTION_EXTRAS = "android.support.actionExtras";
+ field public static final java.lang.String EXTRA_GROUP_KEY = "android.support.groupKey";
+ field public static final java.lang.String EXTRA_GROUP_SUMMARY = "android.support.isGroupSummary";
+ field public static final java.lang.String EXTRA_LOCAL_ONLY = "android.support.localOnly";
+ field public static final java.lang.String EXTRA_REMOTE_INPUTS = "android.support.remoteInputs";
+ field public static final java.lang.String EXTRA_SORT_KEY = "android.support.sortKey";
+ }
+
+ public abstract class NotificationCompatSideChannelService extends android.app.Service {
+ ctor public NotificationCompatSideChannelService();
+ method public abstract void cancel(java.lang.String, int, java.lang.String);
+ method public abstract void cancelAll(java.lang.String);
+ method public abstract void notify(java.lang.String, int, java.lang.String, android.app.Notification);
+ method public android.os.IBinder onBind(android.content.Intent);
+ }
+
+ public class NotificationManagerCompat {
+ method public void cancel(int);
+ method public void cancel(java.lang.String, int);
+ method public void cancelAll();
+ method public static android.support.v4.app.NotificationManagerCompat from(android.content.Context);
+ method public static java.util.Set<java.lang.String> getEnabledListenerPackages(android.content.Context);
+ method public void notify(int, android.app.Notification);
+ method public void notify(java.lang.String, int, android.app.Notification);
+ field public static final java.lang.String ACTION_BIND_SIDE_CHANNEL = "android.support.BIND_NOTIFICATION_SIDE_CHANNEL";
+ field public static final java.lang.String EXTRA_USE_SIDE_CHANNEL = "android.support.useSideChannel";
+ }
+
+ public class RemoteInput extends android.support.v4.app.RemoteInputCompatBase.RemoteInput {
+ method public static void addResultsToIntent(android.support.v4.app.RemoteInput[], android.content.Intent, android.os.Bundle);
+ method public boolean getAllowFreeFormInput();
+ method public java.lang.CharSequence[] getChoices();
+ method public android.os.Bundle getExtras();
+ method public java.lang.CharSequence getLabel();
+ method public java.lang.String getResultKey();
+ method public static android.os.Bundle getResultsFromIntent(android.content.Intent);
+ field public static final java.lang.String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
+ field public static final java.lang.String RESULTS_CLIP_LABEL = "android.remoteinput.results";
+ }
+
+ public static final class RemoteInput.Builder {
+ ctor public RemoteInput.Builder(java.lang.String);
+ method public android.support.v4.app.RemoteInput.Builder addExtras(android.os.Bundle);
+ method public android.support.v4.app.RemoteInput build();
+ method public android.os.Bundle getExtras();
+ method public android.support.v4.app.RemoteInput.Builder setAllowFreeFormInput(boolean);
+ method public android.support.v4.app.RemoteInput.Builder setChoices(java.lang.CharSequence[]);
+ method public android.support.v4.app.RemoteInput.Builder setLabel(java.lang.CharSequence);
+ }
+
+ class RemoteInputCompatBase {
+ }
+
+ public static abstract class RemoteInputCompatBase.RemoteInput {
+ ctor public RemoteInputCompatBase.RemoteInput();
+ method protected abstract boolean getAllowFreeFormInput();
+ method protected abstract java.lang.CharSequence[] getChoices();
+ method protected abstract android.os.Bundle getExtras();
+ method protected abstract java.lang.CharSequence getLabel();
+ method protected abstract java.lang.String getResultKey();
+ }
+
+ public class ServiceCompat {
+ field public static final int START_STICKY = 1; // 0x1
+ }
+
+ public class ShareCompat {
+ ctor public ShareCompat();
+ method public static void configureMenuItem(android.view.MenuItem, android.support.v4.app.ShareCompat.IntentBuilder);
+ method public static void configureMenuItem(android.view.Menu, int, android.support.v4.app.ShareCompat.IntentBuilder);
+ method public static android.content.ComponentName getCallingActivity(android.app.Activity);
+ method public static java.lang.String getCallingPackage(android.app.Activity);
+ field public static final java.lang.String EXTRA_CALLING_ACTIVITY = "android.support.v4.app.EXTRA_CALLING_ACTIVITY";
+ field public static final java.lang.String EXTRA_CALLING_PACKAGE = "android.support.v4.app.EXTRA_CALLING_PACKAGE";
+ }
+
+ public static class ShareCompat.IntentBuilder {
+ method public android.support.v4.app.ShareCompat.IntentBuilder addEmailBcc(java.lang.String);
+ method public android.support.v4.app.ShareCompat.IntentBuilder addEmailBcc(java.lang.String[]);
+ method public android.support.v4.app.ShareCompat.IntentBuilder addEmailCc(java.lang.String);
+ method public android.support.v4.app.ShareCompat.IntentBuilder addEmailCc(java.lang.String[]);
+ method public android.support.v4.app.ShareCompat.IntentBuilder addEmailTo(java.lang.String);
+ method public android.support.v4.app.ShareCompat.IntentBuilder addEmailTo(java.lang.String[]);
+ method public android.support.v4.app.ShareCompat.IntentBuilder addStream(android.net.Uri);
+ method public android.content.Intent createChooserIntent();
+ method public static android.support.v4.app.ShareCompat.IntentBuilder from(android.app.Activity);
+ method public android.content.Intent getIntent();
+ method public android.support.v4.app.ShareCompat.IntentBuilder setChooserTitle(java.lang.CharSequence);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setChooserTitle(int);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setEmailBcc(java.lang.String[]);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setEmailCc(java.lang.String[]);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setEmailTo(java.lang.String[]);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setHtmlText(java.lang.String);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setStream(android.net.Uri);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setSubject(java.lang.String);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setText(java.lang.CharSequence);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setType(java.lang.String);
+ method public void startChooser();
+ }
+
+ public static class ShareCompat.IntentReader {
+ method public static android.support.v4.app.ShareCompat.IntentReader from(android.app.Activity);
+ method public android.content.ComponentName getCallingActivity();
+ method public android.graphics.drawable.Drawable getCallingActivityIcon();
+ method public android.graphics.drawable.Drawable getCallingApplicationIcon();
+ method public java.lang.CharSequence getCallingApplicationLabel();
+ method public java.lang.String getCallingPackage();
+ method public java.lang.String[] getEmailBcc();
+ method public java.lang.String[] getEmailCc();
+ method public java.lang.String[] getEmailTo();
+ method public java.lang.String getHtmlText();
+ method public android.net.Uri getStream();
+ method public android.net.Uri getStream(int);
+ method public int getStreamCount();
+ method public java.lang.String getSubject();
+ method public java.lang.CharSequence getText();
+ method public java.lang.String getType();
+ method public boolean isMultipleShare();
+ method public boolean isShareIntent();
+ method public boolean isSingleShare();
+ }
+
+ public abstract class SharedElementCallback {
+ ctor public SharedElementCallback();
+ method public android.os.Parcelable onCaptureSharedElementSnapshot(android.view.View, android.graphics.Matrix, android.graphics.RectF);
+ method public android.view.View onCreateSnapshotView(android.content.Context, android.os.Parcelable);
+ method public void onMapSharedElements(java.util.List<java.lang.String>, java.util.Map<java.lang.String, android.view.View>);
+ method public void onRejectSharedElements(java.util.List<android.view.View>);
+ method public void onSharedElementEnd(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>);
+ method public void onSharedElementStart(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>);
+ }
+
+ public class TaskStackBuilder implements java.lang.Iterable {
+ method public android.support.v4.app.TaskStackBuilder addNextIntent(android.content.Intent);
+ method public android.support.v4.app.TaskStackBuilder addNextIntentWithParentStack(android.content.Intent);
+ method public android.support.v4.app.TaskStackBuilder addParentStack(android.app.Activity);
+ method public android.support.v4.app.TaskStackBuilder addParentStack(java.lang.Class<?>);
+ method public android.support.v4.app.TaskStackBuilder addParentStack(android.content.ComponentName);
+ method public static android.support.v4.app.TaskStackBuilder create(android.content.Context);
+ method public android.content.Intent editIntentAt(int);
+ method public static deprecated android.support.v4.app.TaskStackBuilder from(android.content.Context);
+ method public deprecated android.content.Intent getIntent(int);
+ method public int getIntentCount();
+ method public android.content.Intent[] getIntents();
+ method public android.app.PendingIntent getPendingIntent(int, int);
+ method public android.app.PendingIntent getPendingIntent(int, int, android.os.Bundle);
+ method public deprecated java.util.Iterator<android.content.Intent> iterator();
+ method public void startActivities();
+ method public void startActivities(android.os.Bundle);
+ }
+
+ public static abstract interface TaskStackBuilder.SupportParentable {
+ method public abstract android.content.Intent getSupportParentActivityIntent();
+ }
+
+}
+
+package android.support.v4.content {
+
+ public abstract class AsyncTaskLoader extends android.support.v4.content.Loader {
+ ctor public AsyncTaskLoader(android.content.Context);
+ method public void cancelLoadInBackground();
+ method public boolean isLoadInBackgroundCanceled();
+ method public abstract D loadInBackground();
+ method public void onCanceled(D);
+ method protected D onLoadInBackground();
+ method public void setUpdateThrottle(long);
+ }
+
+ public class ContentResolverCompat {
+ method public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.support.v4.os.CancellationSignal);
+ }
+
+ public class ContextCompat {
+ ctor public ContextCompat();
+ method public static int checkSelfPermission(android.content.Context, java.lang.String);
+ method public final java.io.File getCodeCacheDir(android.content.Context);
+ method public static final int getColor(android.content.Context, int);
+ method public static final android.content.res.ColorStateList getColorStateList(android.content.Context, int);
+ method public static final android.graphics.drawable.Drawable getDrawable(android.content.Context, int);
+ method public static java.io.File[] getExternalCacheDirs(android.content.Context);
+ method public static java.io.File[] getExternalFilesDirs(android.content.Context, java.lang.String);
+ method public final java.io.File getNoBackupFilesDir(android.content.Context);
+ method public static java.io.File[] getObbDirs(android.content.Context);
+ method public static boolean startActivities(android.content.Context, android.content.Intent[]);
+ method public static boolean startActivities(android.content.Context, android.content.Intent[], android.os.Bundle);
+ }
+
+ public class CursorLoader extends android.support.v4.content.AsyncTaskLoader {
+ ctor public CursorLoader(android.content.Context);
+ ctor public CursorLoader(android.content.Context, android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
+ method public void deliverResult(android.database.Cursor);
+ method public java.lang.String[] getProjection();
+ method public java.lang.String getSelection();
+ method public java.lang.String[] getSelectionArgs();
+ method public java.lang.String getSortOrder();
+ method public android.net.Uri getUri();
+ method public android.database.Cursor loadInBackground();
+ method public void onCanceled(android.database.Cursor);
+ method public void setProjection(java.lang.String[]);
+ method public void setSelection(java.lang.String);
+ method public void setSelectionArgs(java.lang.String[]);
+ method public void setSortOrder(java.lang.String);
+ method public void setUri(android.net.Uri);
+ }
+
+ public class FileProvider extends android.content.ContentProvider {
+ ctor public FileProvider();
+ method public int delete(android.net.Uri, java.lang.String, java.lang.String[]);
+ method public java.lang.String getType(android.net.Uri);
+ method public static android.net.Uri getUriForFile(android.content.Context, java.lang.String, java.io.File);
+ method public android.net.Uri insert(android.net.Uri, android.content.ContentValues);
+ method public boolean onCreate();
+ method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
+ method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
+ }
+
+ public class IntentCompat {
+ method public static android.content.Intent makeMainActivity(android.content.ComponentName);
+ method public static android.content.Intent makeMainSelectorActivity(java.lang.String, java.lang.String);
+ method public static android.content.Intent makeRestartActivityTask(android.content.ComponentName);
+ field public static final java.lang.String ACTION_EXTERNAL_APPLICATIONS_AVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE";
+ field public static final java.lang.String ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE";
+ field public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
+ field public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list";
+ field public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
+ field public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; // 0x8000
+ field public static final int FLAG_ACTIVITY_TASK_ON_HOME = 16384; // 0x4000
+ }
+
+ public class Loader {
+ ctor public Loader(android.content.Context);
+ method public void abandon();
+ method public boolean cancelLoad();
+ method public void commitContentChanged();
+ method public java.lang.String dataToString(D);
+ method public void deliverCancellation();
+ method public void deliverResult(D);
+ method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public void forceLoad();
+ method public android.content.Context getContext();
+ method public int getId();
+ method public boolean isAbandoned();
+ method public boolean isReset();
+ method public boolean isStarted();
+ method protected void onAbandon();
+ method protected boolean onCancelLoad();
+ method public void onContentChanged();
+ method protected void onForceLoad();
+ method protected void onReset();
+ method protected void onStartLoading();
+ method protected void onStopLoading();
+ method public void registerListener(int, android.support.v4.content.Loader.OnLoadCompleteListener<D>);
+ method public void registerOnLoadCanceledListener(android.support.v4.content.Loader.OnLoadCanceledListener<D>);
+ method public void reset();
+ method public void rollbackContentChanged();
+ method public final void startLoading();
+ method public void stopLoading();
+ method public boolean takeContentChanged();
+ method public void unregisterListener(android.support.v4.content.Loader.OnLoadCompleteListener<D>);
+ method public void unregisterOnLoadCanceledListener(android.support.v4.content.Loader.OnLoadCanceledListener<D>);
+ }
+
+ public final class Loader.ForceLoadContentObserver extends android.database.ContentObserver {
+ ctor public Loader.ForceLoadContentObserver();
+ }
+
+ public static abstract interface Loader.OnLoadCanceledListener {
+ method public abstract void onLoadCanceled(android.support.v4.content.Loader<D>);
+ }
+
+ public static abstract interface Loader.OnLoadCompleteListener {
+ method public abstract void onLoadComplete(android.support.v4.content.Loader<D>, D);
+ }
+
+ public class LocalBroadcastManager {
+ method public static android.support.v4.content.LocalBroadcastManager getInstance(android.content.Context);
+ method public void registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter);
+ method public boolean sendBroadcast(android.content.Intent);
+ method public void sendBroadcastSync(android.content.Intent);
+ method public void unregisterReceiver(android.content.BroadcastReceiver);
+ }
+
+ public class ParallelExecutorCompat {
+ ctor public ParallelExecutorCompat();
+ method public static java.util.concurrent.Executor getParallelExecutor();
+ }
+
+ public final class PermissionChecker {
+ method public static int checkCallingOrSelfPermission(android.content.Context, java.lang.String);
+ method public static int checkCallingPermission(android.content.Context, java.lang.String, java.lang.String);
+ method public static int checkPermission(android.content.Context, java.lang.String, int, int, java.lang.String);
+ method public static int checkSelfPermission(android.content.Context, java.lang.String);
+ field public static final int PERMISSION_DENIED = -1; // 0xffffffff
+ field public static final int PERMISSION_DENIED_APP_OP = -2; // 0xfffffffe
+ field public static final int PERMISSION_GRANTED = 0; // 0x0
+ }
+
+ public static abstract class PermissionChecker.PermissionResult implements java.lang.annotation.Annotation {
+ }
+
+ public class SharedPreferencesCompat {
+ ctor public SharedPreferencesCompat();
+ }
+
+ public static class SharedPreferencesCompat.EditorCompat {
+ method public void apply(android.content.SharedPreferences.Editor);
+ method public static android.support.v4.content.SharedPreferencesCompat.EditorCompat getInstance();
+ }
+
+ public abstract class WakefulBroadcastReceiver extends android.content.BroadcastReceiver {
+ ctor public WakefulBroadcastReceiver();
+ method public static boolean completeWakefulIntent(android.content.Intent);
+ method public static android.content.ComponentName startWakefulService(android.content.Context, android.content.Intent);
+ }
+
+}
+
+package android.support.v4.content.pm {
+
+ public class ActivityInfoCompat {
+ field public static final int CONFIG_UI_MODE = 512; // 0x200
+ }
+
+}
+
+package android.support.v4.content.res {
+
+ public class ResourcesCompat {
+ ctor public ResourcesCompat();
+ method public int getColor(android.content.res.Resources, int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
+ method public android.content.res.ColorStateList getColorStateList(android.content.res.Resources, int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
+ method public static android.graphics.drawable.Drawable getDrawable(android.content.res.Resources, int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
+ method public static android.graphics.drawable.Drawable getDrawableForDensity(android.content.res.Resources, int, int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
+ }
+
+}
+
+package android.support.v4.database {
+
+ public class DatabaseUtilsCompat {
+ method public static java.lang.String[] appendSelectionArgs(java.lang.String[], java.lang.String[]);
+ method public static java.lang.String concatenateWhere(java.lang.String, java.lang.String);
+ }
+
+}
+
+package android.support.v4.graphics {
+
+ public class BitmapCompat {
+ ctor public BitmapCompat();
+ method public static int getAllocationByteCount(android.graphics.Bitmap);
+ method public static boolean hasMipMap(android.graphics.Bitmap);
+ method public static void setHasMipMap(android.graphics.Bitmap, boolean);
+ }
+
+ public class ColorUtils {
+ method public static int HSLToColor(float[]);
+ method public static void RGBToHSL(int, int, int, float[]);
+ method public static double calculateContrast(int, int);
+ method public static double calculateLuminance(int);
+ method public static int calculateMinimumAlpha(int, int, float);
+ method public static void colorToHSL(int, float[]);
+ method public static int compositeColors(int, int);
+ method public static int setAlphaComponent(int, int);
+ }
+
+}
+
+package android.support.v4.graphics.drawable {
+
+ public class DrawableCompat {
+ ctor public DrawableCompat();
+ method public static int getLayoutDirection(android.graphics.drawable.Drawable);
+ method public static boolean isAutoMirrored(android.graphics.drawable.Drawable);
+ method public static void jumpToCurrentState(android.graphics.drawable.Drawable);
+ method public static void setAutoMirrored(android.graphics.drawable.Drawable, boolean);
+ method public static void setHotspot(android.graphics.drawable.Drawable, float, float);
+ method public static void setHotspotBounds(android.graphics.drawable.Drawable, int, int, int, int);
+ method public static void setLayoutDirection(android.graphics.drawable.Drawable, int);
+ method public static void setTint(android.graphics.drawable.Drawable, int);
+ method public static void setTintList(android.graphics.drawable.Drawable, android.content.res.ColorStateList);
+ method public static void setTintMode(android.graphics.drawable.Drawable, android.graphics.PorterDuff.Mode);
+ method public static T unwrap(android.graphics.drawable.Drawable);
+ method public static android.graphics.drawable.Drawable wrap(android.graphics.drawable.Drawable);
+ }
+
+ public abstract class RoundedBitmapDrawable extends android.graphics.drawable.Drawable {
+ method public void draw(android.graphics.Canvas);
+ method public final android.graphics.Bitmap getBitmap();
+ method public float getCornerRadius();
+ method public int getGravity();
+ method public int getOpacity();
+ method public final android.graphics.Paint getPaint();
+ method public boolean hasAntiAlias();
+ method public boolean hasMipMap();
+ method public boolean isCircular();
+ method public void setAlpha(int);
+ method public void setAntiAlias(boolean);
+ method public void setCircular(boolean);
+ method public void setColorFilter(android.graphics.ColorFilter);
+ method public void setCornerRadius(float);
+ method public void setGravity(int);
+ method public void setMipMap(boolean);
+ method public void setTargetDensity(android.graphics.Canvas);
+ method public void setTargetDensity(android.util.DisplayMetrics);
+ method public void setTargetDensity(int);
+ }
+
+ public class RoundedBitmapDrawableFactory {
+ ctor public RoundedBitmapDrawableFactory();
+ method public static android.support.v4.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, android.graphics.Bitmap);
+ method public static android.support.v4.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, java.lang.String);
+ method public static android.support.v4.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, java.io.InputStream);
+ }
+
+}
+
+package android.support.v4.hardware.display {
+
+ public abstract class DisplayManagerCompat {
+ method public abstract android.view.Display getDisplay(int);
+ method public abstract android.view.Display[] getDisplays();
+ method public abstract android.view.Display[] getDisplays(java.lang.String);
+ method public static android.support.v4.hardware.display.DisplayManagerCompat getInstance(android.content.Context);
+ field public static final java.lang.String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";
+ }
+
+}
+
+package android.support.v4.hardware.fingerprint {
+
+ public class FingerprintManagerCompat {
+ method public void authenticate(android.support.v4.hardware.fingerprint.FingerprintManagerCompat.CryptoObject, int, android.support.v4.os.CancellationSignal, android.support.v4.hardware.fingerprint.FingerprintManagerCompat.AuthenticationCallback, android.os.Handler);
+ method public static android.support.v4.hardware.fingerprint.FingerprintManagerCompat from(android.content.Context);
+ method public boolean hasEnrolledFingerprints();
+ method public boolean isHardwareDetected();
+ }
+
+ public static abstract class FingerprintManagerCompat.AuthenticationCallback {
+ ctor public FingerprintManagerCompat.AuthenticationCallback();
+ method public void onAuthenticationError(int, java.lang.CharSequence);
+ method public void onAuthenticationFailed();
+ method public void onAuthenticationHelp(int, java.lang.CharSequence);
+ method public void onAuthenticationSucceeded(android.support.v4.hardware.fingerprint.FingerprintManagerCompat.AuthenticationResult);
+ }
+
+ public static final class FingerprintManagerCompat.AuthenticationResult {
+ ctor public FingerprintManagerCompat.AuthenticationResult(android.support.v4.hardware.fingerprint.FingerprintManagerCompat.CryptoObject);
+ method public android.support.v4.hardware.fingerprint.FingerprintManagerCompat.CryptoObject getCryptoObject();
+ }
+
+ public static class FingerprintManagerCompat.CryptoObject {
+ ctor public FingerprintManagerCompat.CryptoObject(java.security.Signature);
+ ctor public FingerprintManagerCompat.CryptoObject(javax.crypto.Cipher);
+ ctor public FingerprintManagerCompat.CryptoObject(javax.crypto.Mac);
+ method public javax.crypto.Cipher getCipher();
+ method public javax.crypto.Mac getMac();
+ method public java.security.Signature getSignature();
+ }
+
+}
+
+package android.support.v4.media {
+
+ public final class MediaDescriptionCompat implements android.os.Parcelable {
+ method public int describeContents();
+ method public static android.support.v4.media.MediaDescriptionCompat fromMediaDescription(java.lang.Object);
+ method public java.lang.CharSequence getDescription();
+ method public android.os.Bundle getExtras();
+ method public android.graphics.Bitmap getIconBitmap();
+ method public android.net.Uri getIconUri();
+ method public java.lang.Object getMediaDescription();
+ method public java.lang.String getMediaId();
+ method public android.net.Uri getMediaUri();
+ method public java.lang.CharSequence getSubtitle();
+ method public java.lang.CharSequence getTitle();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.MediaDescriptionCompat> CREATOR;
+ }
+
+ public static final class MediaDescriptionCompat.Builder {
+ ctor public MediaDescriptionCompat.Builder();
+ method public android.support.v4.media.MediaDescriptionCompat build();
+ method public android.support.v4.media.MediaDescriptionCompat.Builder setDescription(java.lang.CharSequence);
+ method public android.support.v4.media.MediaDescriptionCompat.Builder setExtras(android.os.Bundle);
+ method public android.support.v4.media.MediaDescriptionCompat.Builder setIconBitmap(android.graphics.Bitmap);
+ method public android.support.v4.media.MediaDescriptionCompat.Builder setIconUri(android.net.Uri);
+ method public android.support.v4.media.MediaDescriptionCompat.Builder setMediaId(java.lang.String);
+ method public android.support.v4.media.MediaDescriptionCompat.Builder setMediaUri(android.net.Uri);
+ method public android.support.v4.media.MediaDescriptionCompat.Builder setSubtitle(java.lang.CharSequence);
+ method public android.support.v4.media.MediaDescriptionCompat.Builder setTitle(java.lang.CharSequence);
+ }
+
+ public final class MediaMetadataCompat implements android.os.Parcelable {
+ method public boolean containsKey(java.lang.String);
+ method public int describeContents();
+ method public static android.support.v4.media.MediaMetadataCompat fromMediaMetadata(java.lang.Object);
+ method public android.graphics.Bitmap getBitmap(java.lang.String);
+ method public android.os.Bundle getBundle();
+ method public android.support.v4.media.MediaDescriptionCompat getDescription();
+ method public long getLong(java.lang.String);
+ method public java.lang.Object getMediaMetadata();
+ method public android.support.v4.media.RatingCompat getRating(java.lang.String);
+ method public java.lang.String getString(java.lang.String);
+ method public java.lang.CharSequence getText(java.lang.String);
+ method public java.util.Set<java.lang.String> keySet();
+ method public int size();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.MediaMetadataCompat> CREATOR;
+ field public static final java.lang.String METADATA_KEY_ALBUM = "android.media.metadata.ALBUM";
+ field public static final java.lang.String METADATA_KEY_ALBUM_ART = "android.media.metadata.ALBUM_ART";
+ field public static final java.lang.String METADATA_KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST";
+ field public static final java.lang.String METADATA_KEY_ALBUM_ART_URI = "android.media.metadata.ALBUM_ART_URI";
+ field public static final java.lang.String METADATA_KEY_ART = "android.media.metadata.ART";
+ field public static final java.lang.String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST";
+ field public static final java.lang.String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI";
+ field public static final java.lang.String METADATA_KEY_AUTHOR = "android.media.metadata.AUTHOR";
+ field public static final java.lang.String METADATA_KEY_COMPILATION = "android.media.metadata.COMPILATION";
+ field public static final java.lang.String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER";
+ field public static final java.lang.String METADATA_KEY_DATE = "android.media.metadata.DATE";
+ field public static final java.lang.String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
+ field public static final java.lang.String METADATA_KEY_DISPLAY_DESCRIPTION = "android.media.metadata.DISPLAY_DESCRIPTION";
+ field public static final java.lang.String METADATA_KEY_DISPLAY_ICON = "android.media.metadata.DISPLAY_ICON";
+ field public static final java.lang.String METADATA_KEY_DISPLAY_ICON_URI = "android.media.metadata.DISPLAY_ICON_URI";
+ field public static final java.lang.String METADATA_KEY_DISPLAY_SUBTITLE = "android.media.metadata.DISPLAY_SUBTITLE";
+ field public static final java.lang.String METADATA_KEY_DISPLAY_TITLE = "android.media.metadata.DISPLAY_TITLE";
+ field public static final java.lang.String METADATA_KEY_DURATION = "android.media.metadata.DURATION";
+ field public static final java.lang.String METADATA_KEY_GENRE = "android.media.metadata.GENRE";
+ field public static final java.lang.String METADATA_KEY_MEDIA_ID = "android.media.metadata.MEDIA_ID";
+ field public static final java.lang.String METADATA_KEY_NUM_TRACKS = "android.media.metadata.NUM_TRACKS";
+ field public static final java.lang.String METADATA_KEY_RATING = "android.media.metadata.RATING";
+ field public static final java.lang.String METADATA_KEY_TITLE = "android.media.metadata.TITLE";
+ field public static final java.lang.String METADATA_KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER";
+ field public static final java.lang.String METADATA_KEY_USER_RATING = "android.media.metadata.USER_RATING";
+ field public static final java.lang.String METADATA_KEY_WRITER = "android.media.metadata.WRITER";
+ field public static final java.lang.String METADATA_KEY_YEAR = "android.media.metadata.YEAR";
+ }
+
+ public static final class MediaMetadataCompat.Builder {
+ ctor public MediaMetadataCompat.Builder();
+ ctor public MediaMetadataCompat.Builder(android.support.v4.media.MediaMetadataCompat);
+ method public android.support.v4.media.MediaMetadataCompat build();
+ method public android.support.v4.media.MediaMetadataCompat.Builder putBitmap(java.lang.String, android.graphics.Bitmap);
+ method public android.support.v4.media.MediaMetadataCompat.Builder putLong(java.lang.String, long);
+ method public android.support.v4.media.MediaMetadataCompat.Builder putRating(java.lang.String, android.support.v4.media.RatingCompat);
+ method public android.support.v4.media.MediaMetadataCompat.Builder putString(java.lang.String, java.lang.String);
+ method public android.support.v4.media.MediaMetadataCompat.Builder putText(java.lang.String, java.lang.CharSequence);
+ }
+
+ public final class RatingCompat implements android.os.Parcelable {
+ method public int describeContents();
+ method public static android.support.v4.media.RatingCompat fromRating(java.lang.Object);
+ method public float getPercentRating();
+ method public java.lang.Object getRating();
+ method public int getRatingStyle();
+ method public float getStarRating();
+ method public boolean hasHeart();
+ method public boolean isRated();
+ method public boolean isThumbUp();
+ method public static android.support.v4.media.RatingCompat newHeartRating(boolean);
+ method public static android.support.v4.media.RatingCompat newPercentageRating(float);
+ method public static android.support.v4.media.RatingCompat newStarRating(int, float);
+ method public static android.support.v4.media.RatingCompat newThumbRating(boolean);
+ method public static android.support.v4.media.RatingCompat newUnratedRating(int);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.RatingCompat> CREATOR;
+ field public static final int RATING_3_STARS = 3; // 0x3
+ field public static final int RATING_4_STARS = 4; // 0x4
+ field public static final int RATING_5_STARS = 5; // 0x5
+ field public static final int RATING_HEART = 1; // 0x1
+ field public static final int RATING_NONE = 0; // 0x0
+ field public static final int RATING_PERCENTAGE = 6; // 0x6
+ field public static final int RATING_THUMB_UP_DOWN = 2; // 0x2
+ }
+
+ public abstract class TransportController {
+ ctor public TransportController();
+ method public abstract int getBufferPercentage();
+ method public abstract long getCurrentPosition();
+ method public abstract long getDuration();
+ method public abstract int getTransportControlFlags();
+ method public abstract boolean isPlaying();
+ method public abstract void pausePlaying();
+ method public abstract void registerStateListener(android.support.v4.media.TransportStateListener);
+ method public abstract void seekTo(long);
+ method public abstract void startPlaying();
+ method public abstract void stopPlaying();
+ method public abstract void unregisterStateListener(android.support.v4.media.TransportStateListener);
+ }
+
+ public class TransportMediator extends android.support.v4.media.TransportController {
+ ctor public TransportMediator(android.app.Activity, android.support.v4.media.TransportPerformer);
+ ctor public TransportMediator(android.view.View, android.support.v4.media.TransportPerformer);
+ method public void destroy();
+ method public boolean dispatchKeyEvent(android.view.KeyEvent);
+ method public int getBufferPercentage();
+ method public long getCurrentPosition();
+ method public long getDuration();
+ method public java.lang.Object getRemoteControlClient();
+ method public int getTransportControlFlags();
+ method public boolean isPlaying();
+ method public void pausePlaying();
+ method public void refreshState();
+ method public void registerStateListener(android.support.v4.media.TransportStateListener);
+ method public void seekTo(long);
+ method public void startPlaying();
+ method public void stopPlaying();
+ method public void unregisterStateListener(android.support.v4.media.TransportStateListener);
+ field public static final int FLAG_KEY_MEDIA_FAST_FORWARD = 64; // 0x40
+ field public static final int FLAG_KEY_MEDIA_NEXT = 128; // 0x80
+ field public static final int FLAG_KEY_MEDIA_PAUSE = 16; // 0x10
+ field public static final int FLAG_KEY_MEDIA_PLAY = 4; // 0x4
+ field public static final int FLAG_KEY_MEDIA_PLAY_PAUSE = 8; // 0x8
+ field public static final int FLAG_KEY_MEDIA_PREVIOUS = 1; // 0x1
+ field public static final int FLAG_KEY_MEDIA_REWIND = 2; // 0x2
+ field public static final int FLAG_KEY_MEDIA_STOP = 32; // 0x20
+ field public static final int KEYCODE_MEDIA_PAUSE = 127; // 0x7f
+ field public static final int KEYCODE_MEDIA_PLAY = 126; // 0x7e
+ field public static final int KEYCODE_MEDIA_RECORD = 130; // 0x82
+ }
+
+ public abstract class TransportPerformer {
+ ctor public TransportPerformer();
+ method public void onAudioFocusChange(int);
+ method public int onGetBufferPercentage();
+ method public abstract long onGetCurrentPosition();
+ method public abstract long onGetDuration();
+ method public int onGetTransportControlFlags();
+ method public abstract boolean onIsPlaying();
+ method public boolean onMediaButtonDown(int, android.view.KeyEvent);
+ method public boolean onMediaButtonUp(int, android.view.KeyEvent);
+ method public abstract void onPause();
+ method public abstract void onSeekTo(long);
+ method public abstract void onStart();
+ method public abstract void onStop();
+ }
+
+ public class TransportStateListener {
+ ctor public TransportStateListener();
+ method public void onPlayingChanged(android.support.v4.media.TransportController);
+ method public void onTransportControlsChanged(android.support.v4.media.TransportController);
+ }
+
+ public abstract class VolumeProviderCompat {
+ ctor public VolumeProviderCompat(int, int, int);
+ method public final int getCurrentVolume();
+ method public final int getMaxVolume();
+ method public final int getVolumeControl();
+ method public java.lang.Object getVolumeProvider();
+ method public void onAdjustVolume(int);
+ method public void onSetVolumeTo(int);
+ method public void setCallback(android.support.v4.media.VolumeProviderCompat.Callback);
+ method public final void setCurrentVolume(int);
+ field public static final int VOLUME_CONTROL_ABSOLUTE = 2; // 0x2
+ field public static final int VOLUME_CONTROL_FIXED = 0; // 0x0
+ field public static final int VOLUME_CONTROL_RELATIVE = 1; // 0x1
+ }
+
+ public static abstract class VolumeProviderCompat.Callback {
+ ctor public VolumeProviderCompat.Callback();
+ method public abstract void onVolumeChanged(android.support.v4.media.VolumeProviderCompat);
+ }
+
+}
+
+package android.support.v4.media.session {
+
+ public class MediaButtonReceiver extends android.content.BroadcastReceiver {
+ ctor public MediaButtonReceiver();
+ method public static android.view.KeyEvent handleIntent(android.support.v4.media.session.MediaSessionCompat, android.content.Intent);
+ method public void onReceive(android.content.Context, android.content.Intent);
+ }
+
+ public final class MediaControllerCompat {
+ ctor public MediaControllerCompat(android.content.Context, android.support.v4.media.session.MediaSessionCompat);
+ ctor public MediaControllerCompat(android.content.Context, android.support.v4.media.session.MediaSessionCompat.Token) throws android.os.RemoteException;
+ method public void adjustVolume(int, int);
+ method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
+ method public android.os.Bundle getExtras();
+ method public long getFlags();
+ method public java.lang.Object getMediaController();
+ method public android.support.v4.media.MediaMetadataCompat getMetadata();
+ method public java.lang.String getPackageName();
+ method public android.support.v4.media.session.MediaControllerCompat.PlaybackInfo getPlaybackInfo();
+ method public android.support.v4.media.session.PlaybackStateCompat getPlaybackState();
+ method public java.util.List<android.support.v4.media.session.MediaSessionCompat.QueueItem> getQueue();
+ method public java.lang.CharSequence getQueueTitle();
+ method public int getRatingType();
+ method public android.app.PendingIntent getSessionActivity();
+ method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
+ method public android.support.v4.media.session.MediaControllerCompat.TransportControls getTransportControls();
+ method public void registerCallback(android.support.v4.media.session.MediaControllerCompat.Callback);
+ method public void registerCallback(android.support.v4.media.session.MediaControllerCompat.Callback, android.os.Handler);
+ method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
+ method public void setVolumeTo(int, int);
+ method public void unregisterCallback(android.support.v4.media.session.MediaControllerCompat.Callback);
+ }
+
+ public static abstract class MediaControllerCompat.Callback implements android.os.IBinder.DeathRecipient {
+ ctor public MediaControllerCompat.Callback();
+ method public void binderDied();
+ method public void onAudioInfoChanged(android.support.v4.media.session.MediaControllerCompat.PlaybackInfo);
+ method public void onExtrasChanged(android.os.Bundle);
+ method public void onMetadataChanged(android.support.v4.media.MediaMetadataCompat);
+ method public void onPlaybackStateChanged(android.support.v4.media.session.PlaybackStateCompat);
+ method public void onQueueChanged(java.util.List<android.support.v4.media.session.MediaSessionCompat.QueueItem>);
+ method public void onQueueTitleChanged(java.lang.CharSequence);
+ method public void onSessionDestroyed();
+ method public void onSessionEvent(java.lang.String, android.os.Bundle);
+ }
+
+ public static final class MediaControllerCompat.PlaybackInfo {
+ method public int getAudioStream();
+ method public int getCurrentVolume();
+ method public int getMaxVolume();
+ method public int getPlaybackType();
+ method public int getVolumeControl();
+ field public static final int PLAYBACK_TYPE_LOCAL = 1; // 0x1
+ field public static final int PLAYBACK_TYPE_REMOTE = 2; // 0x2
+ }
+
+ public static abstract class MediaControllerCompat.TransportControls {
+ method public abstract void fastForward();
+ method public abstract void pause();
+ method public abstract void play();
+ method public abstract void playFromMediaId(java.lang.String, android.os.Bundle);
+ method public abstract void playFromSearch(java.lang.String, android.os.Bundle);
+ method public abstract void playFromUri(android.net.Uri, android.os.Bundle);
+ method public abstract void rewind();
+ method public abstract void seekTo(long);
+ method public abstract void sendCustomAction(android.support.v4.media.session.PlaybackStateCompat.CustomAction, android.os.Bundle);
+ method public abstract void sendCustomAction(java.lang.String, android.os.Bundle);
+ method public abstract void setRating(android.support.v4.media.RatingCompat);
+ method public abstract void skipToNext();
+ method public abstract void skipToPrevious();
+ method public abstract void skipToQueueItem(long);
+ method public abstract void stop();
+ }
+
+ public class MediaSessionCompat {
+ ctor public MediaSessionCompat(android.content.Context, java.lang.String);
+ ctor public MediaSessionCompat(android.content.Context, java.lang.String, android.content.ComponentName, android.app.PendingIntent);
+ method public void addOnActiveChangeListener(android.support.v4.media.session.MediaSessionCompat.OnActiveChangeListener);
+ method public android.support.v4.media.session.MediaControllerCompat getController();
+ method public java.lang.Object getMediaSession();
+ method public java.lang.Object getRemoteControlClient();
+ method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
+ method public boolean isActive();
+ method public static android.support.v4.media.session.MediaSessionCompat obtain(android.content.Context, java.lang.Object);
+ method public void release();
+ method public void removeOnActiveChangeListener(android.support.v4.media.session.MediaSessionCompat.OnActiveChangeListener);
+ method public void sendSessionEvent(java.lang.String, android.os.Bundle);
+ method public void setActive(boolean);
+ method public void setCallback(android.support.v4.media.session.MediaSessionCompat.Callback);
+ method public void setCallback(android.support.v4.media.session.MediaSessionCompat.Callback, android.os.Handler);
+ method public void setExtras(android.os.Bundle);
+ method public void setFlags(int);
+ method public void setMediaButtonReceiver(android.app.PendingIntent);
+ method public void setMetadata(android.support.v4.media.MediaMetadataCompat);
+ method public void setPlaybackState(android.support.v4.media.session.PlaybackStateCompat);
+ method public void setPlaybackToLocal(int);
+ method public void setPlaybackToRemote(android.support.v4.media.VolumeProviderCompat);
+ method public void setQueue(java.util.List<android.support.v4.media.session.MediaSessionCompat.QueueItem>);
+ method public void setQueueTitle(java.lang.CharSequence);
+ method public void setRatingType(int);
+ method public void setSessionActivity(android.app.PendingIntent);
+ field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
+ field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
+ }
+
+ public static abstract class MediaSessionCompat.Callback {
+ ctor public MediaSessionCompat.Callback();
+ method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
+ method public void onCustomAction(java.lang.String, android.os.Bundle);
+ method public void onFastForward();
+ method public boolean onMediaButtonEvent(android.content.Intent);
+ method public void onPause();
+ method public void onPlay();
+ method public void onPlayFromMediaId(java.lang.String, android.os.Bundle);
+ method public void onPlayFromSearch(java.lang.String, android.os.Bundle);
+ method public void onPlayFromUri(android.net.Uri, android.os.Bundle);
+ method public void onRewind();
+ method public void onSeekTo(long);
+ method public void onSetRating(android.support.v4.media.RatingCompat);
+ method public void onSkipToNext();
+ method public void onSkipToPrevious();
+ method public void onSkipToQueueItem(long);
+ method public void onStop();
+ }
+
+ public static abstract interface MediaSessionCompat.OnActiveChangeListener {
+ method public abstract void onActiveChanged();
+ }
+
+ public static final class MediaSessionCompat.QueueItem implements android.os.Parcelable {
+ ctor public MediaSessionCompat.QueueItem(android.support.v4.media.MediaDescriptionCompat, long);
+ method public int describeContents();
+ method public android.support.v4.media.MediaDescriptionCompat getDescription();
+ method public long getQueueId();
+ method public java.lang.Object getQueueItem();
+ method public static android.support.v4.media.session.MediaSessionCompat.QueueItem obtain(java.lang.Object);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.session.MediaSessionCompat.QueueItem> CREATOR;
+ field public static final int UNKNOWN_ID = -1; // 0xffffffff
+ }
+
+ public static final class MediaSessionCompat.Token implements android.os.Parcelable {
+ method public int describeContents();
+ method public static android.support.v4.media.session.MediaSessionCompat.Token fromToken(java.lang.Object);
+ method public java.lang.Object getToken();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.session.MediaSessionCompat.Token> CREATOR;
+ }
+
+ public class ParcelableVolumeInfo implements android.os.Parcelable {
+ ctor public ParcelableVolumeInfo(int, int, int, int, int);
+ ctor public ParcelableVolumeInfo(android.os.Parcel);
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.session.ParcelableVolumeInfo> CREATOR;
+ field public int audioStream;
+ field public int controlType;
+ field public int currentVolume;
+ field public int maxVolume;
+ field public int volumeType;
+ }
+
+ public final class PlaybackStateCompat implements android.os.Parcelable {
+ method public int describeContents();
+ method public static android.support.v4.media.session.PlaybackStateCompat fromPlaybackState(java.lang.Object);
+ method public long getActions();
+ method public long getActiveQueueItemId();
+ method public long getBufferedPosition();
+ method public java.util.List<android.support.v4.media.session.PlaybackStateCompat.CustomAction> getCustomActions();
+ method public java.lang.CharSequence getErrorMessage();
+ method public android.os.Bundle getExtras();
+ method public long getLastPositionUpdateTime();
+ method public float getPlaybackSpeed();
+ method public java.lang.Object getPlaybackState();
+ method public long getPosition();
+ method public int getState();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final long ACTION_FAST_FORWARD = 64L; // 0x40L
+ field public static final long ACTION_PAUSE = 2L; // 0x2L
+ field public static final long ACTION_PLAY = 4L; // 0x4L
+ field public static final long ACTION_PLAY_FROM_MEDIA_ID = 1024L; // 0x400L
+ field public static final long ACTION_PLAY_FROM_SEARCH = 2048L; // 0x800L
+ field public static final long ACTION_PLAY_FROM_URI = 8192L; // 0x2000L
+ field public static final long ACTION_PLAY_PAUSE = 512L; // 0x200L
+ field public static final long ACTION_REWIND = 8L; // 0x8L
+ field public static final long ACTION_SEEK_TO = 256L; // 0x100L
+ field public static final long ACTION_SET_RATING = 128L; // 0x80L
+ field public static final long ACTION_SKIP_TO_NEXT = 32L; // 0x20L
+ field public static final long ACTION_SKIP_TO_PREVIOUS = 16L; // 0x10L
+ field public static final long ACTION_SKIP_TO_QUEUE_ITEM = 4096L; // 0x1000L
+ field public static final long ACTION_STOP = 1L; // 0x1L
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.session.PlaybackStateCompat> CREATOR;
+ field public static final long PLAYBACK_POSITION_UNKNOWN = -1L; // 0xffffffffffffffffL
+ field public static final int STATE_BUFFERING = 6; // 0x6
+ field public static final int STATE_CONNECTING = 8; // 0x8
+ field public static final int STATE_ERROR = 7; // 0x7
+ field public static final int STATE_FAST_FORWARDING = 4; // 0x4
+ field public static final int STATE_NONE = 0; // 0x0
+ field public static final int STATE_PAUSED = 2; // 0x2
+ field public static final int STATE_PLAYING = 3; // 0x3
+ field public static final int STATE_REWINDING = 5; // 0x5
+ field public static final int STATE_SKIPPING_TO_NEXT = 10; // 0xa
+ field public static final int STATE_SKIPPING_TO_PREVIOUS = 9; // 0x9
+ field public static final int STATE_SKIPPING_TO_QUEUE_ITEM = 11; // 0xb
+ field public static final int STATE_STOPPED = 1; // 0x1
+ }
+
+ public static final class PlaybackStateCompat.Builder {
+ ctor public PlaybackStateCompat.Builder();
+ ctor public PlaybackStateCompat.Builder(android.support.v4.media.session.PlaybackStateCompat);
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder addCustomAction(java.lang.String, java.lang.String, int);
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder addCustomAction(android.support.v4.media.session.PlaybackStateCompat.CustomAction);
+ method public android.support.v4.media.session.PlaybackStateCompat build();
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder setActions(long);
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder setActiveQueueItemId(long);
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder setBufferedPosition(long);
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder setErrorMessage(java.lang.CharSequence);
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder setExtras(android.os.Bundle);
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder setState(int, long, float);
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder setState(int, long, float, long);
+ }
+
+ public static final class PlaybackStateCompat.CustomAction implements android.os.Parcelable {
+ method public int describeContents();
+ method public static android.support.v4.media.session.PlaybackStateCompat.CustomAction fromCustomAction(java.lang.Object);
+ method public java.lang.String getAction();
+ method public java.lang.Object getCustomAction();
+ method public android.os.Bundle getExtras();
+ method public int getIcon();
+ method public java.lang.CharSequence getName();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.session.PlaybackStateCompat.CustomAction> CREATOR;
+ }
+
+ public static final class PlaybackStateCompat.CustomAction.Builder {
+ ctor public PlaybackStateCompat.CustomAction.Builder(java.lang.String, java.lang.CharSequence, int);
+ method public android.support.v4.media.session.PlaybackStateCompat.CustomAction build();
+ method public android.support.v4.media.session.PlaybackStateCompat.CustomAction.Builder setExtras(android.os.Bundle);
+ }
+
+}
+
+package android.support.v4.net {
+
+ public class ConnectivityManagerCompat {
+ ctor public ConnectivityManagerCompat();
+ method public static android.net.NetworkInfo getNetworkInfoFromBroadcast(android.net.ConnectivityManager, android.content.Intent);
+ method public static boolean isActiveNetworkMetered(android.net.ConnectivityManager);
+ }
+
+ public class TrafficStatsCompat {
+ ctor public TrafficStatsCompat();
+ method public static void clearThreadStatsTag();
+ method public static int getThreadStatsTag();
+ method public static void incrementOperationCount(int);
+ method public static void incrementOperationCount(int, int);
+ method public static void setThreadStatsTag(int);
+ method public static void tagSocket(java.net.Socket) throws java.net.SocketException;
+ method public static void untagSocket(java.net.Socket) throws java.net.SocketException;
+ }
+
+}
+
+package android.support.v4.os {
+
+ public class AsyncTaskCompat {
+ ctor public AsyncTaskCompat();
+ method public static android.os.AsyncTask<Params, Progress, Result> executeParallel(android.os.AsyncTask<Params, Progress, Result>, Params...);
+ }
+
+ public final class CancellationSignal {
+ ctor public CancellationSignal();
+ method public void cancel();
+ method public java.lang.Object getCancellationSignalObject();
+ method public boolean isCanceled();
+ method public void setOnCancelListener(android.support.v4.os.CancellationSignal.OnCancelListener);
+ method public void throwIfCanceled();
+ }
+
+ public static abstract interface CancellationSignal.OnCancelListener {
+ method public abstract void onCancel();
+ }
+
+ public class EnvironmentCompat {
+ ctor public EnvironmentCompat();
+ method public static java.lang.String getStorageState(java.io.File);
+ field public static final java.lang.String MEDIA_UNKNOWN = "unknown";
+ }
+
+ public class OperationCanceledException extends java.lang.RuntimeException {
+ ctor public OperationCanceledException();
+ ctor public OperationCanceledException(java.lang.String);
+ }
+
+ public class ParcelableCompat {
+ ctor public ParcelableCompat();
+ method public static android.os.Parcelable.Creator<T> newCreator(android.support.v4.os.ParcelableCompatCreatorCallbacks<T>);
+ }
+
+ public abstract interface ParcelableCompatCreatorCallbacks {
+ method public abstract T createFromParcel(android.os.Parcel, java.lang.ClassLoader);
+ method public abstract T[] newArray(int);
+ }
+
+ public class TraceCompat {
+ ctor public TraceCompat();
+ method public static void beginSection(java.lang.String);
+ method public static void endSection();
+ }
+
+}
+
+package android.support.v4.print {
+
+ public final class PrintHelper {
+ ctor public PrintHelper(android.content.Context);
+ method public int getColorMode();
+ method public int getOrientation();
+ method public int getScaleMode();
+ method public void printBitmap(java.lang.String, android.graphics.Bitmap);
+ method public void printBitmap(java.lang.String, android.graphics.Bitmap, android.support.v4.print.PrintHelper.OnPrintFinishCallback);
+ method public void printBitmap(java.lang.String, android.net.Uri) throws java.io.FileNotFoundException;
+ method public void printBitmap(java.lang.String, android.net.Uri, android.support.v4.print.PrintHelper.OnPrintFinishCallback) throws java.io.FileNotFoundException;
+ method public void setColorMode(int);
+ method public void setOrientation(int);
+ method public void setScaleMode(int);
+ method public static boolean systemSupportsPrint();
+ field public static final int COLOR_MODE_COLOR = 2; // 0x2
+ field public static final int COLOR_MODE_MONOCHROME = 1; // 0x1
+ field public static final int ORIENTATION_LANDSCAPE = 1; // 0x1
+ field public static final int ORIENTATION_PORTRAIT = 2; // 0x2
+ field public static final int SCALE_MODE_FILL = 2; // 0x2
+ field public static final int SCALE_MODE_FIT = 1; // 0x1
+ }
+
+ public static abstract interface PrintHelper.OnPrintFinishCallback {
+ method public abstract void onFinish();
+ }
+
+}
+
+package android.support.v4.provider {
+
+ public abstract class DocumentFile {
+ method public abstract boolean canRead();
+ method public abstract boolean canWrite();
+ method public abstract android.support.v4.provider.DocumentFile createDirectory(java.lang.String);
+ method public abstract android.support.v4.provider.DocumentFile createFile(java.lang.String, java.lang.String);
+ method public abstract boolean delete();
+ method public abstract boolean exists();
+ method public android.support.v4.provider.DocumentFile findFile(java.lang.String);
+ method public static android.support.v4.provider.DocumentFile fromFile(java.io.File);
+ method public static android.support.v4.provider.DocumentFile fromSingleUri(android.content.Context, android.net.Uri);
+ method public static android.support.v4.provider.DocumentFile fromTreeUri(android.content.Context, android.net.Uri);
+ method public abstract java.lang.String getName();
+ method public android.support.v4.provider.DocumentFile getParentFile();
+ method public abstract java.lang.String getType();
+ method public abstract android.net.Uri getUri();
+ method public abstract boolean isDirectory();
+ method public static boolean isDocumentUri(android.content.Context, android.net.Uri);
+ method public abstract boolean isFile();
+ method public abstract long lastModified();
+ method public abstract long length();
+ method public abstract android.support.v4.provider.DocumentFile[] listFiles();
+ method public abstract boolean renameTo(java.lang.String);
+ }
+
+}
+
+package android.support.v4.text {
+
+ public final class BidiFormatter {
+ method public static android.support.v4.text.BidiFormatter getInstance();
+ method public static android.support.v4.text.BidiFormatter getInstance(boolean);
+ method public static android.support.v4.text.BidiFormatter getInstance(java.util.Locale);
+ method public boolean getStereoReset();
+ method public boolean isRtl(java.lang.String);
+ method public boolean isRtlContext();
+ method public java.lang.String unicodeWrap(java.lang.String, android.support.v4.text.TextDirectionHeuristicCompat, boolean);
+ method public java.lang.String unicodeWrap(java.lang.String, android.support.v4.text.TextDirectionHeuristicCompat);
+ method public java.lang.String unicodeWrap(java.lang.String, boolean);
+ method public java.lang.String unicodeWrap(java.lang.String);
+ }
+
+ public static final class BidiFormatter.Builder {
+ ctor public BidiFormatter.Builder();
+ ctor public BidiFormatter.Builder(boolean);
+ ctor public BidiFormatter.Builder(java.util.Locale);
+ method public android.support.v4.text.BidiFormatter build();
+ method public android.support.v4.text.BidiFormatter.Builder setTextDirectionHeuristic(android.support.v4.text.TextDirectionHeuristicCompat);
+ method public android.support.v4.text.BidiFormatter.Builder stereoReset(boolean);
+ }
+
+ public class ICUCompat {
+ ctor public ICUCompat();
+ method public static java.lang.String maximizeAndGetScript(java.util.Locale);
+ }
+
+ public abstract interface TextDirectionHeuristicCompat {
+ method public abstract boolean isRtl(char[], int, int);
+ method public abstract boolean isRtl(java.lang.CharSequence, int, int);
+ }
+
+ public class TextDirectionHeuristicsCompat {
+ ctor public TextDirectionHeuristicsCompat();
+ field public static final android.support.v4.text.TextDirectionHeuristicCompat ANYRTL_LTR;
+ field public static final android.support.v4.text.TextDirectionHeuristicCompat FIRSTSTRONG_LTR;
+ field public static final android.support.v4.text.TextDirectionHeuristicCompat FIRSTSTRONG_RTL;
+ field public static final android.support.v4.text.TextDirectionHeuristicCompat LOCALE;
+ field public static final android.support.v4.text.TextDirectionHeuristicCompat LTR;
+ field public static final android.support.v4.text.TextDirectionHeuristicCompat RTL;
+ }
+
+ public class TextUtilsCompat {
+ ctor public TextUtilsCompat();
+ method public static int getLayoutDirectionFromLocale(java.util.Locale);
+ method public static java.lang.String htmlEncode(java.lang.String);
+ field public static final java.util.Locale ROOT;
+ }
+
+}
+
+package android.support.v4.util {
+
+ public class ArrayMap extends android.support.v4.util.SimpleArrayMap implements java.util.Map {
+ ctor public ArrayMap();
+ ctor public ArrayMap(int);
+ ctor public ArrayMap(android.support.v4.util.SimpleArrayMap);
+ method public boolean containsAll(java.util.Collection<?>);
+ method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+ method public java.util.Set<K> keySet();
+ method public void putAll(java.util.Map<? extends K, ? extends V>);
+ method public boolean removeAll(java.util.Collection<?>);
+ method public boolean retainAll(java.util.Collection<?>);
+ method public java.util.Collection<V> values();
+ }
+
+ public class AtomicFile {
+ ctor public AtomicFile(java.io.File);
+ method public void delete();
+ method public void failWrite(java.io.FileOutputStream);
+ method public void finishWrite(java.io.FileOutputStream);
+ method public java.io.File getBaseFile();
+ method public java.io.FileInputStream openRead() throws java.io.FileNotFoundException;
+ method public byte[] readFully() throws java.io.IOException;
+ method public java.io.FileOutputStream startWrite() throws java.io.IOException;
+ }
+
+ public final class CircularArray {
+ ctor public CircularArray();
+ ctor public CircularArray(int);
+ method public void addFirst(E);
+ method public void addLast(E);
+ method public void clear();
+ method public E get(int);
+ method public E getFirst();
+ method public E getLast();
+ method public boolean isEmpty();
+ method public E popFirst();
+ method public E popLast();
+ method public void removeFromEnd(int);
+ method public void removeFromStart(int);
+ method public int size();
+ }
+
+ public final class CircularIntArray {
+ ctor public CircularIntArray();
+ ctor public CircularIntArray(int);
+ method public void addFirst(int);
+ method public void addLast(int);
+ method public void clear();
+ method public int get(int);
+ method public int getFirst();
+ method public int getLast();
+ method public boolean isEmpty();
+ method public int popFirst();
+ method public int popLast();
+ method public void removeFromEnd(int);
+ method public void removeFromStart(int);
+ method public int size();
+ }
+
+ public class LongSparseArray {
+ ctor public LongSparseArray();
+ ctor public LongSparseArray(int);
+ method public void append(long, E);
+ method public void clear();
+ method public android.support.v4.util.LongSparseArray<E> clone();
+ method public void delete(long);
+ method public E get(long);
+ method public E get(long, E);
+ method public int indexOfKey(long);
+ method public int indexOfValue(E);
+ method public long keyAt(int);
+ method public void put(long, E);
+ method public void remove(long);
+ method public void removeAt(int);
+ method public void setValueAt(int, E);
+ method public int size();
+ method public E valueAt(int);
+ }
+
+ public class LruCache {
+ ctor public LruCache(int);
+ method protected V create(K);
+ method public final synchronized int createCount();
+ method protected void entryRemoved(boolean, K, V, V);
+ method public final void evictAll();
+ method public final synchronized int evictionCount();
+ method public final V get(K);
+ method public final synchronized int hitCount();
+ method public final synchronized int maxSize();
+ method public final synchronized int missCount();
+ method public final V put(K, V);
+ method public final synchronized int putCount();
+ method public final V remove(K);
+ method public void resize(int);
+ method public final synchronized int size();
+ method protected int sizeOf(K, V);
+ method public final synchronized java.util.Map<K, V> snapshot();
+ method public final synchronized java.lang.String toString();
+ method public void trimToSize(int);
+ }
+
+ public class Pair {
+ ctor public Pair(F, S);
+ method public static android.support.v4.util.Pair<A, B> create(A, B);
+ field public final F first;
+ field public final S second;
+ }
+
+ public final class Pools {
+ }
+
+ public static abstract interface Pools.Pool {
+ method public abstract T acquire();
+ method public abstract boolean release(T);
+ }
+
+ public static class Pools.SimplePool implements android.support.v4.util.Pools.Pool {
+ ctor public Pools.SimplePool(int);
+ method public T acquire();
+ method public boolean release(T);
+ }
+
+ public static class Pools.SynchronizedPool extends android.support.v4.util.Pools.SimplePool {
+ ctor public Pools.SynchronizedPool(int);
+ }
+
+ public class SimpleArrayMap {
+ ctor public SimpleArrayMap();
+ ctor public SimpleArrayMap(int);
+ ctor public SimpleArrayMap(android.support.v4.util.SimpleArrayMap);
+ method public void clear();
+ method public boolean containsKey(java.lang.Object);
+ method public boolean containsValue(java.lang.Object);
+ method public void ensureCapacity(int);
+ method public V get(java.lang.Object);
+ method public int indexOfKey(java.lang.Object);
+ method public boolean isEmpty();
+ method public K keyAt(int);
+ method public V put(K, V);
+ method public void putAll(android.support.v4.util.SimpleArrayMap<? extends K, ? extends V>);
+ method public V remove(java.lang.Object);
+ method public V removeAt(int);
+ method public V setValueAt(int, V);
+ method public int size();
+ method public V valueAt(int);
+ }
+
+ public class SparseArrayCompat {
+ ctor public SparseArrayCompat();
+ ctor public SparseArrayCompat(int);
+ method public void append(int, E);
+ method public void clear();
+ method public android.support.v4.util.SparseArrayCompat<E> clone();
+ method public void delete(int);
+ method public E get(int);
+ method public E get(int, E);
+ method public int indexOfKey(int);
+ method public int indexOfValue(E);
+ method public int keyAt(int);
+ method public void put(int, E);
+ method public void remove(int);
+ method public void removeAt(int);
+ method public void removeAtRange(int, int);
+ method public void setValueAt(int, E);
+ method public int size();
+ method public E valueAt(int);
+ }
+
+}
+
+package android.support.v4.view {
+
+ public class AccessibilityDelegateCompat {
+ ctor public AccessibilityDelegateCompat();
+ method public boolean dispatchPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+ method public android.support.v4.view.accessibility.AccessibilityNodeProviderCompat getAccessibilityNodeProvider(android.view.View);
+ method public void onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+ method public void onInitializeAccessibilityNodeInfo(android.view.View, android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+ method public void onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+ method public boolean onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent);
+ method public boolean performAccessibilityAction(android.view.View, int, android.os.Bundle);
+ method public void sendAccessibilityEvent(android.view.View, int);
+ method public void sendAccessibilityEventUnchecked(android.view.View, android.view.accessibility.AccessibilityEvent);
+ }
+
+ public abstract class ActionProvider {
+ ctor public ActionProvider(android.content.Context);
+ method public android.content.Context getContext();
+ method public boolean hasSubMenu();
+ method public boolean isVisible();
+ method public abstract android.view.View onCreateActionView();
+ method public android.view.View onCreateActionView(android.view.MenuItem);
+ method public boolean onPerformDefaultAction();
+ method public void onPrepareSubMenu(android.view.SubMenu);
+ method public boolean overridesItemVisibility();
+ method public void refreshVisibility();
+ method public void setVisibilityListener(android.support.v4.view.ActionProvider.VisibilityListener);
+ }
+
+ public static abstract interface ActionProvider.VisibilityListener {
+ method public abstract void onActionProviderVisibilityChanged(boolean);
+ }
+
+ public class GestureDetectorCompat {
+ ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener);
+ ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler);
+ method public boolean isLongpressEnabled();
+ method public boolean onTouchEvent(android.view.MotionEvent);
+ method public void setIsLongpressEnabled(boolean);
+ method public void setOnDoubleTapListener(android.view.GestureDetector.OnDoubleTapListener);
+ }
+
+ public class GravityCompat {
+ ctor public GravityCompat();
+ method public static void apply(int, int, int, android.graphics.Rect, android.graphics.Rect, int);
+ method public static void apply(int, int, int, android.graphics.Rect, int, int, android.graphics.Rect, int);
+ method public static void applyDisplay(int, android.graphics.Rect, android.graphics.Rect, int);
+ method public static int getAbsoluteGravity(int, int);
+ field public static final int END = 8388613; // 0x800005
+ field public static final int RELATIVE_HORIZONTAL_GRAVITY_MASK = 8388615; // 0x800007
+ field public static final int RELATIVE_LAYOUT_DIRECTION = 8388608; // 0x800000
+ field public static final int START = 8388611; // 0x800003
+ }
+
+ public class InputDeviceCompat {
+ ctor public InputDeviceCompat();
+ field public static final int SOURCE_ANY = -256; // 0xffffff00
+ field public static final int SOURCE_CLASS_BUTTON = 1; // 0x1
+ field public static final int SOURCE_CLASS_JOYSTICK = 16; // 0x10
+ field public static final int SOURCE_CLASS_MASK = 255; // 0xff
+ field public static final int SOURCE_CLASS_NONE = 0; // 0x0
+ field public static final int SOURCE_CLASS_POINTER = 2; // 0x2
+ field public static final int SOURCE_CLASS_POSITION = 8; // 0x8
+ field public static final int SOURCE_CLASS_TRACKBALL = 4; // 0x4
+ field public static final int SOURCE_DPAD = 513; // 0x201
+ field public static final int SOURCE_GAMEPAD = 1025; // 0x401
+ field public static final int SOURCE_HDMI = 33554433; // 0x2000001
+ field public static final int SOURCE_JOYSTICK = 16777232; // 0x1000010
+ field public static final int SOURCE_KEYBOARD = 257; // 0x101
+ field public static final int SOURCE_MOUSE = 8194; // 0x2002
+ field public static final int SOURCE_STYLUS = 16386; // 0x4002
+ field public static final int SOURCE_TOUCHPAD = 1048584; // 0x100008
+ field public static final int SOURCE_TOUCHSCREEN = 4098; // 0x1002
+ field public static final int SOURCE_TOUCH_NAVIGATION = 2097152; // 0x200000
+ field public static final int SOURCE_TRACKBALL = 65540; // 0x10004
+ field public static final int SOURCE_UNKNOWN = 0; // 0x0
+ }
+
+ public class KeyEventCompat {
+ ctor public KeyEventCompat();
+ method public static boolean dispatch(android.view.KeyEvent, android.view.KeyEvent.Callback, java.lang.Object, java.lang.Object);
+ method public static java.lang.Object getKeyDispatcherState(android.view.View);
+ method public static boolean hasModifiers(android.view.KeyEvent, int);
+ method public static boolean hasNoModifiers(android.view.KeyEvent);
+ method public static boolean isTracking(android.view.KeyEvent);
+ method public static boolean metaStateHasModifiers(int, int);
+ method public static boolean metaStateHasNoModifiers(int);
+ method public static int normalizeMetaState(int);
+ method public static void startTracking(android.view.KeyEvent);
+ }
+
+ public class LayoutInflaterCompat {
+ method public static void setFactory(android.view.LayoutInflater, android.support.v4.view.LayoutInflaterFactory);
+ }
+
+ public abstract interface LayoutInflaterFactory {
+ method public abstract android.view.View onCreateView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet);
+ }
+
+ public class MarginLayoutParamsCompat {
+ ctor public MarginLayoutParamsCompat();
+ method public static int getLayoutDirection(android.view.ViewGroup.MarginLayoutParams);
+ method public static int getMarginEnd(android.view.ViewGroup.MarginLayoutParams);
+ method public static int getMarginStart(android.view.ViewGroup.MarginLayoutParams);
+ method public static boolean isMarginRelative(android.view.ViewGroup.MarginLayoutParams);
+ method public static void resolveLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
+ method public static void setLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
+ method public static void setMarginEnd(android.view.ViewGroup.MarginLayoutParams, int);
+ method public static void setMarginStart(android.view.ViewGroup.MarginLayoutParams, int);
+ }
+
+ public class MenuCompat {
+ ctor public MenuCompat();
+ method public static deprecated void setShowAsAction(android.view.MenuItem, int);
+ }
+
+ public class MenuItemCompat {
+ ctor public MenuItemCompat();
+ method public static boolean collapseActionView(android.view.MenuItem);
+ method public static boolean expandActionView(android.view.MenuItem);
+ method public static android.support.v4.view.ActionProvider getActionProvider(android.view.MenuItem);
+ method public static android.view.View getActionView(android.view.MenuItem);
+ method public static boolean isActionViewExpanded(android.view.MenuItem);
+ method public static android.view.MenuItem setActionProvider(android.view.MenuItem, android.support.v4.view.ActionProvider);
+ method public static android.view.MenuItem setActionView(android.view.MenuItem, android.view.View);
+ method public static android.view.MenuItem setActionView(android.view.MenuItem, int);
+ method public static android.view.MenuItem setOnActionExpandListener(android.view.MenuItem, android.support.v4.view.MenuItemCompat.OnActionExpandListener);
+ method public static void setShowAsAction(android.view.MenuItem, int);
+ field public static final int SHOW_AS_ACTION_ALWAYS = 2; // 0x2
+ field public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8; // 0x8
+ field public static final int SHOW_AS_ACTION_IF_ROOM = 1; // 0x1
+ field public static final int SHOW_AS_ACTION_NEVER = 0; // 0x0
+ field public static final int SHOW_AS_ACTION_WITH_TEXT = 4; // 0x4
+ }
+
+ public static abstract interface MenuItemCompat.OnActionExpandListener {
+ method public abstract boolean onMenuItemActionCollapse(android.view.MenuItem);
+ method public abstract boolean onMenuItemActionExpand(android.view.MenuItem);
+ }
+
+ public class MotionEventCompat {
+ ctor public MotionEventCompat();
+ method public static int findPointerIndex(android.view.MotionEvent, int);
+ method public static int getActionIndex(android.view.MotionEvent);
+ method public static int getActionMasked(android.view.MotionEvent);
+ method public static float getAxisValue(android.view.MotionEvent, int);
+ method public static float getAxisValue(android.view.MotionEvent, int, int);
+ method public static int getPointerCount(android.view.MotionEvent);
+ method public static int getPointerId(android.view.MotionEvent, int);
+ method public static int getSource(android.view.MotionEvent);
+ method public static float getX(android.view.MotionEvent, int);
+ method public static float getY(android.view.MotionEvent, int);
+ field public static final int ACTION_HOVER_ENTER = 9; // 0x9
+ field public static final int ACTION_HOVER_EXIT = 10; // 0xa
+ field public static final int ACTION_HOVER_MOVE = 7; // 0x7
+ field public static final int ACTION_MASK = 255; // 0xff
+ field public static final int ACTION_POINTER_DOWN = 5; // 0x5
+ field public static final int ACTION_POINTER_INDEX_MASK = 65280; // 0xff00
+ field public static final int ACTION_POINTER_INDEX_SHIFT = 8; // 0x8
+ field public static final int ACTION_POINTER_UP = 6; // 0x6
+ field public static final int ACTION_SCROLL = 8; // 0x8
+ field public static final int AXIS_BRAKE = 23; // 0x17
+ field public static final int AXIS_DISTANCE = 24; // 0x18
+ field public static final int AXIS_GAS = 22; // 0x16
+ field public static final int AXIS_GENERIC_1 = 32; // 0x20
+ field public static final int AXIS_GENERIC_10 = 41; // 0x29
+ field public static final int AXIS_GENERIC_11 = 42; // 0x2a
+ field public static final int AXIS_GENERIC_12 = 43; // 0x2b
+ field public static final int AXIS_GENERIC_13 = 44; // 0x2c
+ field public static final int AXIS_GENERIC_14 = 45; // 0x2d
+ field public static final int AXIS_GENERIC_15 = 46; // 0x2e
+ field public static final int AXIS_GENERIC_16 = 47; // 0x2f
+ field public static final int AXIS_GENERIC_2 = 33; // 0x21
+ field public static final int AXIS_GENERIC_3 = 34; // 0x22
+ field public static final int AXIS_GENERIC_4 = 35; // 0x23
+ field public static final int AXIS_GENERIC_5 = 36; // 0x24
+ field public static final int AXIS_GENERIC_6 = 37; // 0x25
+ field public static final int AXIS_GENERIC_7 = 38; // 0x26
+ field public static final int AXIS_GENERIC_8 = 39; // 0x27
+ field public static final int AXIS_GENERIC_9 = 40; // 0x28
+ field public static final int AXIS_HAT_X = 15; // 0xf
+ field public static final int AXIS_HAT_Y = 16; // 0x10
+ field public static final int AXIS_HSCROLL = 10; // 0xa
+ field public static final int AXIS_LTRIGGER = 17; // 0x11
+ field public static final int AXIS_ORIENTATION = 8; // 0x8
+ field public static final int AXIS_PRESSURE = 2; // 0x2
+ field public static final int AXIS_RTRIGGER = 18; // 0x12
+ field public static final int AXIS_RUDDER = 20; // 0x14
+ field public static final int AXIS_RX = 12; // 0xc
+ field public static final int AXIS_RY = 13; // 0xd
+ field public static final int AXIS_RZ = 14; // 0xe
+ field public static final int AXIS_SIZE = 3; // 0x3
+ field public static final int AXIS_THROTTLE = 19; // 0x13
+ field public static final int AXIS_TILT = 25; // 0x19
+ field public static final int AXIS_TOOL_MAJOR = 6; // 0x6
+ field public static final int AXIS_TOOL_MINOR = 7; // 0x7
+ field public static final int AXIS_TOUCH_MAJOR = 4; // 0x4
+ field public static final int AXIS_TOUCH_MINOR = 5; // 0x5
+ field public static final int AXIS_VSCROLL = 9; // 0x9
+ field public static final int AXIS_WHEEL = 21; // 0x15
+ field public static final int AXIS_X = 0; // 0x0
+ field public static final int AXIS_Y = 1; // 0x1
+ field public static final int AXIS_Z = 11; // 0xb
+ }
+
+ public abstract interface NestedScrollingChild {
+ method public abstract boolean dispatchNestedFling(float, float, boolean);
+ method public abstract boolean dispatchNestedPreFling(float, float);
+ method public abstract boolean dispatchNestedPreScroll(int, int, int[], int[]);
+ method public abstract boolean dispatchNestedScroll(int, int, int, int, int[]);
+ method public abstract boolean hasNestedScrollingParent();
+ method public abstract boolean isNestedScrollingEnabled();
+ method public abstract void setNestedScrollingEnabled(boolean);
+ method public abstract boolean startNestedScroll(int);
+ method public abstract void stopNestedScroll();
+ }
+
+ public class NestedScrollingChildHelper {
+ ctor public NestedScrollingChildHelper(android.view.View);
+ method public boolean dispatchNestedFling(float, float, boolean);
+ method public boolean dispatchNestedPreFling(float, float);
+ method public boolean dispatchNestedPreScroll(int, int, int[], int[]);
+ method public boolean dispatchNestedScroll(int, int, int, int, int[]);
+ method public boolean hasNestedScrollingParent();
+ method public boolean isNestedScrollingEnabled();
+ method public void onDetachedFromWindow();
+ method public void onStopNestedScroll(android.view.View);
+ method public void setNestedScrollingEnabled(boolean);
+ method public boolean startNestedScroll(int);
+ method public void stopNestedScroll();
+ }
+
+ public abstract interface NestedScrollingParent {
+ method public abstract int getNestedScrollAxes();
+ method public abstract boolean onNestedFling(android.view.View, float, float, boolean);
+ method public abstract boolean onNestedPreFling(android.view.View, float, float);
+ method public abstract void onNestedPreScroll(android.view.View, int, int, int[]);
+ method public abstract void onNestedScroll(android.view.View, int, int, int, int);
+ method public abstract void onNestedScrollAccepted(android.view.View, android.view.View, int);
+ method public abstract boolean onStartNestedScroll(android.view.View, android.view.View, int);
+ method public abstract void onStopNestedScroll(android.view.View);
+ }
+
+ public class NestedScrollingParentHelper {
+ ctor public NestedScrollingParentHelper(android.view.ViewGroup);
+ method public int getNestedScrollAxes();
+ method public void onNestedScrollAccepted(android.view.View, android.view.View, int);
+ method public void onStopNestedScroll(android.view.View);
+ }
+
+ public abstract interface OnApplyWindowInsetsListener {
+ method public abstract android.support.v4.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, android.support.v4.view.WindowInsetsCompat);
+ }
+
+ public abstract class PagerAdapter {
+ ctor public PagerAdapter();
+ method public void destroyItem(android.view.ViewGroup, int, java.lang.Object);
+ method public deprecated void destroyItem(android.view.View, int, java.lang.Object);
+ method public void finishUpdate(android.view.ViewGroup);
+ method public deprecated void finishUpdate(android.view.View);
+ method public abstract int getCount();
+ method public int getItemPosition(java.lang.Object);
+ method public java.lang.CharSequence getPageTitle(int);
+ method public float getPageWidth(int);
+ method public java.lang.Object instantiateItem(android.view.ViewGroup, int);
+ method public deprecated java.lang.Object instantiateItem(android.view.View, int);
+ method public abstract boolean isViewFromObject(android.view.View, java.lang.Object);
+ method public void notifyDataSetChanged();
+ method public void registerDataSetObserver(android.database.DataSetObserver);
+ method public void restoreState(android.os.Parcelable, java.lang.ClassLoader);
+ method public android.os.Parcelable saveState();
+ method public void setPrimaryItem(android.view.ViewGroup, int, java.lang.Object);
+ method public deprecated void setPrimaryItem(android.view.View, int, java.lang.Object);
+ method public void startUpdate(android.view.ViewGroup);
+ method public deprecated void startUpdate(android.view.View);
+ method public void unregisterDataSetObserver(android.database.DataSetObserver);
+ field public static final int POSITION_NONE = -2; // 0xfffffffe
+ field public static final int POSITION_UNCHANGED = -1; // 0xffffffff
+ }
+
+ public class PagerTabStrip extends android.support.v4.view.PagerTitleStrip {
+ ctor public PagerTabStrip(android.content.Context);
+ ctor public PagerTabStrip(android.content.Context, android.util.AttributeSet);
+ method public boolean getDrawFullUnderline();
+ method public int getTabIndicatorColor();
+ method public void setDrawFullUnderline(boolean);
+ method public void setTabIndicatorColor(int);
+ method public void setTabIndicatorColorResource(int);
+ }
+
+ public class PagerTitleStrip extends android.view.ViewGroup {
+ ctor public PagerTitleStrip(android.content.Context);
+ ctor public PagerTitleStrip(android.content.Context, android.util.AttributeSet);
+ method public int getTextSpacing();
+ method protected void onLayout(boolean, int, int, int, int);
+ method public void setGravity(int);
+ method public void setNonPrimaryAlpha(float);
+ method public void setTextColor(int);
+ method public void setTextSize(int, float);
+ method public void setTextSpacing(int);
+ }
+
+ public class ScaleGestureDetectorCompat {
+ method public static boolean isQuickScaleEnabled(java.lang.Object);
+ method public static void setQuickScaleEnabled(java.lang.Object, boolean);
+ }
+
+ public abstract interface ScrollingView {
+ method public abstract int computeHorizontalScrollExtent();
+ method public abstract int computeHorizontalScrollOffset();
+ method public abstract int computeHorizontalScrollRange();
+ method public abstract int computeVerticalScrollExtent();
+ method public abstract int computeVerticalScrollOffset();
+ method public abstract int computeVerticalScrollRange();
+ }
+
+ public class VelocityTrackerCompat {
+ ctor public VelocityTrackerCompat();
+ method public static float getXVelocity(android.view.VelocityTracker, int);
+ method public static float getYVelocity(android.view.VelocityTracker, int);
+ }
+
+ public class ViewCompat {
+ ctor public ViewCompat();
+ method public static android.support.v4.view.ViewPropertyAnimatorCompat animate(android.view.View);
+ method public static boolean canScrollHorizontally(android.view.View, int);
+ method public static boolean canScrollVertically(android.view.View, int);
+ method public static int combineMeasuredStates(int, int);
+ method public static android.support.v4.view.WindowInsetsCompat dispatchApplyWindowInsets(android.view.View, android.support.v4.view.WindowInsetsCompat);
+ method public static void dispatchFinishTemporaryDetach(android.view.View);
+ method public static boolean dispatchNestedFling(android.view.View, float, float, boolean);
+ method public static boolean dispatchNestedPreFling(android.view.View, float, float);
+ method public static boolean dispatchNestedPreScroll(android.view.View, int, int, int[], int[]);
+ method public static boolean dispatchNestedScroll(android.view.View, int, int, int, int, int[]);
+ method public static void dispatchStartTemporaryDetach(android.view.View);
+ method public static int getAccessibilityLiveRegion(android.view.View);
+ method public static android.support.v4.view.accessibility.AccessibilityNodeProviderCompat getAccessibilityNodeProvider(android.view.View);
+ method public static float getAlpha(android.view.View);
+ method public static android.content.res.ColorStateList getBackgroundTintList(android.view.View);
+ method public static android.graphics.PorterDuff.Mode getBackgroundTintMode(android.view.View);
+ method public static android.graphics.Rect getClipBounds(android.view.View);
+ method public static float getElevation(android.view.View);
+ method public static boolean getFitsSystemWindows(android.view.View);
+ method public static int getImportantForAccessibility(android.view.View);
+ method public static int getLabelFor(android.view.View);
+ method public static int getLayerType(android.view.View);
+ method public static int getLayoutDirection(android.view.View);
+ method public static int getMeasuredHeightAndState(android.view.View);
+ method public static int getMeasuredState(android.view.View);
+ method public static int getMeasuredWidthAndState(android.view.View);
+ method public static int getMinimumHeight(android.view.View);
+ method public static int getMinimumWidth(android.view.View);
+ method public static int getOverScrollMode(android.view.View);
+ method public static int getPaddingEnd(android.view.View);
+ method public static int getPaddingStart(android.view.View);
+ method public static android.view.ViewParent getParentForAccessibility(android.view.View);
+ method public static float getPivotX(android.view.View);
+ method public static float getPivotY(android.view.View);
+ method public static float getRotation(android.view.View);
+ method public static float getRotationX(android.view.View);
+ method public static float getRotationY(android.view.View);
+ method public static float getScaleX(android.view.View);
+ method public static float getScaleY(android.view.View);
+ method public static int getScrollIndicators(android.view.View);
+ method public static java.lang.String getTransitionName(android.view.View);
+ method public static float getTranslationX(android.view.View);
+ method public static float getTranslationY(android.view.View);
+ method public static float getTranslationZ(android.view.View);
+ method public static int getWindowSystemUiVisibility(android.view.View);
+ method public static float getX(android.view.View);
+ method public static float getY(android.view.View);
+ method public static float getZ(android.view.View);
+ method public static boolean hasAccessibilityDelegate(android.view.View);
+ method public static boolean hasNestedScrollingParent(android.view.View);
+ method public static boolean hasOnClickListeners(android.view.View);
+ method public static boolean hasOverlappingRendering(android.view.View);
+ method public static boolean hasTransientState(android.view.View);
+ method public static boolean isAttachedToWindow(android.view.View);
+ method public static boolean isLaidOut(android.view.View);
+ method public static boolean isNestedScrollingEnabled(android.view.View);
+ method public static boolean isOpaque(android.view.View);
+ method public static boolean isPaddingRelative(android.view.View);
+ method public static void jumpDrawablesToCurrentState(android.view.View);
+ method public static void offsetLeftAndRight(android.view.View, int);
+ method public static void offsetTopAndBottom(android.view.View, int);
+ method public static android.support.v4.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, android.support.v4.view.WindowInsetsCompat);
+ method public static void onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+ method public static void onInitializeAccessibilityNodeInfo(android.view.View, android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+ method public static void onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+ method public static boolean performAccessibilityAction(android.view.View, int, android.os.Bundle);
+ method public static void postInvalidateOnAnimation(android.view.View);
+ method public static void postInvalidateOnAnimation(android.view.View, int, int, int, int);
+ method public static void postOnAnimation(android.view.View, java.lang.Runnable);
+ method public static void postOnAnimationDelayed(android.view.View, java.lang.Runnable, long);
+ method public static void requestApplyInsets(android.view.View);
+ method public static int resolveSizeAndState(int, int, int);
+ method public static void setAccessibilityDelegate(android.view.View, android.support.v4.view.AccessibilityDelegateCompat);
+ method public static void setAccessibilityLiveRegion(android.view.View, int);
+ method public static void setActivated(android.view.View, boolean);
+ method public static void setAlpha(android.view.View, float);
+ method public static void setBackgroundTintList(android.view.View, android.content.res.ColorStateList);
+ method public static void setBackgroundTintMode(android.view.View, android.graphics.PorterDuff.Mode);
+ method public static void setChildrenDrawingOrderEnabled(android.view.ViewGroup, boolean);
+ method public static void setClipBounds(android.view.View, android.graphics.Rect);
+ method public static void setElevation(android.view.View, float);
+ method public static void setFitsSystemWindows(android.view.View, boolean);
+ method public static void setHasTransientState(android.view.View, boolean);
+ method public static void setImportantForAccessibility(android.view.View, int);
+ method public static void setLabelFor(android.view.View, int);
+ method public static void setLayerPaint(android.view.View, android.graphics.Paint);
+ method public static void setLayerType(android.view.View, int, android.graphics.Paint);
+ method public static void setLayoutDirection(android.view.View, int);
+ method public static void setNestedScrollingEnabled(android.view.View, boolean);
+ method public static void setOnApplyWindowInsetsListener(android.view.View, android.support.v4.view.OnApplyWindowInsetsListener);
+ method public static void setOverScrollMode(android.view.View, int);
+ method public static void setPaddingRelative(android.view.View, int, int, int, int);
+ method public static void setPivotX(android.view.View, float);
+ method public static void setPivotY(android.view.View, float);
+ method public static void setRotation(android.view.View, float);
+ method public static void setRotationX(android.view.View, float);
+ method public static void setRotationY(android.view.View, float);
+ method public static void setSaveFromParentEnabled(android.view.View, boolean);
+ method public static void setScaleX(android.view.View, float);
+ method public static void setScaleY(android.view.View, float);
+ method public static void setScrollIndicators(android.view.View, int);
+ method public static void setScrollIndicators(android.view.View, int, int);
+ method public static void setTransitionName(android.view.View, java.lang.String);
+ method public static void setTranslationX(android.view.View, float);
+ method public static void setTranslationY(android.view.View, float);
+ method public static void setTranslationZ(android.view.View, float);
+ method public static void setX(android.view.View, float);
+ method public static void setY(android.view.View, float);
+ method public static boolean startNestedScroll(android.view.View, int);
+ method public static void stopNestedScroll(android.view.View);
+ field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2
+ field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
+ field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
+ field public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0; // 0x0
+ field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 2; // 0x2
+ field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 4; // 0x4
+ field public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 1; // 0x1
+ field public static final int LAYER_TYPE_HARDWARE = 2; // 0x2
+ field public static final int LAYER_TYPE_NONE = 0; // 0x0
+ field public static final int LAYER_TYPE_SOFTWARE = 1; // 0x1
+ field public static final int LAYOUT_DIRECTION_INHERIT = 2; // 0x2
+ field public static final int LAYOUT_DIRECTION_LOCALE = 3; // 0x3
+ field public static final int LAYOUT_DIRECTION_LTR = 0; // 0x0
+ field public static final int LAYOUT_DIRECTION_RTL = 1; // 0x1
+ field public static final int MEASURED_HEIGHT_STATE_SHIFT = 16; // 0x10
+ field public static final int MEASURED_SIZE_MASK = 16777215; // 0xffffff
+ field public static final int MEASURED_STATE_MASK = -16777216; // 0xff000000
+ field public static final int MEASURED_STATE_TOO_SMALL = 16777216; // 0x1000000
+ field public static final int OVER_SCROLL_ALWAYS = 0; // 0x0
+ field public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; // 0x1
+ field public static final int OVER_SCROLL_NEVER = 2; // 0x2
+ field public static final int SCROLL_AXIS_HORIZONTAL = 1; // 0x1
+ field public static final int SCROLL_AXIS_NONE = 0; // 0x0
+ field public static final int SCROLL_AXIS_VERTICAL = 2; // 0x2
+ field public static final int SCROLL_INDICATOR_BOTTOM = 2; // 0x2
+ field public static final int SCROLL_INDICATOR_END = 32; // 0x20
+ field public static final int SCROLL_INDICATOR_LEFT = 4; // 0x4
+ field public static final int SCROLL_INDICATOR_RIGHT = 8; // 0x8
+ field public static final int SCROLL_INDICATOR_START = 16; // 0x10
+ field public static final int SCROLL_INDICATOR_TOP = 1; // 0x1
+ }
+
+ public class ViewConfigurationCompat {
+ ctor public ViewConfigurationCompat();
+ method public static int getScaledPagingTouchSlop(android.view.ViewConfiguration);
+ method public static boolean hasPermanentMenuKey(android.view.ViewConfiguration);
+ }
+
+ public class ViewGroupCompat {
+ method public static int getLayoutMode(android.view.ViewGroup);
+ method public static int getNestedScrollAxes(android.view.ViewGroup);
+ method public static boolean isTransitionGroup(android.view.ViewGroup);
+ method public static boolean onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent);
+ method public static void setLayoutMode(android.view.ViewGroup, int);
+ method public static void setMotionEventSplittingEnabled(android.view.ViewGroup, boolean);
+ method public static void setTransitionGroup(android.view.ViewGroup, boolean);
+ field public static final int LAYOUT_MODE_CLIP_BOUNDS = 0; // 0x0
+ field public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1; // 0x1
+ }
+
+ public class ViewPager extends android.view.ViewGroup {
+ ctor public ViewPager(android.content.Context);
+ ctor public ViewPager(android.content.Context, android.util.AttributeSet);
+ method public void addOnPageChangeListener(android.support.v4.view.ViewPager.OnPageChangeListener);
+ method public boolean arrowScroll(int);
+ method public boolean beginFakeDrag();
+ method protected boolean canScroll(android.view.View, boolean, int, int, int);
+ method public void clearOnPageChangeListeners();
+ method public void endFakeDrag();
+ method public boolean executeKeyEvent(android.view.KeyEvent);
+ method public void fakeDragBy(float);
+ method public android.support.v4.view.PagerAdapter getAdapter();
+ method public int getCurrentItem();
+ method public int getOffscreenPageLimit();
+ method public int getPageMargin();
+ method public boolean isFakeDragging();
+ method protected void onLayout(boolean, int, int, int, int);
+ method protected void onPageScrolled(int, float, int);
+ method public void onRestoreInstanceState(android.os.Parcelable);
+ method public android.os.Parcelable onSaveInstanceState();
+ method public void removeOnPageChangeListener(android.support.v4.view.ViewPager.OnPageChangeListener);
+ method public void setAdapter(android.support.v4.view.PagerAdapter);
+ method public void setCurrentItem(int);
+ method public void setCurrentItem(int, boolean);
+ method public void setOffscreenPageLimit(int);
+ method public deprecated void setOnPageChangeListener(android.support.v4.view.ViewPager.OnPageChangeListener);
+ method public void setPageMargin(int);
+ method public void setPageMarginDrawable(android.graphics.drawable.Drawable);
+ method public void setPageMarginDrawable(int);
+ method public void setPageTransformer(boolean, android.support.v4.view.ViewPager.PageTransformer);
+ field public static final int SCROLL_STATE_DRAGGING = 1; // 0x1
+ field public static final int SCROLL_STATE_IDLE = 0; // 0x0
+ field public static final int SCROLL_STATE_SETTLING = 2; // 0x2
+ }
+
+ public static class ViewPager.LayoutParams extends android.view.ViewGroup.LayoutParams {
+ ctor public ViewPager.LayoutParams();
+ ctor public ViewPager.LayoutParams(android.content.Context, android.util.AttributeSet);
+ field public int gravity;
+ field public boolean isDecor;
+ }
+
+ public static abstract interface ViewPager.OnPageChangeListener {
+ method public abstract void onPageScrollStateChanged(int);
+ method public abstract void onPageScrolled(int, float, int);
+ method public abstract void onPageSelected(int);
+ }
+
+ public static abstract interface ViewPager.PageTransformer {
+ method public abstract void transformPage(android.view.View, float);
+ }
+
+ public static class ViewPager.SavedState extends android.view.View.BaseSavedState {
+ ctor public ViewPager.SavedState(android.os.Parcelable);
+ field public static final android.os.Parcelable.Creator<android.support.v4.view.ViewPager.SavedState> CREATOR;
+ }
+
+ public static class ViewPager.SimpleOnPageChangeListener implements android.support.v4.view.ViewPager.OnPageChangeListener {
+ ctor public ViewPager.SimpleOnPageChangeListener();
+ method public void onPageScrollStateChanged(int);
+ method public void onPageScrolled(int, float, int);
+ method public void onPageSelected(int);
+ }
+
+ public class ViewParentCompat {
+ method public static void notifySubtreeAccessibilityStateChanged(android.view.ViewParent, android.view.View, android.view.View, int);
+ method public static boolean onNestedFling(android.view.ViewParent, android.view.View, float, float, boolean);
+ method public static boolean onNestedPreFling(android.view.ViewParent, android.view.View, float, float);
+ method public static void onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[]);
+ method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int);
+ method public static void onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int);
+ method public static boolean onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int);
+ method public static void onStopNestedScroll(android.view.ViewParent, android.view.View);
+ method public static boolean requestSendAccessibilityEvent(android.view.ViewParent, android.view.View, android.view.accessibility.AccessibilityEvent);
+ }
+
+ public class ViewPropertyAnimatorCompat {
+ method public android.support.v4.view.ViewPropertyAnimatorCompat alpha(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat alphaBy(float);
+ method public void cancel();
+ method public long getDuration();
+ method public android.view.animation.Interpolator getInterpolator();
+ method public long getStartDelay();
+ method public android.support.v4.view.ViewPropertyAnimatorCompat rotation(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat rotationBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat rotationX(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat rotationXBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat rotationY(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat rotationYBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat scaleX(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat scaleXBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat scaleY(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat scaleYBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat setDuration(long);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat setInterpolator(android.view.animation.Interpolator);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat setListener(android.support.v4.view.ViewPropertyAnimatorListener);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat setStartDelay(long);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat setUpdateListener(android.support.v4.view.ViewPropertyAnimatorUpdateListener);
+ method public void start();
+ method public android.support.v4.view.ViewPropertyAnimatorCompat translationX(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat translationXBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat translationY(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat translationYBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat translationZ(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat translationZBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat withEndAction(java.lang.Runnable);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat withLayer();
+ method public android.support.v4.view.ViewPropertyAnimatorCompat withStartAction(java.lang.Runnable);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat x(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat xBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat y(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat yBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat z(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat zBy(float);
+ }
+
+ public abstract interface ViewPropertyAnimatorListener {
+ method public abstract void onAnimationCancel(android.view.View);
+ method public abstract void onAnimationEnd(android.view.View);
+ method public abstract void onAnimationStart(android.view.View);
+ }
+
+ public class ViewPropertyAnimatorListenerAdapter implements android.support.v4.view.ViewPropertyAnimatorListener {
+ ctor public ViewPropertyAnimatorListenerAdapter();
+ method public void onAnimationCancel(android.view.View);
+ method public void onAnimationEnd(android.view.View);
+ method public void onAnimationStart(android.view.View);
+ }
+
+ public abstract interface ViewPropertyAnimatorUpdateListener {
+ method public abstract void onAnimationUpdate(android.view.View);
+ }
+
+ public class WindowCompat {
+ ctor public WindowCompat();
+ field public static final int FEATURE_ACTION_BAR = 8; // 0x8
+ field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
+ field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+ }
+
+ public class WindowInsetsCompat {
+ method public android.support.v4.view.WindowInsetsCompat consumeStableInsets();
+ method public android.support.v4.view.WindowInsetsCompat consumeSystemWindowInsets();
+ method public int getStableInsetBottom();
+ method public int getStableInsetLeft();
+ method public int getStableInsetRight();
+ method public int getStableInsetTop();
+ method public int getSystemWindowInsetBottom();
+ method public int getSystemWindowInsetLeft();
+ method public int getSystemWindowInsetRight();
+ method public int getSystemWindowInsetTop();
+ method public boolean hasInsets();
+ method public boolean hasStableInsets();
+ method public boolean hasSystemWindowInsets();
+ method public boolean isConsumed();
+ method public boolean isRound();
+ method public android.support.v4.view.WindowInsetsCompat replaceSystemWindowInsets(int, int, int, int);
+ method public android.support.v4.view.WindowInsetsCompat replaceSystemWindowInsets(android.graphics.Rect);
+ }
+
+}
+
+package android.support.v4.view.accessibility {
+
+ public class AccessibilityEventCompat {
+ method public static void appendRecord(android.view.accessibility.AccessibilityEvent, android.support.v4.view.accessibility.AccessibilityRecordCompat);
+ method public static android.support.v4.view.accessibility.AccessibilityRecordCompat asRecord(android.view.accessibility.AccessibilityEvent);
+ method public static int getContentChangeTypes(android.view.accessibility.AccessibilityEvent);
+ method public static android.support.v4.view.accessibility.AccessibilityRecordCompat getRecord(android.view.accessibility.AccessibilityEvent, int);
+ method public static int getRecordCount(android.view.accessibility.AccessibilityEvent);
+ method public static void setContentChangeTypes(android.view.accessibility.AccessibilityEvent, int);
+ field public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 4; // 0x4
+ field public static final int CONTENT_CHANGE_TYPE_SUBTREE = 1; // 0x1
+ field public static final int CONTENT_CHANGE_TYPE_TEXT = 2; // 0x2
+ field public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0; // 0x0
+ field public static final int TYPES_ALL_MASK = -1; // 0xffffffff
+ field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000
+ field public static final int TYPE_GESTURE_DETECTION_END = 524288; // 0x80000
+ field public static final int TYPE_GESTURE_DETECTION_START = 262144; // 0x40000
+ field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1024; // 0x400
+ field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 512; // 0x200
+ field public static final int TYPE_TOUCH_INTERACTION_END = 2097152; // 0x200000
+ field public static final int TYPE_TOUCH_INTERACTION_START = 1048576; // 0x100000
+ field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 32768; // 0x8000
+ field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 65536; // 0x10000
+ field public static final int TYPE_VIEW_HOVER_ENTER = 128; // 0x80
+ field public static final int TYPE_VIEW_HOVER_EXIT = 256; // 0x100
+ field public static final int TYPE_VIEW_SCROLLED = 4096; // 0x1000
+ field public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192; // 0x2000
+ field public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072; // 0x20000
+ field public static final int TYPE_WINDOW_CONTENT_CHANGED = 2048; // 0x800
+ }
+
+ public class AccessibilityManagerCompat {
+ ctor public AccessibilityManagerCompat();
+ method public static boolean addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager, android.support.v4.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat);
+ method public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getEnabledAccessibilityServiceList(android.view.accessibility.AccessibilityManager, int);
+ method public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getInstalledAccessibilityServiceList(android.view.accessibility.AccessibilityManager);
+ method public static boolean isTouchExplorationEnabled(android.view.accessibility.AccessibilityManager);
+ method public static boolean removeAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager, android.support.v4.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat);
+ }
+
+ public static abstract class AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat {
+ ctor public AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat();
+ method public abstract void onAccessibilityStateChanged(boolean);
+ }
+
+ public class AccessibilityNodeInfoCompat {
+ ctor public AccessibilityNodeInfoCompat(java.lang.Object);
+ method public void addAction(int);
+ method public void addAction(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat);
+ method public void addChild(android.view.View);
+ method public void addChild(android.view.View, int);
+ method public boolean canOpenPopup();
+ method public java.util.List<android.support.v4.view.accessibility.AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(java.lang.String);
+ method public java.util.List<android.support.v4.view.accessibility.AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByViewId(java.lang.String);
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat findFocus(int);
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat focusSearch(int);
+ method public java.util.List<android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat> getActionList();
+ method public int getActions();
+ method public void getBoundsInParent(android.graphics.Rect);
+ method public void getBoundsInScreen(android.graphics.Rect);
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getChild(int);
+ method public int getChildCount();
+ method public java.lang.CharSequence getClassName();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat getCollectionInfo();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat getCollectionItemInfo();
+ method public java.lang.CharSequence getContentDescription();
+ method public java.lang.CharSequence getError();
+ method public android.os.Bundle getExtras();
+ method public java.lang.Object getInfo();
+ method public int getInputType();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getLabelFor();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getLabeledBy();
+ method public int getLiveRegion();
+ method public int getMaxTextLength();
+ method public int getMovementGranularities();
+ method public java.lang.CharSequence getPackageName();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getParent();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat getRangeInfo();
+ method public java.lang.CharSequence getText();
+ method public int getTextSelectionEnd();
+ method public int getTextSelectionStart();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getTraversalAfter();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getTraversalBefore();
+ method public java.lang.String getViewIdResourceName();
+ method public android.support.v4.view.accessibility.AccessibilityWindowInfoCompat getWindow();
+ method public int getWindowId();
+ method public boolean isAccessibilityFocused();
+ method public boolean isCheckable();
+ method public boolean isChecked();
+ method public boolean isClickable();
+ method public boolean isContentInvalid();
+ method public boolean isDismissable();
+ method public boolean isEditable();
+ method public boolean isEnabled();
+ method public boolean isFocusable();
+ method public boolean isFocused();
+ method public boolean isLongClickable();
+ method public boolean isMultiLine();
+ method public boolean isPassword();
+ method public boolean isScrollable();
+ method public boolean isSelected();
+ method public boolean isVisibleToUser();
+ method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat obtain(android.view.View);
+ method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat obtain(android.view.View, int);
+ method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat obtain();
+ method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat obtain(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+ method public boolean performAction(int);
+ method public boolean performAction(int, android.os.Bundle);
+ method public void recycle();
+ method public boolean refresh();
+ method public boolean removeAction(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat);
+ method public boolean removeChild(android.view.View);
+ method public boolean removeChild(android.view.View, int);
+ method public void setAccessibilityFocused(boolean);
+ method public void setBoundsInParent(android.graphics.Rect);
+ method public void setBoundsInScreen(android.graphics.Rect);
+ method public void setCanOpenPopup(boolean);
+ method public void setCheckable(boolean);
+ method public void setChecked(boolean);
+ method public void setClassName(java.lang.CharSequence);
+ method public void setClickable(boolean);
+ method public void setCollectionInfo(java.lang.Object);
+ method public void setCollectionItemInfo(java.lang.Object);
+ method public void setContentDescription(java.lang.CharSequence);
+ method public void setContentInvalid(boolean);
+ method public void setDismissable(boolean);
+ method public void setEditable(boolean);
+ method public void setEnabled(boolean);
+ method public void setError(java.lang.CharSequence);
+ method public void setFocusable(boolean);
+ method public void setFocused(boolean);
+ method public void setInputType(int);
+ method public void setLabelFor(android.view.View);
+ method public void setLabelFor(android.view.View, int);
+ method public void setLabeledBy(android.view.View);
+ method public void setLabeledBy(android.view.View, int);
+ method public void setLiveRegion(int);
+ method public void setLongClickable(boolean);
+ method public void setMaxTextLength(int);
+ method public void setMovementGranularities(int);
+ method public void setMultiLine(boolean);
+ method public void setPackageName(java.lang.CharSequence);
+ method public void setParent(android.view.View);
+ method public void setParent(android.view.View, int);
+ method public void setPassword(boolean);
+ method public void setRangeInfo(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat);
+ method public void setScrollable(boolean);
+ method public void setSelected(boolean);
+ method public void setSource(android.view.View);
+ method public void setSource(android.view.View, int);
+ method public void setText(java.lang.CharSequence);
+ method public void setTextSelection(int, int);
+ method public void setTraversalAfter(android.view.View);
+ method public void setTraversalAfter(android.view.View, int);
+ method public void setTraversalBefore(android.view.View);
+ method public void setTraversalBefore(android.view.View, int);
+ method public void setViewIdResourceName(java.lang.String);
+ method public void setVisibleToUser(boolean);
+ field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
+ field public static final java.lang.String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
+ field public static final java.lang.String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
+ field public static final java.lang.String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
+ field public static final java.lang.String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
+ field public static final java.lang.String ACTION_ARGUMENT_SELECTION_START_INT = "ACTION_ARGUMENT_SELECTION_START_INT";
+ field public static final java.lang.String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE = "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
+ field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 128; // 0x80
+ field public static final int ACTION_CLEAR_FOCUS = 2; // 0x2
+ field public static final int ACTION_CLEAR_SELECTION = 8; // 0x8
+ field public static final int ACTION_CLICK = 16; // 0x10
+ field public static final int ACTION_COLLAPSE = 524288; // 0x80000
+ field public static final int ACTION_COPY = 16384; // 0x4000
+ field public static final int ACTION_CUT = 65536; // 0x10000
+ field public static final int ACTION_DISMISS = 1048576; // 0x100000
+ field public static final int ACTION_EXPAND = 262144; // 0x40000
+ field public static final int ACTION_FOCUS = 1; // 0x1
+ field public static final int ACTION_LONG_CLICK = 32; // 0x20
+ field public static final int ACTION_NEXT_AT_MOVEMENT_GRANULARITY = 256; // 0x100
+ field public static final int ACTION_NEXT_HTML_ELEMENT = 1024; // 0x400
+ field public static final int ACTION_PASTE = 32768; // 0x8000
+ field public static final int ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY = 512; // 0x200
+ field public static final int ACTION_PREVIOUS_HTML_ELEMENT = 2048; // 0x800
+ field public static final int ACTION_SCROLL_BACKWARD = 8192; // 0x2000
+ field public static final int ACTION_SCROLL_FORWARD = 4096; // 0x1000
+ field public static final int ACTION_SELECT = 4; // 0x4
+ field public static final int ACTION_SET_SELECTION = 131072; // 0x20000
+ field public static final int ACTION_SET_TEXT = 2097152; // 0x200000
+ field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2
+ field public static final int FOCUS_INPUT = 1; // 0x1
+ field public static final int MOVEMENT_GRANULARITY_CHARACTER = 1; // 0x1
+ field public static final int MOVEMENT_GRANULARITY_LINE = 4; // 0x4
+ field public static final int MOVEMENT_GRANULARITY_PAGE = 16; // 0x10
+ field public static final int MOVEMENT_GRANULARITY_PARAGRAPH = 8; // 0x8
+ field public static final int MOVEMENT_GRANULARITY_WORD = 2; // 0x2
+ }
+
+ public static class AccessibilityNodeInfoCompat.AccessibilityActionCompat {
+ ctor public AccessibilityNodeInfoCompat.AccessibilityActionCompat(int, java.lang.CharSequence);
+ method public int getId();
+ method public java.lang.CharSequence getLabel();
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_ACCESSIBILITY_FOCUS;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CLEAR_ACCESSIBILITY_FOCUS;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CLEAR_FOCUS;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CLEAR_SELECTION;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CLICK;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_COLLAPSE;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_COPY;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CUT;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DISMISS;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_EXPAND;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_FOCUS;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_LONG_CLICK;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_NEXT_HTML_ELEMENT;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PASTE;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PREVIOUS_HTML_ELEMENT;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_BACKWARD;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_FORWARD;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SELECT;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SET_SELECTION;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SET_TEXT;
+ }
+
+ public static class AccessibilityNodeInfoCompat.CollectionInfoCompat {
+ method public int getColumnCount();
+ method public int getRowCount();
+ method public boolean isHierarchical();
+ method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat obtain(int, int, boolean, int);
+ field public static final int SELECTION_MODE_MULTIPLE = 2; // 0x2
+ field public static final int SELECTION_MODE_NONE = 0; // 0x0
+ field public static final int SELECTION_MODE_SINGLE = 1; // 0x1
+ }
+
+ public static class AccessibilityNodeInfoCompat.CollectionItemInfoCompat {
+ method public int getColumnIndex();
+ method public int getColumnSpan();
+ method public int getRowIndex();
+ method public int getRowSpan();
+ method public boolean isHeading();
+ method public boolean isSelected();
+ method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat obtain(int, int, int, int, boolean, boolean);
+ }
+
+ public static class AccessibilityNodeInfoCompat.RangeInfoCompat {
+ method public float getCurrent();
+ method public float getMax();
+ method public float getMin();
+ method public int getType();
+ field public static final int RANGE_TYPE_FLOAT = 1; // 0x1
+ field public static final int RANGE_TYPE_INT = 0; // 0x0
+ field public static final int RANGE_TYPE_PERCENT = 2; // 0x2
+ }
+
+ public class AccessibilityNodeProviderCompat {
+ ctor public AccessibilityNodeProviderCompat();
+ ctor public AccessibilityNodeProviderCompat(java.lang.Object);
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int);
+ method public java.util.List<android.support.v4.view.accessibility.AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(java.lang.String, int);
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat findFocus(int);
+ method public java.lang.Object getProvider();
+ method public boolean performAction(int, int, android.os.Bundle);
+ }
+
+ public class AccessibilityRecordCompat {
+ ctor public deprecated AccessibilityRecordCompat(java.lang.Object);
+ method public int getAddedCount();
+ method public java.lang.CharSequence getBeforeText();
+ method public java.lang.CharSequence getClassName();
+ method public java.lang.CharSequence getContentDescription();
+ method public int getCurrentItemIndex();
+ method public int getFromIndex();
+ method public deprecated java.lang.Object getImpl();
+ method public int getItemCount();
+ method public int getMaxScrollX();
+ method public int getMaxScrollY();
+ method public android.os.Parcelable getParcelableData();
+ method public int getRemovedCount();
+ method public int getScrollX();
+ method public int getScrollY();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getSource();
+ method public java.util.List<java.lang.CharSequence> getText();
+ method public int getToIndex();
+ method public int getWindowId();
+ method public boolean isChecked();
+ method public boolean isEnabled();
+ method public boolean isFullScreen();
+ method public boolean isPassword();
+ method public boolean isScrollable();
+ method public static android.support.v4.view.accessibility.AccessibilityRecordCompat obtain(android.support.v4.view.accessibility.AccessibilityRecordCompat);
+ method public static android.support.v4.view.accessibility.AccessibilityRecordCompat obtain();
+ method public void recycle();
+ method public void setAddedCount(int);
+ method public void setBeforeText(java.lang.CharSequence);
+ method public void setChecked(boolean);
+ method public void setClassName(java.lang.CharSequence);
+ method public void setContentDescription(java.lang.CharSequence);
+ method public void setCurrentItemIndex(int);
+ method public void setEnabled(boolean);
+ method public void setFromIndex(int);
+ method public void setFullScreen(boolean);
+ method public void setItemCount(int);
+ method public void setMaxScrollX(int);
+ method public void setMaxScrollY(int);
+ method public void setParcelableData(android.os.Parcelable);
+ method public void setPassword(boolean);
+ method public void setRemovedCount(int);
+ method public void setScrollX(int);
+ method public void setScrollY(int);
+ method public void setScrollable(boolean);
+ method public void setSource(android.view.View);
+ method public void setSource(android.view.View, int);
+ method public void setToIndex(int);
+ }
+
+ public class AccessibilityWindowInfoCompat {
+ method public void getBoundsInScreen(android.graphics.Rect);
+ method public android.support.v4.view.accessibility.AccessibilityWindowInfoCompat getChild(int);
+ method public int getChildCount();
+ method public int getId();
+ method public int getLayer();
+ method public android.support.v4.view.accessibility.AccessibilityWindowInfoCompat getParent();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getRoot();
+ method public int getType();
+ method public boolean isAccessibilityFocused();
+ method public boolean isActive();
+ method public boolean isFocused();
+ method public static android.support.v4.view.accessibility.AccessibilityWindowInfoCompat obtain();
+ method public static android.support.v4.view.accessibility.AccessibilityWindowInfoCompat obtain(android.support.v4.view.accessibility.AccessibilityWindowInfoCompat);
+ method public void recycle();
+ field public static final int TYPE_ACCESSIBILITY_OVERLAY = 4; // 0x4
+ field public static final int TYPE_APPLICATION = 1; // 0x1
+ field public static final int TYPE_INPUT_METHOD = 2; // 0x2
+ field public static final int TYPE_SYSTEM = 3; // 0x3
+ }
+
+}
+
+package android.support.v4.view.animation {
+
+ public class FastOutLinearInInterpolator extends android.support.v4.view.animation.LookupTableInterpolator {
+ ctor public FastOutLinearInInterpolator();
+ }
+
+ public class FastOutSlowInInterpolator extends android.support.v4.view.animation.LookupTableInterpolator {
+ ctor public FastOutSlowInInterpolator();
+ }
+
+ public class LinearOutSlowInInterpolator extends android.support.v4.view.animation.LookupTableInterpolator {
+ ctor public LinearOutSlowInInterpolator();
+ }
+
+ abstract class LookupTableInterpolator implements android.view.animation.Interpolator {
+ ctor public LookupTableInterpolator(float[]);
+ method public float getInterpolation(float);
+ }
+
+ public class PathInterpolatorCompat {
+ method public static android.view.animation.Interpolator create(android.graphics.Path);
+ method public static android.view.animation.Interpolator create(float, float);
+ method public static android.view.animation.Interpolator create(float, float, float, float);
+ }
+
+}
+
+package android.support.v4.widget {
+
+ public abstract class AutoScrollHelper implements android.view.View.OnTouchListener {
+ ctor public AutoScrollHelper(android.view.View);
+ method public abstract boolean canTargetScrollHorizontally(int);
+ method public abstract boolean canTargetScrollVertically(int);
+ method public boolean isEnabled();
+ method public boolean isExclusive();
+ method public boolean onTouch(android.view.View, android.view.MotionEvent);
+ method public abstract void scrollTargetBy(int, int);
+ method public android.support.v4.widget.AutoScrollHelper setActivationDelay(int);
+ method public android.support.v4.widget.AutoScrollHelper setEdgeType(int);
+ method public android.support.v4.widget.AutoScrollHelper setEnabled(boolean);
+ method public android.support.v4.widget.AutoScrollHelper setExclusive(boolean);
+ method public android.support.v4.widget.AutoScrollHelper setMaximumEdges(float, float);
+ method public android.support.v4.widget.AutoScrollHelper setMaximumVelocity(float, float);
+ method public android.support.v4.widget.AutoScrollHelper setMinimumVelocity(float, float);
+ method public android.support.v4.widget.AutoScrollHelper setRampDownDuration(int);
+ method public android.support.v4.widget.AutoScrollHelper setRampUpDuration(int);
+ method public android.support.v4.widget.AutoScrollHelper setRelativeEdges(float, float);
+ method public android.support.v4.widget.AutoScrollHelper setRelativeVelocity(float, float);
+ field public static final int EDGE_TYPE_INSIDE = 0; // 0x0
+ field public static final int EDGE_TYPE_INSIDE_EXTEND = 1; // 0x1
+ field public static final int EDGE_TYPE_OUTSIDE = 2; // 0x2
+ field public static final float NO_MAX = 3.4028235E38f;
+ field public static final float NO_MIN = 0.0f;
+ field public static final float RELATIVE_UNSPECIFIED = 0.0f;
+ }
+
+ public final class CompoundButtonCompat {
+ method public static android.graphics.drawable.Drawable getButtonDrawable(android.widget.CompoundButton);
+ method public static android.content.res.ColorStateList getButtonTintList(android.widget.CompoundButton);
+ method public static android.graphics.PorterDuff.Mode getButtonTintMode(android.widget.CompoundButton);
+ method public static void setButtonTintList(android.widget.CompoundButton, android.content.res.ColorStateList);
+ method public static void setButtonTintMode(android.widget.CompoundButton, android.graphics.PorterDuff.Mode);
+ }
+
+ public class ContentLoadingProgressBar extends android.widget.ProgressBar {
+ ctor public ContentLoadingProgressBar(android.content.Context);
+ ctor public ContentLoadingProgressBar(android.content.Context, android.util.AttributeSet);
+ method public void hide();
+ method public void onAttachedToWindow();
+ method public void onDetachedFromWindow();
+ method public void show();
+ }
+
+ public abstract class CursorAdapter extends android.widget.BaseAdapter {
+ ctor public deprecated CursorAdapter(android.content.Context, android.database.Cursor);
+ ctor public CursorAdapter(android.content.Context, android.database.Cursor, boolean);
+ ctor public CursorAdapter(android.content.Context, android.database.Cursor, int);
+ method public abstract void bindView(android.view.View, android.content.Context, android.database.Cursor);
+ method public void changeCursor(android.database.Cursor);
+ method public java.lang.CharSequence convertToString(android.database.Cursor);
+ method public int getCount();
+ method public android.database.Cursor getCursor();
+ method public android.widget.Filter getFilter();
+ method public android.widget.FilterQueryProvider getFilterQueryProvider();
+ method public java.lang.Object getItem(int);
+ method public long getItemId(int);
+ method public android.view.View getView(int, android.view.View, android.view.ViewGroup);
+ method protected deprecated void init(android.content.Context, android.database.Cursor, boolean);
+ method public android.view.View newDropDownView(android.content.Context, android.database.Cursor, android.view.ViewGroup);
+ method public abstract android.view.View newView(android.content.Context, android.database.Cursor, android.view.ViewGroup);
+ method protected void onContentChanged();
+ method public android.database.Cursor runQueryOnBackgroundThread(java.lang.CharSequence);
+ method public void setFilterQueryProvider(android.widget.FilterQueryProvider);
+ method public android.database.Cursor swapCursor(android.database.Cursor);
+ field public static final deprecated int FLAG_AUTO_REQUERY = 1; // 0x1
+ field public static final int FLAG_REGISTER_CONTENT_OBSERVER = 2; // 0x2
+ }
+
+ public class DrawerLayout extends android.view.ViewGroup {
+ ctor public DrawerLayout(android.content.Context);
+ ctor public DrawerLayout(android.content.Context, android.util.AttributeSet);
+ ctor public DrawerLayout(android.content.Context, android.util.AttributeSet, int);
+ method public void closeDrawer(android.view.View);
+ method public void closeDrawer(int);
+ method public void closeDrawers();
+ method public float getDrawerElevation();
+ method public int getDrawerLockMode(int);
+ method public int getDrawerLockMode(android.view.View);
+ method public java.lang.CharSequence getDrawerTitle(int);
+ method public android.graphics.drawable.Drawable getStatusBarBackgroundDrawable();
+ method public boolean isDrawerOpen(android.view.View);
+ method public boolean isDrawerOpen(int);
+ method public boolean isDrawerVisible(android.view.View);
+ method public boolean isDrawerVisible(int);
+ method public void onDraw(android.graphics.Canvas);
+ method protected void onLayout(boolean, int, int, int, int);
+ method public void openDrawer(android.view.View);
+ method public void openDrawer(int);
+ method public void setDrawerElevation(float);
+ method public void setDrawerListener(android.support.v4.widget.DrawerLayout.DrawerListener);
+ method public void setDrawerLockMode(int);
+ method public void setDrawerLockMode(int, int);
+ method public void setDrawerLockMode(int, android.view.View);
+ method public void setDrawerShadow(android.graphics.drawable.Drawable, int);
+ method public void setDrawerShadow(int, int);
+ method public void setDrawerTitle(int, java.lang.CharSequence);
+ method public void setScrimColor(int);
+ method public void setStatusBarBackground(android.graphics.drawable.Drawable);
+ method public void setStatusBarBackground(int);
+ method public void setStatusBarBackgroundColor(int);
+ field public static final int LOCK_MODE_LOCKED_CLOSED = 1; // 0x1
+ field public static final int LOCK_MODE_LOCKED_OPEN = 2; // 0x2
+ field public static final int LOCK_MODE_UNLOCKED = 0; // 0x0
+ field public static final int STATE_DRAGGING = 1; // 0x1
+ field public static final int STATE_IDLE = 0; // 0x0
+ field public static final int STATE_SETTLING = 2; // 0x2
+ }
+
+ public static abstract interface DrawerLayout.DrawerListener {
+ method public abstract void onDrawerClosed(android.view.View);
+ method public abstract void onDrawerOpened(android.view.View);
+ method public abstract void onDrawerSlide(android.view.View, float);
+ method public abstract void onDrawerStateChanged(int);
+ }
+
+ public static class DrawerLayout.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+ ctor public DrawerLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+ ctor public DrawerLayout.LayoutParams(int, int);
+ ctor public DrawerLayout.LayoutParams(int, int, int);
+ ctor public DrawerLayout.LayoutParams(android.support.v4.widget.DrawerLayout.LayoutParams);
+ ctor public DrawerLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+ ctor public DrawerLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ field public int gravity;
+ }
+
+ protected static class DrawerLayout.SavedState extends android.view.View.BaseSavedState {
+ ctor public DrawerLayout.SavedState(android.os.Parcel);
+ ctor public DrawerLayout.SavedState(android.os.Parcelable);
+ field public static final android.os.Parcelable.Creator<android.support.v4.widget.DrawerLayout.SavedState> CREATOR;
+ }
+
+ public static abstract class DrawerLayout.SimpleDrawerListener implements android.support.v4.widget.DrawerLayout.DrawerListener {
+ ctor public DrawerLayout.SimpleDrawerListener();
+ method public void onDrawerClosed(android.view.View);
+ method public void onDrawerOpened(android.view.View);
+ method public void onDrawerSlide(android.view.View, float);
+ method public void onDrawerStateChanged(int);
+ }
+
+ public class EdgeEffectCompat {
+ ctor public EdgeEffectCompat(android.content.Context);
+ method public boolean draw(android.graphics.Canvas);
+ method public void finish();
+ method public boolean isFinished();
+ method public boolean onAbsorb(int);
+ method public deprecated boolean onPull(float);
+ method public boolean onPull(float, float);
+ method public boolean onRelease();
+ method public void setSize(int, int);
+ }
+
+ public abstract class ExploreByTouchHelper extends android.support.v4.view.AccessibilityDelegateCompat {
+ ctor public ExploreByTouchHelper(android.view.View);
+ method public boolean dispatchHoverEvent(android.view.MotionEvent);
+ method public int getFocusedVirtualView();
+ method protected abstract int getVirtualViewAt(float, float);
+ method protected abstract void getVisibleVirtualViews(java.util.List<java.lang.Integer>);
+ method public void invalidateRoot();
+ method public void invalidateVirtualView(int);
+ method protected abstract boolean onPerformActionForVirtualView(int, int, android.os.Bundle);
+ method protected abstract void onPopulateEventForVirtualView(int, android.view.accessibility.AccessibilityEvent);
+ method public void onPopulateNodeForHost(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+ method protected abstract void onPopulateNodeForVirtualView(int, android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+ method public boolean sendEventForVirtualView(int, int);
+ field public static final int HOST_ID = -1; // 0xffffffff
+ field public static final int INVALID_ID = -2147483648; // 0x80000000
+ }
+
+ public class ListPopupWindowCompat {
+ method public static android.view.View.OnTouchListener createDragToOpenListener(java.lang.Object, android.view.View);
+ }
+
+ public class ListViewAutoScrollHelper extends android.support.v4.widget.AutoScrollHelper {
+ ctor public ListViewAutoScrollHelper(android.widget.ListView);
+ method public boolean canTargetScrollHorizontally(int);
+ method public boolean canTargetScrollVertically(int);
+ method public void scrollTargetBy(int, int);
+ }
+
+ public class NestedScrollView extends android.widget.FrameLayout implements android.support.v4.view.NestedScrollingChild android.support.v4.view.NestedScrollingParent android.support.v4.view.ScrollingView {
+ ctor public NestedScrollView(android.content.Context);
+ ctor public NestedScrollView(android.content.Context, android.util.AttributeSet);
+ ctor public NestedScrollView(android.content.Context, android.util.AttributeSet, int);
+ method public boolean arrowScroll(int);
+ method protected int computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect);
+ method public boolean executeKeyEvent(android.view.KeyEvent);
+ method public void fling(int);
+ method public boolean fullScroll(int);
+ method public int getMaxScrollAmount();
+ method public boolean isFillViewport();
+ method public boolean isSmoothScrollingEnabled();
+ method public void onAttachedToWindow();
+ method public boolean pageScroll(int);
+ method public void setFillViewport(boolean);
+ method public void setOnScrollChangeListener(android.support.v4.widget.NestedScrollView.OnScrollChangeListener);
+ method public void setSmoothScrollingEnabled(boolean);
+ method public final void smoothScrollBy(int, int);
+ method public final void smoothScrollTo(int, int);
+ }
+
+ public static abstract interface NestedScrollView.OnScrollChangeListener {
+ method public abstract void onScrollChange(android.support.v4.widget.NestedScrollView, int, int, int, int);
+ }
+
+ public class PopupMenuCompat {
+ method public static android.view.View.OnTouchListener getDragToOpenListener(java.lang.Object);
+ }
+
+ public class PopupWindowCompat {
+ method public static boolean getOverlapAnchor(android.widget.PopupWindow);
+ method public static int getWindowLayoutType(android.widget.PopupWindow);
+ method public static void setOverlapAnchor(android.widget.PopupWindow, boolean);
+ method public static void setWindowLayoutType(android.widget.PopupWindow, int);
+ method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
+ }
+
+ public abstract class ResourceCursorAdapter extends android.support.v4.widget.CursorAdapter {
+ ctor public deprecated ResourceCursorAdapter(android.content.Context, int, android.database.Cursor);
+ ctor public ResourceCursorAdapter(android.content.Context, int, android.database.Cursor, boolean);
+ ctor public ResourceCursorAdapter(android.content.Context, int, android.database.Cursor, int);
+ method public android.view.View newView(android.content.Context, android.database.Cursor, android.view.ViewGroup);
+ method public void setDropDownViewResource(int);
+ method public void setViewResource(int);
+ }
+
+ public class ScrollerCompat {
+ method public void abortAnimation();
+ method public boolean computeScrollOffset();
+ method public static android.support.v4.widget.ScrollerCompat create(android.content.Context);
+ method public static android.support.v4.widget.ScrollerCompat create(android.content.Context, android.view.animation.Interpolator);
+ method public void fling(int, int, int, int, int, int, int, int);
+ method public void fling(int, int, int, int, int, int, int, int, int, int);
+ method public float getCurrVelocity();
+ method public int getCurrX();
+ method public int getCurrY();
+ method public int getFinalX();
+ method public int getFinalY();
+ method public boolean isFinished();
+ method public boolean isOverScrolled();
+ method public void notifyHorizontalEdgeReached(int, int, int);
+ method public void notifyVerticalEdgeReached(int, int, int);
+ method public boolean springBack(int, int, int, int, int, int);
+ method public void startScroll(int, int, int, int);
+ method public void startScroll(int, int, int, int, int);
+ }
+
+ public class SearchViewCompat {
+ method public static java.lang.CharSequence getQuery(android.view.View);
+ method public static boolean isIconified(android.view.View);
+ method public static boolean isQueryRefinementEnabled(android.view.View);
+ method public static boolean isSubmitButtonEnabled(android.view.View);
+ method public static android.view.View newSearchView(android.content.Context);
+ method public static void setIconified(android.view.View, boolean);
+ method public static void setImeOptions(android.view.View, int);
+ method public static void setInputType(android.view.View, int);
+ method public static void setMaxWidth(android.view.View, int);
+ method public static void setOnCloseListener(android.view.View, android.support.v4.widget.SearchViewCompat.OnCloseListenerCompat);
+ method public static void setOnQueryTextListener(android.view.View, android.support.v4.widget.SearchViewCompat.OnQueryTextListenerCompat);
+ method public static void setQuery(android.view.View, java.lang.CharSequence, boolean);
+ method public static void setQueryHint(android.view.View, java.lang.CharSequence);
+ method public static void setQueryRefinementEnabled(android.view.View, boolean);
+ method public static void setSearchableInfo(android.view.View, android.content.ComponentName);
+ method public static void setSubmitButtonEnabled(android.view.View, boolean);
+ }
+
+ public static abstract class SearchViewCompat.OnCloseListenerCompat {
+ ctor public SearchViewCompat.OnCloseListenerCompat();
+ method public boolean onClose();
+ }
+
+ public static abstract class SearchViewCompat.OnQueryTextListenerCompat {
+ ctor public SearchViewCompat.OnQueryTextListenerCompat();
+ method public boolean onQueryTextChange(java.lang.String);
+ method public boolean onQueryTextSubmit(java.lang.String);
+ }
+
+ public class SimpleCursorAdapter extends android.support.v4.widget.ResourceCursorAdapter {
+ ctor public deprecated SimpleCursorAdapter(android.content.Context, int, android.database.Cursor, java.lang.String[], int[]);
+ ctor public SimpleCursorAdapter(android.content.Context, int, android.database.Cursor, java.lang.String[], int[], int);
+ method public void bindView(android.view.View, android.content.Context, android.database.Cursor);
+ method public void changeCursorAndColumns(android.database.Cursor, java.lang.String[], int[]);
+ method public android.support.v4.widget.SimpleCursorAdapter.CursorToStringConverter getCursorToStringConverter();
+ method public int getStringConversionColumn();
+ method public android.support.v4.widget.SimpleCursorAdapter.ViewBinder getViewBinder();
+ method public void setCursorToStringConverter(android.support.v4.widget.SimpleCursorAdapter.CursorToStringConverter);
+ method public void setStringConversionColumn(int);
+ method public void setViewBinder(android.support.v4.widget.SimpleCursorAdapter.ViewBinder);
+ method public void setViewImage(android.widget.ImageView, java.lang.String);
+ method public void setViewText(android.widget.TextView, java.lang.String);
+ }
+
+ public static abstract interface SimpleCursorAdapter.CursorToStringConverter {
+ method public abstract java.lang.CharSequence convertToString(android.database.Cursor);
+ }
+
+ public static abstract interface SimpleCursorAdapter.ViewBinder {
+ method public abstract boolean setViewValue(android.view.View, android.database.Cursor, int);
+ }
+
+ public class SlidingPaneLayout extends android.view.ViewGroup {
+ ctor public SlidingPaneLayout(android.content.Context);
+ ctor public SlidingPaneLayout(android.content.Context, android.util.AttributeSet);
+ ctor public SlidingPaneLayout(android.content.Context, android.util.AttributeSet, int);
+ method protected boolean canScroll(android.view.View, boolean, int, int, int);
+ method public deprecated boolean canSlide();
+ method public boolean closePane();
+ method public int getCoveredFadeColor();
+ method public int getParallaxDistance();
+ method public int getSliderFadeColor();
+ method public boolean isOpen();
+ method public boolean isSlideable();
+ method protected void onLayout(boolean, int, int, int, int);
+ method public boolean openPane();
+ method public void setCoveredFadeColor(int);
+ method public void setPanelSlideListener(android.support.v4.widget.SlidingPaneLayout.PanelSlideListener);
+ method public void setParallaxDistance(int);
+ method public deprecated void setShadowDrawable(android.graphics.drawable.Drawable);
+ method public void setShadowDrawableLeft(android.graphics.drawable.Drawable);
+ method public void setShadowDrawableRight(android.graphics.drawable.Drawable);
+ method public deprecated void setShadowResource(int);
+ method public void setShadowResourceLeft(int);
+ method public void setShadowResourceRight(int);
+ method public void setSliderFadeColor(int);
+ method public deprecated void smoothSlideClosed();
+ method public deprecated void smoothSlideOpen();
+ }
+
+ public static class SlidingPaneLayout.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+ ctor public SlidingPaneLayout.LayoutParams();
+ ctor public SlidingPaneLayout.LayoutParams(int, int);
+ ctor public SlidingPaneLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+ ctor public SlidingPaneLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ ctor public SlidingPaneLayout.LayoutParams(android.support.v4.widget.SlidingPaneLayout.LayoutParams);
+ ctor public SlidingPaneLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+ field public float weight;
+ }
+
+ public static abstract interface SlidingPaneLayout.PanelSlideListener {
+ method public abstract void onPanelClosed(android.view.View);
+ method public abstract void onPanelOpened(android.view.View);
+ method public abstract void onPanelSlide(android.view.View, float);
+ }
+
+ public static class SlidingPaneLayout.SimplePanelSlideListener implements android.support.v4.widget.SlidingPaneLayout.PanelSlideListener {
+ ctor public SlidingPaneLayout.SimplePanelSlideListener();
+ method public void onPanelClosed(android.view.View);
+ method public void onPanelOpened(android.view.View);
+ method public void onPanelSlide(android.view.View, float);
+ }
+
+ public class Space extends android.view.View {
+ ctor public Space(android.content.Context, android.util.AttributeSet, int);
+ ctor public Space(android.content.Context, android.util.AttributeSet);
+ ctor public Space(android.content.Context);
+ }
+
+ public class SwipeRefreshLayout extends android.view.ViewGroup implements android.support.v4.view.NestedScrollingChild android.support.v4.view.NestedScrollingParent {
+ ctor public SwipeRefreshLayout(android.content.Context);
+ ctor public SwipeRefreshLayout(android.content.Context, android.util.AttributeSet);
+ method public boolean canChildScrollUp();
+ method public int getProgressCircleDiameter();
+ method public boolean isRefreshing();
+ method protected void onLayout(boolean, int, int, int, int);
+ method public void onMeasure(int, int);
+ method public deprecated void setColorScheme(int...);
+ method public void setColorSchemeColors(int...);
+ method public void setColorSchemeResources(int...);
+ method public void setDistanceToTriggerSync(int);
+ method public void setOnRefreshListener(android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener);
+ method public deprecated void setProgressBackgroundColor(int);
+ method public void setProgressBackgroundColorSchemeColor(int);
+ method public void setProgressBackgroundColorSchemeResource(int);
+ method public void setProgressViewEndTarget(boolean, int);
+ method public void setProgressViewOffset(boolean, int, int);
+ method public void setRefreshing(boolean);
+ method public void setSize(int);
+ field public static final int DEFAULT = 1; // 0x1
+ field public static final int LARGE = 0; // 0x0
+ field protected int mFrom;
+ field protected int mOriginalOffsetTop;
+ }
+
+ public static abstract interface SwipeRefreshLayout.OnRefreshListener {
+ method public abstract void onRefresh();
+ }
+
+ public class TextViewCompat {
+ method public static int getMaxLines(android.widget.TextView);
+ method public static int getMinLines(android.widget.TextView);
+ method public static void setCompoundDrawablesRelative(android.widget.TextView, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
+ method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
+ method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, int, int, int, int);
+ }
+
+ public class ViewDragHelper {
+ method public void abort();
+ method protected boolean canScroll(android.view.View, boolean, int, int, int, int);
+ method public void cancel();
+ method public void captureChildView(android.view.View, int);
+ method public boolean checkTouchSlop(int);
+ method public boolean checkTouchSlop(int, int);
+ method public boolean continueSettling(boolean);
+ method public static android.support.v4.widget.ViewDragHelper create(android.view.ViewGroup, android.support.v4.widget.ViewDragHelper.Callback);
+ method public static android.support.v4.widget.ViewDragHelper create(android.view.ViewGroup, float, android.support.v4.widget.ViewDragHelper.Callback);
+ method public android.view.View findTopChildUnder(int, int);
+ method public void flingCapturedView(int, int, int, int);
+ method public int getActivePointerId();
+ method public android.view.View getCapturedView();
+ method public int getEdgeSize();
+ method public float getMinVelocity();
+ method public int getTouchSlop();
+ method public int getViewDragState();
+ method public boolean isCapturedViewUnder(int, int);
+ method public boolean isEdgeTouched(int);
+ method public boolean isEdgeTouched(int, int);
+ method public boolean isPointerDown(int);
+ method public boolean isViewUnder(android.view.View, int, int);
+ method public void processTouchEvent(android.view.MotionEvent);
+ method public void setEdgeTrackingEnabled(int);
+ method public void setMinVelocity(float);
+ method public boolean settleCapturedViewAt(int, int);
+ method public boolean shouldInterceptTouchEvent(android.view.MotionEvent);
+ method public boolean smoothSlideViewTo(android.view.View, int, int);
+ field public static final int DIRECTION_ALL = 3; // 0x3
+ field public static final int DIRECTION_HORIZONTAL = 1; // 0x1
+ field public static final int DIRECTION_VERTICAL = 2; // 0x2
+ field public static final int EDGE_ALL = 15; // 0xf
+ field public static final int EDGE_BOTTOM = 8; // 0x8
+ field public static final int EDGE_LEFT = 1; // 0x1
+ field public static final int EDGE_RIGHT = 2; // 0x2
+ field public static final int EDGE_TOP = 4; // 0x4
+ field public static final int INVALID_POINTER = -1; // 0xffffffff
+ field public static final int STATE_DRAGGING = 1; // 0x1
+ field public static final int STATE_IDLE = 0; // 0x0
+ field public static final int STATE_SETTLING = 2; // 0x2
+ }
+
+ public static abstract class ViewDragHelper.Callback {
+ ctor public ViewDragHelper.Callback();
+ method public int clampViewPositionHorizontal(android.view.View, int, int);
+ method public int clampViewPositionVertical(android.view.View, int, int);
+ method public int getOrderedChildIndex(int);
+ method public int getViewHorizontalDragRange(android.view.View);
+ method public int getViewVerticalDragRange(android.view.View);
+ method public void onEdgeDragStarted(int, int);
+ method public boolean onEdgeLock(int);
+ method public void onEdgeTouched(int, int);
+ method public void onViewCaptured(android.view.View, int);
+ method public void onViewDragStateChanged(int);
+ method public void onViewPositionChanged(android.view.View, int, int, int, int);
+ method public void onViewReleased(android.view.View, float, float);
+ method public abstract boolean tryCaptureView(android.view.View, int);
+ }
+
+}
+
diff --git a/v4/api/current.txt b/v4/api/current.txt
index 3c4290e6a5..9f50a24886 100644
--- a/v4/api/current.txt
+++ b/v4/api/current.txt
@@ -26,36 +26,6 @@ package android.support.v4.accessibilityservice {
}
-package android.support.v4.animation {
-
- public abstract class AnimatorCompatHelper {
- method public static void clearInterpolator(android.view.View);
- method public static android.support.v4.animation.ValueAnimatorCompat emptyValueAnimator();
- }
-
- public abstract interface AnimatorListenerCompat {
- method public abstract void onAnimationCancel(android.support.v4.animation.ValueAnimatorCompat);
- method public abstract void onAnimationEnd(android.support.v4.animation.ValueAnimatorCompat);
- method public abstract void onAnimationRepeat(android.support.v4.animation.ValueAnimatorCompat);
- method public abstract void onAnimationStart(android.support.v4.animation.ValueAnimatorCompat);
- }
-
- public abstract interface AnimatorUpdateListenerCompat {
- method public abstract void onAnimationUpdate(android.support.v4.animation.ValueAnimatorCompat);
- }
-
- public abstract interface ValueAnimatorCompat {
- method public abstract void addListener(android.support.v4.animation.AnimatorListenerCompat);
- method public abstract void addUpdateListener(android.support.v4.animation.AnimatorUpdateListenerCompat);
- method public abstract void cancel();
- method public abstract float getAnimatedFraction();
- method public abstract void setDuration(long);
- method public abstract void setTarget(android.view.View);
- method public abstract void start();
- }
-
-}
-
package android.support.v4.app {
public deprecated class ActionBarDrawerToggle implements android.support.v4.widget.DrawerLayout.DrawerListener {
@@ -274,12 +244,14 @@ package android.support.v4.app {
method public java.lang.Object getLastCustomNonConfigurationInstance();
method public android.support.v4.app.FragmentManager getSupportFragmentManager();
method public android.support.v4.app.LoaderManager getSupportLoaderManager();
+ method public final android.support.v4.media.session.MediaControllerCompat getSupportMediaController();
method public void onAttachFragment(android.support.v4.app.Fragment);
method protected void onResumeFragments();
method public java.lang.Object onRetainCustomNonConfigurationInstance();
method public final java.lang.Object onRetainNonConfigurationInstance();
method public void setEnterSharedElementCallback(android.support.v4.app.SharedElementCallback);
method public void setExitSharedElementCallback(android.support.v4.app.SharedElementCallback);
+ method public final void setSupportMediaController(android.support.v4.media.session.MediaControllerCompat);
method public void startActivityFromFragment(android.support.v4.app.Fragment, android.content.Intent, int);
method public void supportFinishAfterTransition();
method public void supportInvalidateOptionsMenu();
@@ -560,7 +532,7 @@ package android.support.v4.app {
field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
}
- public static class NotificationCompat.Action extends android.support.v4.app.NotificationCompatBase.Action {
+ public static class NotificationCompat.Action {
ctor public NotificationCompat.Action(int, java.lang.CharSequence, android.app.PendingIntent);
method public android.app.PendingIntent getActionIntent();
method public android.os.Bundle getExtras();
@@ -681,7 +653,7 @@ package android.support.v4.app {
method public android.support.v4.app.NotificationCompat.CarExtender setUnreadConversation(android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation);
}
- public static class NotificationCompat.CarExtender.UnreadConversation extends android.support.v4.app.NotificationCompatBase.UnreadConversation {
+ public static class NotificationCompat.CarExtender.UnreadConversation {
method public long getLatestTimestamp();
method public java.lang.String[] getMessages();
method public java.lang.String getParticipant();
@@ -770,23 +742,6 @@ package android.support.v4.app {
field public static final int UNSET_ACTION_INDEX = -1; // 0xffffffff
}
- public class NotificationCompatBase {
- ctor public NotificationCompatBase();
- }
-
- public static abstract class NotificationCompatBase.Action {
- ctor public NotificationCompatBase.Action();
- method public abstract android.app.PendingIntent getActionIntent();
- method public abstract android.os.Bundle getExtras();
- method public abstract int getIcon();
- method public abstract android.support.v4.app.RemoteInputCompatBase.RemoteInput[] getRemoteInputs();
- method public abstract java.lang.CharSequence getTitle();
- }
-
- public static abstract class NotificationCompatBase.UnreadConversation {
- ctor public NotificationCompatBase.UnreadConversation();
- }
-
public final class NotificationCompatExtras {
field public static final java.lang.String EXTRA_ACTION_EXTRAS = "android.support.actionExtras";
field public static final java.lang.String EXTRA_GROUP_KEY = "android.support.groupKey";
@@ -964,13 +919,13 @@ package android.support.v4.content {
public class ContextCompat {
ctor public ContextCompat();
method public static int checkSelfPermission(android.content.Context, java.lang.String);
- method public final java.io.File getCodeCacheDir(android.content.Context);
+ method public static java.io.File getCodeCacheDir(android.content.Context);
method public static final int getColor(android.content.Context, int);
method public static final android.content.res.ColorStateList getColorStateList(android.content.Context, int);
method public static final android.graphics.drawable.Drawable getDrawable(android.content.Context, int);
method public static java.io.File[] getExternalCacheDirs(android.content.Context);
method public static java.io.File[] getExternalFilesDirs(android.content.Context, java.lang.String);
- method public final java.io.File getNoBackupFilesDir(android.content.Context);
+ method public static java.io.File getNoBackupFilesDir(android.content.Context);
method public static java.io.File[] getObbDirs(android.content.Context);
method public static boolean startActivities(android.content.Context, android.content.Intent[]);
method public static boolean startActivities(android.content.Context, android.content.Intent[], android.os.Bundle);
@@ -1071,6 +1026,11 @@ package android.support.v4.content {
method public void unregisterReceiver(android.content.BroadcastReceiver);
}
+ public class ParallelExecutorCompat {
+ ctor public ParallelExecutorCompat();
+ method public static java.util.concurrent.Executor getParallelExecutor();
+ }
+
public final class PermissionChecker {
method public static int checkCallingOrSelfPermission(android.content.Context, java.lang.String);
method public static int checkCallingPermission(android.content.Context, java.lang.String, java.lang.String);
@@ -1113,6 +1073,8 @@ package android.support.v4.content.res {
public class ResourcesCompat {
ctor public ResourcesCompat();
+ method public static int getColor(android.content.res.Resources, int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
+ method public static android.content.res.ColorStateList getColorStateList(android.content.res.Resources, int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
method public static android.graphics.drawable.Drawable getDrawable(android.content.res.Resources, int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
method public static android.graphics.drawable.Drawable getDrawableForDensity(android.content.res.Resources, int, int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
}
@@ -1246,6 +1208,77 @@ package android.support.v4.hardware.fingerprint {
package android.support.v4.media {
+ public final class MediaBrowserCompat {
+ ctor public MediaBrowserCompat(android.content.Context, android.content.ComponentName, android.support.v4.media.MediaBrowserCompat.ConnectionCallback, android.os.Bundle);
+ method public void connect();
+ method public void disconnect();
+ method public android.os.Bundle getExtras();
+ method public void getItem(java.lang.String, android.support.v4.media.MediaBrowserCompat.ItemCallback);
+ method public java.lang.String getRoot();
+ method public android.content.ComponentName getServiceComponent();
+ method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
+ method public boolean isConnected();
+ method public void subscribe(java.lang.String, android.support.v4.media.MediaBrowserCompat.SubscriptionCallback);
+ method public void unsubscribe(java.lang.String);
+ }
+
+ public static class MediaBrowserCompat.ConnectionCallback {
+ ctor public MediaBrowserCompat.ConnectionCallback();
+ method public void onConnected();
+ method public void onConnectionFailed();
+ method public void onConnectionSuspended();
+ }
+
+ public static abstract class MediaBrowserCompat.ItemCallback {
+ ctor public MediaBrowserCompat.ItemCallback();
+ method public void onError(java.lang.String);
+ method public void onItemLoaded(android.support.v4.media.MediaBrowserCompat.MediaItem);
+ }
+
+ public static class MediaBrowserCompat.MediaItem implements android.os.Parcelable {
+ ctor public MediaBrowserCompat.MediaItem(android.support.v4.media.MediaDescriptionCompat, int);
+ method public int describeContents();
+ method public android.support.v4.media.MediaDescriptionCompat getDescription();
+ method public int getFlags();
+ method public java.lang.String getMediaId();
+ method public boolean isBrowsable();
+ method public boolean isPlayable();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.MediaBrowserCompat.MediaItem> CREATOR;
+ field public static final int FLAG_BROWSABLE = 1; // 0x1
+ field public static final int FLAG_PLAYABLE = 2; // 0x2
+ }
+
+ public static abstract class MediaBrowserCompat.SubscriptionCallback {
+ ctor public MediaBrowserCompat.SubscriptionCallback();
+ method public void onChildrenLoaded(java.lang.String, java.util.List<android.support.v4.media.MediaBrowserCompat.MediaItem>);
+ method public void onError(java.lang.String);
+ }
+
+ public abstract class MediaBrowserServiceCompat extends android.app.Service {
+ ctor public MediaBrowserServiceCompat();
+ method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
+ method public void notifyChildrenChanged(java.lang.String);
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public abstract android.support.v4.media.MediaBrowserServiceCompat.BrowserRoot onGetRoot(java.lang.String, int, android.os.Bundle);
+ method public abstract void onLoadChildren(java.lang.String, android.support.v4.media.MediaBrowserServiceCompat.Result<java.util.List<android.support.v4.media.MediaBrowserCompat.MediaItem>>);
+ method public void onLoadItem(java.lang.String, android.support.v4.media.MediaBrowserServiceCompat.Result<android.support.v4.media.MediaBrowserCompat.MediaItem>);
+ method public void setSessionToken(android.support.v4.media.session.MediaSessionCompat.Token);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.media.browse.MediaBrowserService";
+ }
+
+ public static final class MediaBrowserServiceCompat.BrowserRoot {
+ ctor public MediaBrowserServiceCompat.BrowserRoot(java.lang.String, android.os.Bundle);
+ method public android.os.Bundle getExtras();
+ method public java.lang.String getRootId();
+ }
+
+ public static class MediaBrowserServiceCompat.Result {
+ method public void detach();
+ method public void sendResult(T);
+ }
+
public final class MediaDescriptionCompat implements android.os.Parcelable {
method public int describeContents();
method public static android.support.v4.media.MediaDescriptionCompat fromMediaDescription(java.lang.Object);
@@ -1449,6 +1482,12 @@ package android.support.v4.media {
package android.support.v4.media.session {
+ public class MediaButtonReceiver extends android.content.BroadcastReceiver {
+ ctor public MediaButtonReceiver();
+ method public static android.view.KeyEvent handleIntent(android.support.v4.media.session.MediaSessionCompat, android.content.Intent);
+ method public void onReceive(android.content.Context, android.content.Intent);
+ }
+
public final class MediaControllerCompat {
ctor public MediaControllerCompat(android.content.Context, android.support.v4.media.session.MediaSessionCompat);
ctor public MediaControllerCompat(android.content.Context, android.support.v4.media.session.MediaSessionCompat.Token) throws android.os.RemoteException;
@@ -1516,6 +1555,7 @@ package android.support.v4.media.session {
}
public class MediaSessionCompat {
+ ctor public MediaSessionCompat(android.content.Context, java.lang.String);
ctor public MediaSessionCompat(android.content.Context, java.lang.String, android.content.ComponentName, android.app.PendingIntent);
method public void addOnActiveChangeListener(android.support.v4.media.session.MediaSessionCompat.OnActiveChangeListener);
method public android.support.v4.media.session.MediaControllerCompat getController();
@@ -2349,6 +2389,13 @@ package android.support.v4.view {
method public abstract int computeVerticalScrollRange();
}
+ public abstract interface TintableBackgroundView {
+ method public abstract android.content.res.ColorStateList getSupportBackgroundTintList();
+ method public abstract android.graphics.PorterDuff.Mode getSupportBackgroundTintMode();
+ method public abstract void setSupportBackgroundTintList(android.content.res.ColorStateList);
+ method public abstract void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode);
+ }
+
public class VelocityTrackerCompat {
ctor public VelocityTrackerCompat();
method public static float getXVelocity(android.view.VelocityTracker, int);
@@ -2396,6 +2443,7 @@ package android.support.v4.view {
method public static float getRotationY(android.view.View);
method public static float getScaleX(android.view.View);
method public static float getScaleY(android.view.View);
+ method public static int getScrollIndicators(android.view.View);
method public static java.lang.String getTransitionName(android.view.View);
method public static float getTranslationX(android.view.View);
method public static float getTranslationY(android.view.View);
@@ -2406,6 +2454,7 @@ package android.support.v4.view {
method public static float getZ(android.view.View);
method public static boolean hasAccessibilityDelegate(android.view.View);
method public static boolean hasNestedScrollingParent(android.view.View);
+ method public static boolean hasOnClickListeners(android.view.View);
method public static boolean hasOverlappingRendering(android.view.View);
method public static boolean hasTransientState(android.view.View);
method public static boolean isAttachedToWindow(android.view.View);
@@ -2455,6 +2504,8 @@ package android.support.v4.view {
method public static void setSaveFromParentEnabled(android.view.View, boolean);
method public static void setScaleX(android.view.View, float);
method public static void setScaleY(android.view.View, float);
+ method public static void setScrollIndicators(android.view.View, int);
+ method public static void setScrollIndicators(android.view.View, int, int);
method public static void setTransitionName(android.view.View, java.lang.String);
method public static void setTranslationX(android.view.View, float);
method public static void setTranslationY(android.view.View, float);
@@ -2487,6 +2538,12 @@ package android.support.v4.view {
field public static final int SCROLL_AXIS_HORIZONTAL = 1; // 0x1
field public static final int SCROLL_AXIS_NONE = 0; // 0x0
field public static final int SCROLL_AXIS_VERTICAL = 2; // 0x2
+ field public static final int SCROLL_INDICATOR_BOTTOM = 2; // 0x2
+ field public static final int SCROLL_INDICATOR_END = 32; // 0x20
+ field public static final int SCROLL_INDICATOR_LEFT = 4; // 0x4
+ field public static final int SCROLL_INDICATOR_RIGHT = 8; // 0x8
+ field public static final int SCROLL_INDICATOR_START = 16; // 0x10
+ field public static final int SCROLL_INDICATOR_TOP = 1; // 0x1
}
public class ViewConfigurationCompat {
@@ -3138,6 +3195,7 @@ package android.support.v4.widget {
method public void setStatusBarBackgroundColor(int);
field public static final int LOCK_MODE_LOCKED_CLOSED = 1; // 0x1
field public static final int LOCK_MODE_LOCKED_OPEN = 2; // 0x2
+ field public static final int LOCK_MODE_UNDEFINED = 3; // 0x3
field public static final int LOCK_MODE_UNLOCKED = 0; // 0x0
field public static final int STATE_DRAGGING = 1; // 0x1
field public static final int STATE_IDLE = 0; // 0x0
@@ -3215,7 +3273,7 @@ package android.support.v4.widget {
method public void scrollTargetBy(int, int);
}
- public class NestedScrollView extends android.widget.FrameLayout implements android.support.v4.view.NestedScrollingChild android.support.v4.view.NestedScrollingParent {
+ public class NestedScrollView extends android.widget.FrameLayout implements android.support.v4.view.NestedScrollingChild android.support.v4.view.NestedScrollingParent android.support.v4.view.ScrollingView {
ctor public NestedScrollView(android.content.Context);
ctor public NestedScrollView(android.content.Context, android.util.AttributeSet);
ctor public NestedScrollView(android.content.Context, android.util.AttributeSet, int);
@@ -3230,11 +3288,16 @@ package android.support.v4.widget {
method public void onAttachedToWindow();
method public boolean pageScroll(int);
method public void setFillViewport(boolean);
+ method public void setOnScrollChangeListener(android.support.v4.widget.NestedScrollView.OnScrollChangeListener);
method public void setSmoothScrollingEnabled(boolean);
method public final void smoothScrollBy(int, int);
method public final void smoothScrollTo(int, int);
}
+ public static abstract interface NestedScrollView.OnScrollChangeListener {
+ method public abstract void onScrollChange(android.support.v4.widget.NestedScrollView, int, int, int, int);
+ }
+
public class PopupMenuCompat {
method public static android.view.View.OnTouchListener getDragToOpenListener(java.lang.Object);
}
@@ -3272,6 +3335,7 @@ package android.support.v4.widget {
method public boolean isOverScrolled();
method public void notifyHorizontalEdgeReached(int, int, int);
method public void notifyVerticalEdgeReached(int, int, int);
+ method public boolean springBack(int, int, int, int, int, int);
method public void startScroll(int, int, int, int);
method public void startScroll(int, int, int, int, int);
}
@@ -3417,9 +3481,19 @@ package android.support.v4.widget {
}
public class TextViewCompat {
+ method public static int getMaxLines(android.widget.TextView);
+ method public static int getMinLines(android.widget.TextView);
method public static void setCompoundDrawablesRelative(android.widget.TextView, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, int, int, int, int);
+ method public static void setTextAppearance(android.widget.TextView, int);
+ }
+
+ public abstract interface TintableCompoundButton {
+ method public abstract android.content.res.ColorStateList getSupportButtonTintList();
+ method public abstract android.graphics.PorterDuff.Mode getSupportButtonTintMode();
+ method public abstract void setSupportButtonTintList(android.content.res.ColorStateList);
+ method public abstract void setSupportButtonTintMode(android.graphics.PorterDuff.Mode);
}
public class ViewDragHelper {
diff --git a/v4/api21/android/content/pm/ParceledListSlice.java b/v4/api21/android/content/pm/ParceledListSlice.java
new file mode 100644
index 0000000000..b5183c0b94
--- /dev/null
+++ b/v4/api21/android/content/pm/ParceledListSlice.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2015 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.content.pm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.List;
+
+/**
+ * A dummy implementation for overriding a hidden framework class, ParceledListSlice.
+ * When there are duplicated signatures between app and framework code, the framework code will be
+ * run.
+ * @hide
+ */
+public class ParceledListSlice<T extends Parcelable> implements Parcelable {
+ public ParceledListSlice(List<T> list) {
+ }
+
+ @SuppressWarnings("unchecked")
+ private ParceledListSlice(Parcel p, ClassLoader loader) {
+ }
+
+ private static void verifySameType(final Class<?> expected, final Class<?> actual) {
+ }
+
+ public List<T> getList() {
+ return null;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ }
+
+ @SuppressWarnings("unchecked")
+ public static final Parcelable.ClassLoaderCreator<ParceledListSlice> CREATOR =
+ new Parcelable.ClassLoaderCreator<ParceledListSlice>() {
+ public ParceledListSlice createFromParcel(Parcel in) {
+ return null;
+ }
+
+ @Override
+ public ParceledListSlice createFromParcel(Parcel in, ClassLoader loader) {
+ return null;
+ }
+
+ public ParceledListSlice[] newArray(int size) {
+ return null;
+ }
+ };
+}
diff --git a/v4/api21/android/service/media/IMediaBrowserService.java b/v4/api21/android/service/media/IMediaBrowserService.java
new file mode 100644
index 0000000000..086dc9cc0d
--- /dev/null
+++ b/v4/api21/android/service/media/IMediaBrowserService.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 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.service.media;
+
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+
+/**
+ * A dummy implementation for overriding a hidden framework class, IMediaBrowserService.
+ * When there are duplicated signatures between app and framework code, the framework code will be
+ * run.
+ * TODO: Consider using aidl instead of this.
+ * @hide
+ */
+public interface IMediaBrowserService extends IInterface {
+
+ public static abstract class Stub extends Binder
+ implements IMediaBrowserService {
+ public Stub() {
+ }
+
+ public static IMediaBrowserService asInterface(IBinder obj) {
+ return null;
+ }
+
+ @Override
+ public IBinder asBinder() {
+ return null;
+ }
+
+ @Override
+ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+ throws android.os.RemoteException {
+ return false;
+ }
+ }
+
+ public void connect(String pkg, Bundle rootHints, IMediaBrowserServiceCallbacks callbacks)
+ throws android.os.RemoteException;
+ public void disconnect(IMediaBrowserServiceCallbacks callbacks) throws RemoteException;
+ public void addSubscription(String uri, IMediaBrowserServiceCallbacks callbacks)
+ throws RemoteException;
+ public void removeSubscription(String uri, IMediaBrowserServiceCallbacks callbacks)
+ throws RemoteException;
+ public void getMediaItem(String uri, ResultReceiver cb) throws android.os.RemoteException;
+}
diff --git a/v4/api21/android/service/media/IMediaBrowserServiceCallbacks.java b/v4/api21/android/service/media/IMediaBrowserServiceCallbacks.java
new file mode 100644
index 0000000000..fe988fee08
--- /dev/null
+++ b/v4/api21/android/service/media/IMediaBrowserServiceCallbacks.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2015 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.service.media;
+
+import android.content.pm.ParceledListSlice;
+import android.media.session.MediaSession;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.Parcel;
+import android.os.RemoteException;
+
+/**
+ * A dummy implementation for overriding a hidden framework class, IMediaBrowserServiceCallbacks.
+ * When there are duplicated signatures between app and framework code, the framework code will be
+ * run.
+ * TODO: Consider using aidl instead of this.
+ * @hide
+ */
+public interface IMediaBrowserServiceCallbacks extends IInterface {
+ public static abstract class Stub extends Binder implements IMediaBrowserServiceCallbacks
+ {
+ public Stub() {
+ }
+
+ public static IMediaBrowserServiceCallbacks asInterface(IBinder obj) {
+ return null;
+ }
+
+ @Override
+ public IBinder asBinder() {
+ return null;
+ }
+
+ @Override
+ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
+ return false;
+ }
+
+ private static class Proxy implements IMediaBrowserServiceCallbacks
+ {
+ Proxy(IBinder remote) {
+ }
+
+ @Override
+ public IBinder asBinder() {
+ return null;
+ }
+
+ public String getInterfaceDescriptor() {
+ return null;
+ }
+
+ @Override
+ public void onConnect(String root, MediaSession.Token session, Bundle extras)
+ throws RemoteException {
+ }
+
+ @Override
+ public void onConnectFailed() throws RemoteException {
+ }
+
+ @Override
+ public void onLoadChildren(String mediaId, ParceledListSlice list)
+ throws RemoteException {
+ }
+ }
+ }
+
+ public void onConnect(String root, MediaSession.Token session, Bundle extras)
+ throws RemoteException;
+ public void onConnectFailed() throws RemoteException;
+ public void onLoadChildren(String mediaId, ParceledListSlice list) throws RemoteException;
+}
+
diff --git a/v4/api21/android/support/v4/app/ActivityCompat21.java b/v4/api21/android/support/v4/app/ActivityCompat21.java
index f690fff0ed..2e6de1e462 100644
--- a/v4/api21/android/support/v4/app/ActivityCompat21.java
+++ b/v4/api21/android/support/v4/app/ActivityCompat21.java
@@ -21,6 +21,7 @@ import android.app.SharedElementCallback;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.RectF;
+import android.media.session.MediaController;
import android.os.Parcelable;
import android.view.View;
@@ -31,6 +32,10 @@ import java.util.Map;
class ActivityCompat21 {
+ public static void setMediaController(Activity activity, Object mediaControllerObj) {
+ activity.setMediaController((MediaController) mediaControllerObj);
+ }
+
public static void finishAfterTransition(Activity activity) {
activity.finishAfterTransition();
}
diff --git a/v4/api21/android/support/v4/graphics/drawable/DrawableCompatLollipop.java b/v4/api21/android/support/v4/graphics/drawable/DrawableCompatLollipop.java
index 93990b47fb..2f3b45a0d4 100644
--- a/v4/api21/android/support/v4/graphics/drawable/DrawableCompatLollipop.java
+++ b/v4/api21/android/support/v4/graphics/drawable/DrawableCompatLollipop.java
@@ -37,46 +37,28 @@ class DrawableCompatLollipop {
}
public static void setTint(Drawable drawable, int tint) {
- if (drawable instanceof DrawableWrapperLollipop) {
- // GradientDrawable on Lollipop does not support tinting, so we'll use our compatible
- // functionality instead
- DrawableCompatBase.setTint(drawable, tint);
- } else {
- // Else, we'll use the framework API
- drawable.setTint(tint);
- }
+ drawable.setTint(tint);
}
public static void setTintList(Drawable drawable, ColorStateList tint) {
- if (drawable instanceof DrawableWrapperLollipop) {
- // GradientDrawable on Lollipop does not support tinting, so we'll use our compatible
- // functionality instead
- DrawableCompatBase.setTintList(drawable, tint);
- } else {
- // Else, we'll use the framework API
- drawable.setTintList(tint);
- }
+ drawable.setTintList(tint);
}
public static void setTintMode(Drawable drawable, PorterDuff.Mode tintMode) {
- if (drawable instanceof DrawableWrapperLollipop) {
- // GradientDrawable on Lollipop does not support tinting, so we'll use our compatible
- // functionality instead
- DrawableCompatBase.setTintMode(drawable, tintMode);
- } else {
- // Else, we'll use the framework API
- drawable.setTintMode(tintMode);
- }
+ drawable.setTintMode(tintMode);
}
- public static Drawable wrapForTinting(Drawable drawable) {
- if (drawable instanceof GradientDrawable || drawable instanceof DrawableContainer) {
- // GradientDrawable on Lollipop does not support tinting, so we'll use our compatible
- // functionality instead. We also do the same for DrawableContainers since they may
- // contain GradientDrawable instances.
- return new DrawableWrapperLollipop(drawable);
+ public static Drawable wrapForTinting(final Drawable drawable) {
+ if (!(drawable instanceof DrawableWrapperLollipop)) {
+ return new DrawableWrapperLollipop(drawable, shouldForceCompatTinting(drawable));
}
return drawable;
}
+ private static boolean shouldForceCompatTinting(Drawable drawable) {
+ // GradientDrawable on Lollipop does not support tinting, so we'll use our compatible
+ // functionality instead. We also do the same for DrawableContainers since they may
+ // contain GradientDrawable instances.
+ return drawable instanceof GradientDrawable || drawable instanceof DrawableContainer;
+ }
}
diff --git a/v4/api21/android/support/v4/graphics/drawable/DrawableWrapperLollipop.java b/v4/api21/android/support/v4/graphics/drawable/DrawableWrapperLollipop.java
index 1f15040056..9533afd80f 100644
--- a/v4/api21/android/support/v4/graphics/drawable/DrawableWrapperLollipop.java
+++ b/v4/api21/android/support/v4/graphics/drawable/DrawableWrapperLollipop.java
@@ -16,15 +16,24 @@
package android.support.v4.graphics.drawable;
+import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Outline;
+import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
class DrawableWrapperLollipop extends DrawableWrapperKitKat {
+ private final boolean mUseCompatTinting;
+
DrawableWrapperLollipop(Drawable drawable) {
+ this(drawable, false);
+ }
+
+ DrawableWrapperLollipop(Drawable drawable, boolean useCompatTinting) {
super(drawable);
+ mUseCompatTinting = useCompatTinting;
}
@Override
@@ -56,4 +65,47 @@ class DrawableWrapperLollipop extends DrawableWrapperKitKat {
public Rect getDirtyBounds() {
return mDrawable.getDirtyBounds();
}
+
+ @Override
+ public void setTintList(ColorStateList tint) {
+ if (mUseCompatTinting) {
+ setCompatTintList(tint);
+ } else {
+ mDrawable.setTintList(tint);
+ }
+ }
+
+ @Override
+ public void setTint(int tintColor) {
+ if (mUseCompatTinting) {
+ setCompatTint(tintColor);
+ } else {
+ mDrawable.setTint(tintColor);
+ }
+ }
+
+ @Override
+ public void setTintMode(PorterDuff.Mode tintMode) {
+ if (mUseCompatTinting) {
+ setCompatTintMode(tintMode);
+ } else {
+ mDrawable.setTintMode(tintMode);
+ }
+ }
+
+ @Override
+ public boolean setState(int[] stateSet) {
+ if (super.setState(stateSet)) {
+ // Manually invalidate because the framework doesn't currently force an invalidation
+ // on a state change
+ invalidateSelf();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean isCompatTintEnabled() {
+ return mUseCompatTinting;
+ }
}
diff --git a/v4/api21/android/support/v4/media/MediaBrowserCompatApi21.java b/v4/api21/android/support/v4/media/MediaBrowserCompatApi21.java
new file mode 100644
index 0000000000..c6ccb14f2d
--- /dev/null
+++ b/v4/api21/android/support/v4/media/MediaBrowserCompatApi21.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2015 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.support.v4.media;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.media.browse.MediaBrowser;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.support.annotation.NonNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class MediaBrowserCompatApi21 {
+ static final String NULL_MEDIA_ITEM_ID =
+ "android.support.v4.media.MediaBrowserCompat.NULL_MEDIA_ITEM";
+
+ public static Object createConnectionCallback(ConnectionCallback callback) {
+ return new ConnectionCallbackProxy<>(callback);
+ }
+
+ public static Object createBrowser(Context context, ComponentName serviceComponent,
+ Object callback, Bundle rootHints) {
+ return new MediaBrowser(context, serviceComponent,
+ (MediaBrowser.ConnectionCallback) callback, rootHints);
+ }
+
+ public static void connect(Object browserObj) {
+ ((MediaBrowser)browserObj).connect();
+ }
+
+ public static void disconnect(Object browserObj) {
+ ((MediaBrowser)browserObj).disconnect();
+
+ }
+
+ public static boolean isConnected(Object browserObj) {
+ return ((MediaBrowser)browserObj).isConnected();
+ }
+
+ public static ComponentName getServiceComponent(Object browserObj) {
+ return ((MediaBrowser)browserObj).getServiceComponent();
+ }
+
+ public static String getRoot(Object browserObj) {
+ return ((MediaBrowser)browserObj).getRoot();
+ }
+
+ public static Bundle getExtras(Object browserObj) {
+ return ((MediaBrowser)browserObj).getExtras();
+ }
+
+ public static Object getSessionToken(Object browserObj) {
+ return ((MediaBrowser)browserObj).getSessionToken();
+ }
+
+ public static Object createSubscriptionCallback(SubscriptionCallback callback) {
+ return new SubscriptionCallbackProxy<>(callback);
+ }
+
+ public static void subscribe(
+ Object browserObj, String parentId, Object subscriptionCallbackObj) {
+ ((MediaBrowser)browserObj).subscribe(parentId,
+ (MediaBrowser.SubscriptionCallback) subscriptionCallbackObj);
+ }
+
+ public static void unsubscribe(Object browserObj, String parentId) {
+ ((MediaBrowser)browserObj).unsubscribe(parentId);
+ }
+
+ interface ConnectionCallback {
+ void onConnected();
+ void onConnectionSuspended();
+ void onConnectionFailed();
+ }
+
+ static class ConnectionCallbackProxy<T extends ConnectionCallback>
+ extends MediaBrowser.ConnectionCallback {
+ protected final T mConnectionCallback;
+
+ public ConnectionCallbackProxy(T connectionCallback) {
+ mConnectionCallback = connectionCallback;
+ }
+
+ @Override
+ public void onConnected() {
+ mConnectionCallback.onConnected();
+ }
+
+ @Override
+ public void onConnectionSuspended() {
+ mConnectionCallback.onConnectionSuspended();
+ }
+
+ @Override
+ public void onConnectionFailed() {
+ mConnectionCallback.onConnectionFailed();
+ }
+ }
+
+ interface SubscriptionCallback {
+ void onChildrenLoaded(@NonNull String parentId, List<Parcel> children);
+ void onError(@NonNull String parentId);
+ }
+
+ static class SubscriptionCallbackProxy<T extends SubscriptionCallback>
+ extends MediaBrowser.SubscriptionCallback {
+ protected final T mSubscriptionCallback;
+
+ public SubscriptionCallbackProxy(T callback) {
+ mSubscriptionCallback = callback;
+ }
+
+ @Override
+ public void onChildrenLoaded(@NonNull String parentId,
+ List<MediaBrowser.MediaItem> children) {
+ List<Parcel> parcelList = null;
+ if (children != null && children.size() == 1
+ && children.get(0).getMediaId().equals(NULL_MEDIA_ITEM_ID)) {
+ children = null;
+ }
+ if (children != null) {
+ parcelList = new ArrayList<>();
+ for (MediaBrowser.MediaItem item : children) {
+ Parcel parcel = Parcel.obtain();
+ item.writeToParcel(parcel, 0);
+ parcelList.add(parcel);
+ }
+ }
+ mSubscriptionCallback.onChildrenLoaded(parentId, parcelList);
+ }
+
+ @Override
+ public void onError(@NonNull String parentId) {
+ mSubscriptionCallback.onError(parentId);
+ }
+ }
+}
diff --git a/v4/api21/android/support/v4/media/MediaBrowserServiceCompatApi21.java b/v4/api21/android/support/v4/media/MediaBrowserServiceCompatApi21.java
new file mode 100644
index 0000000000..a1506d3f22
--- /dev/null
+++ b/v4/api21/android/support/v4/media/MediaBrowserServiceCompatApi21.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2015 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.support.v4.media;
+
+import android.content.Intent;
+import android.content.pm.ParceledListSlice;
+import android.media.MediaDescription;
+import android.media.browse.MediaBrowser;
+import android.media.session.MediaSession;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.service.media.IMediaBrowserService;
+import android.service.media.IMediaBrowserServiceCallbacks;
+import android.service.media.MediaBrowserService;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class MediaBrowserServiceCompatApi21 {
+
+ public static Object createService() {
+ return new MediaBrowserServiceAdaptorApi21();
+ }
+
+ public static void onCreate(Object serviceObj, ServiceImplApi21 serviceImpl) {
+ ((MediaBrowserServiceAdaptorApi21) serviceObj).onCreate(serviceImpl);
+ }
+
+ public static IBinder onBind(Object serviceObj, Intent intent) {
+ return ((MediaBrowserServiceAdaptorApi21) serviceObj).onBind(intent);
+ }
+
+ public interface ServiceImplApi21 {
+ void connect(final String pkg, final Bundle rootHints, final ServiceCallbacks callbacks);
+ void disconnect(final ServiceCallbacks callbacks);
+ void addSubscription(final String id, final ServiceCallbacks callbacks);
+ void removeSubscription(final String id, final ServiceCallbacks callbacks);
+ }
+
+ public interface ServiceCallbacks {
+ IBinder asBinder();
+ void onConnect(String root, Object session, Bundle extras) throws RemoteException;
+ void onConnectFailed() throws RemoteException;
+ void onLoadChildren(String mediaId, List<Parcel> list) throws RemoteException;
+ }
+
+ public static class ServiceCallbacksApi21 implements ServiceCallbacks {
+ private static final ParceledListSlice sNullParceledListSlice;
+ static {
+ MediaDescription nullDescription = new MediaDescription.Builder().setMediaId(
+ MediaBrowserCompatApi21.NULL_MEDIA_ITEM_ID).build();
+ MediaBrowser.MediaItem nullMediaItem = new MediaBrowser.MediaItem(nullDescription, 0);
+ List<MediaBrowser.MediaItem> nullMediaItemList = new ArrayList<>();
+ nullMediaItemList.add(nullMediaItem);
+ sNullParceledListSlice = new ParceledListSlice(nullMediaItemList);
+ }
+
+ private final IMediaBrowserServiceCallbacks mCallbacks;
+
+ ServiceCallbacksApi21(IMediaBrowserServiceCallbacks callbacks) {
+ mCallbacks = callbacks;
+ }
+
+ public IBinder asBinder() {
+ return mCallbacks.asBinder();
+ }
+
+ public void onConnect(String root, Object session, Bundle extras) throws RemoteException {
+ mCallbacks.onConnect(root, (MediaSession.Token) session, extras);
+ }
+
+ public void onConnectFailed() throws RemoteException {
+ mCallbacks.onConnectFailed();
+ }
+
+ public void onLoadChildren(String mediaId, List<Parcel> list) throws RemoteException {
+ List<MediaBrowser.MediaItem> itemList = null;
+ if (list != null) {
+ itemList = new ArrayList<>();
+ for (Parcel parcel : list) {
+ parcel.setDataPosition(0);
+ itemList.add(MediaBrowser.MediaItem.CREATOR.createFromParcel(parcel));
+ parcel.recycle();
+ }
+ }
+ ParceledListSlice<MediaBrowser.MediaItem> pls;
+ if (Build.VERSION.SDK_INT > 23) {
+ pls = itemList == null ? null : new ParceledListSlice(itemList);
+ } else {
+ pls = itemList == null ? sNullParceledListSlice : new ParceledListSlice(itemList);
+ }
+ mCallbacks.onLoadChildren(mediaId, pls);
+ }
+ }
+
+ static class MediaBrowserServiceAdaptorApi21 {
+ ServiceBinderProxyApi21 mBinder;
+
+ public void onCreate(ServiceImplApi21 serviceImpl) {
+ mBinder = new ServiceBinderProxyApi21(serviceImpl);
+ }
+
+ public IBinder onBind(Intent intent) {
+ if (MediaBrowserService.SERVICE_INTERFACE.equals(intent.getAction())) {
+ return mBinder;
+ }
+ return null;
+ }
+
+ static class ServiceBinderProxyApi21 extends IMediaBrowserService.Stub {
+ final ServiceImplApi21 mServiceImpl;
+
+ ServiceBinderProxyApi21(ServiceImplApi21 serviceImpl) {
+ mServiceImpl = serviceImpl;
+ }
+
+ @Override
+ public void connect(final String pkg, final Bundle rootHints,
+ final IMediaBrowserServiceCallbacks callbacks) {
+ mServiceImpl.connect(pkg, rootHints, new ServiceCallbacksApi21(callbacks));
+ }
+
+ @Override
+ public void disconnect(final IMediaBrowserServiceCallbacks callbacks) {
+ mServiceImpl.disconnect(new ServiceCallbacksApi21(callbacks));
+ }
+
+
+ @Override
+ public void addSubscription(final String id,
+ final IMediaBrowserServiceCallbacks callbacks) {
+ mServiceImpl.addSubscription(id, new ServiceCallbacksApi21(callbacks));
+ }
+
+ @Override
+ public void removeSubscription(final String id,
+ final IMediaBrowserServiceCallbacks callbacks) {
+ mServiceImpl.removeSubscription(id, new ServiceCallbacksApi21(callbacks));
+ }
+
+ @Override
+ public void getMediaItem(final String mediaId, final ResultReceiver receiver) {
+ // No operation since this method is added in API 23.
+ }
+ }
+ }
+}
diff --git a/v4/api21/android/support/v4/media/MediaDescriptionCompatApi21.java b/v4/api21/android/support/v4/media/MediaDescriptionCompatApi21.java
index 991515accc..234a77a6c8 100644
--- a/v4/api21/android/support/v4/media/MediaDescriptionCompatApi21.java
+++ b/v4/api21/android/support/v4/media/MediaDescriptionCompatApi21.java
@@ -21,7 +21,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
-public class MediaDescriptionCompatApi21 {
+class MediaDescriptionCompatApi21 {
public static String getMediaId(Object descriptionObj) {
return ((MediaDescription) descriptionObj).getMediaId();
@@ -59,7 +59,7 @@ public class MediaDescriptionCompatApi21 {
return MediaDescription.CREATOR.createFromParcel(in);
}
- public static class Builder {
+ static class Builder {
public static Object newInstance() {
return new MediaDescription.Builder();
}
diff --git a/v4/api21/android/support/v4/media/MediaMetadataCompatApi21.java b/v4/api21/android/support/v4/media/MediaMetadataCompatApi21.java
index eddcf76944..fd51f783ce 100644
--- a/v4/api21/android/support/v4/media/MediaMetadataCompatApi21.java
+++ b/v4/api21/android/support/v4/media/MediaMetadataCompatApi21.java
@@ -19,6 +19,7 @@ package android.support.v4.media;
import android.graphics.Bitmap;
import android.media.MediaMetadata;
import android.media.Rating;
+import android.os.Parcel;
import java.util.Set;
@@ -43,6 +44,14 @@ class MediaMetadataCompatApi21 {
return ((MediaMetadata) metadataObj).getText(key);
}
+ public static void writeToParcel(Object metadataObj, Parcel dest, int flags) {
+ ((MediaMetadata) metadataObj).writeToParcel(dest, flags);
+ }
+
+ public static Object createFromParcel(Parcel in) {
+ return MediaMetadata.CREATOR.createFromParcel(in);
+ }
+
public static class Builder {
public static Object newInstance() {
return new MediaMetadata.Builder();
diff --git a/v4/api21/android/support/v4/media/session/MediaSessionCompatApi21.java b/v4/api21/android/support/v4/media/session/MediaSessionCompatApi21.java
index 809439137a..b3e7fd11f1 100644
--- a/v4/api21/android/support/v4/media/session/MediaSessionCompatApi21.java
+++ b/v4/api21/android/support/v4/media/session/MediaSessionCompatApi21.java
@@ -132,7 +132,7 @@ class MediaSessionCompatApi21 {
((MediaSession) sessionObj).setExtras(extras);
}
- public static interface Callback {
+ static interface Callback {
public void onCommand(String command, Bundle extras, ResultReceiver cb);
public boolean onMediaButtonEvent(Intent mediaButtonIntent);
public void onPlay();
diff --git a/v4/api22/android/support/v4/graphics/drawable/DrawableCompatApi22.java b/v4/api22/android/support/v4/graphics/drawable/DrawableCompatApi22.java
index bfd2bea122..50f265704a 100644
--- a/v4/api22/android/support/v4/graphics/drawable/DrawableCompatApi22.java
+++ b/v4/api22/android/support/v4/graphics/drawable/DrawableCompatApi22.java
@@ -24,8 +24,8 @@ import android.graphics.drawable.Drawable;
class DrawableCompatApi22 {
public static Drawable wrapForTinting(Drawable drawable) {
- // We don't need to wrap anything in Lollipop-MR1
- return drawable;
+ // We need to wrap to force an invalidation on any state change
+ return new DrawableWrapperLollipop(drawable);
}
}
diff --git a/v4/api23/android/support/v4/app/AppOpsManagerCompat23.java b/v4/api23/android/support/v4/app/AppOpsManagerCompat23.java
index 64a1206949..72e07bf0ed 100644
--- a/v4/api23/android/support/v4/app/AppOpsManagerCompat23.java
+++ b/v4/api23/android/support/v4/app/AppOpsManagerCompat23.java
@@ -22,7 +22,7 @@ import android.content.Context;
/**
* AppOpsManager implementations for API 23.
*/
-public class AppOpsManagerCompat23 {
+class AppOpsManagerCompat23 {
public static String permissionToOp(String permission) {
return AppOpsManager.permissionToOp(permission);
}
diff --git a/v4/api23/android/support/v4/content/ResourcesCompatApi23.java b/v4/api23/android/support/v4/content/ResourcesCompatApi23.java
new file mode 100644
index 0000000000..c44f9cef1f
--- /dev/null
+++ b/v4/api23/android/support/v4/content/ResourcesCompatApi23.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 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.support.v4.content.res;
+
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.content.res.Resources.Theme;
+
+class ResourcesCompatApi23 {
+ public static int getColor(Resources res, int id, Theme theme) throws NotFoundException {
+ return res.getColor(id, theme);
+ }
+
+ public static ColorStateList getColorStateList(Resources res, int id, Theme theme)
+ throws NotFoundException {
+ return res.getColorStateList(id, theme);
+ }
+}
diff --git a/v4/api23/android/support/v4/media/MediaBrowserCompatApi23.java b/v4/api23/android/support/v4/media/MediaBrowserCompatApi23.java
new file mode 100644
index 0000000000..1e9df1a439
--- /dev/null
+++ b/v4/api23/android/support/v4/media/MediaBrowserCompatApi23.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 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.support.v4.media;
+
+import android.media.browse.MediaBrowser;
+import android.os.Parcel;
+import android.support.annotation.NonNull;
+
+class MediaBrowserCompatApi23 {
+
+ public static Object createItemCallback(ItemCallback callback) {
+ return new ItemCallbackProxy<>(callback);
+ }
+
+ public static void getItem(Object browserObj, String mediaId, Object itemCallbackObj) {
+ ((MediaBrowser) browserObj).getItem(mediaId, ((MediaBrowser.ItemCallback) itemCallbackObj));
+ }
+
+ interface ItemCallback {
+ void onItemLoaded(Parcel itemParcel);
+ void onError(@NonNull String itemId);
+ }
+
+ static class ItemCallbackProxy<T extends ItemCallback> extends MediaBrowser.ItemCallback {
+ protected final T mItemCallback;
+
+ public ItemCallbackProxy(T callback) {
+ mItemCallback = callback;
+ }
+
+ @Override
+ public void onItemLoaded(MediaBrowser.MediaItem item) {
+ Parcel parcel = Parcel.obtain();
+ item.writeToParcel(parcel, 0);
+ mItemCallback.onItemLoaded(parcel);
+ }
+
+ @Override
+ public void onError(@NonNull String itemId) {
+ mItemCallback.onError(itemId);
+ }
+ }
+}
diff --git a/v4/api23/android/support/v4/media/MediaBrowserServiceCompatApi23.java b/v4/api23/android/support/v4/media/MediaBrowserServiceCompatApi23.java
new file mode 100644
index 0000000000..fcaea408a2
--- /dev/null
+++ b/v4/api23/android/support/v4/media/MediaBrowserServiceCompatApi23.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2015 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.support.v4.media;
+
+import android.media.browse.MediaBrowser;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.ResultReceiver;
+import android.service.media.MediaBrowserService;
+import android.util.Log;
+
+class MediaBrowserServiceCompatApi23 extends MediaBrowserServiceCompatApi21 {
+ private static final String TAG = "MediaBrowserServiceCompatApi21";
+
+ public static Object createService() {
+ return new MediaBrowserServiceAdaptorApi23();
+ }
+
+ public static void onCreate(Object serviceObj, ServiceImplApi23 serviceImpl) {
+ ((MediaBrowserServiceAdaptorApi23) serviceObj).onCreate(serviceImpl);
+ }
+
+ public interface ServiceImplApi23 extends ServiceImplApi21 {
+ void getMediaItem(final String mediaId, final ItemCallback cb);
+ }
+
+ public interface ItemCallback {
+ void onItemLoaded(int resultCode, Bundle resultData, Parcel itemParcel);
+ }
+
+ static class MediaBrowserServiceAdaptorApi23 extends MediaBrowserServiceAdaptorApi21 {
+
+ public void onCreate(ServiceImplApi23 serviceImpl) {
+ mBinder = new ServiceBinderProxyApi23(serviceImpl);
+ }
+
+ private static class ServiceBinderProxyApi23 extends ServiceBinderProxyApi21 {
+ ServiceImplApi23 mServiceImpl;
+
+ ServiceBinderProxyApi23(ServiceImplApi23 serviceImpl) {
+ super(serviceImpl);
+ mServiceImpl = serviceImpl;
+ }
+
+ @Override
+ public void getMediaItem(final String mediaId, final ResultReceiver receiver) {
+ final String KEY_MEDIA_ITEM;
+ try {
+ KEY_MEDIA_ITEM = (String) MediaBrowserService.class.getDeclaredField(
+ "KEY_MEDIA_ITEM").get(null);
+ } catch (IllegalAccessException | NoSuchFieldException e) {
+ Log.i(TAG, "Failed to get KEY_MEDIA_ITEM via reflection", e);
+ return;
+ }
+
+ mServiceImpl.getMediaItem(mediaId, new ItemCallback() {
+ @Override
+ public void onItemLoaded(int resultCode, Bundle resultData, Parcel itemParcel) {
+ if (itemParcel != null) {
+ itemParcel.setDataPosition(0);
+ MediaBrowser.MediaItem item =
+ MediaBrowser.MediaItem.CREATOR.createFromParcel(itemParcel);
+ resultData.putParcelable(KEY_MEDIA_ITEM, item);
+ itemParcel.recycle();
+ }
+ receiver.send(resultCode, resultData);
+ }
+ });
+ }
+ }
+ }
+}
diff --git a/v4/api23/android/support/v4/text/ICUCompatApi23.java b/v4/api23/android/support/v4/text/ICUCompatApi23.java
index f013522a90..1a3c54f17e 100644
--- a/v4/api23/android/support/v4/text/ICUCompatApi23.java
+++ b/v4/api23/android/support/v4/text/ICUCompatApi23.java
@@ -22,7 +22,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Locale;
-public class ICUCompatApi23 {
+class ICUCompatApi23 {
private static final String TAG = "ICUCompatIcs";
diff --git a/v4/api23/android/support/v4/view/ViewCompatMarshmallow.java b/v4/api23/android/support/v4/view/ViewCompatMarshmallow.java
new file mode 100644
index 0000000000..16d3ae88e1
--- /dev/null
+++ b/v4/api23/android/support/v4/view/ViewCompatMarshmallow.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 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.support.v4.view;
+
+import android.view.View;
+
+class ViewCompatMarshmallow {
+ public static void setScrollIndicators(View view, int indicators) {
+ view.setScrollIndicators(indicators);
+ }
+
+ public static void setScrollIndicators(View view, int indicators, int mask) {
+ view.setScrollIndicators(indicators, mask);
+ }
+
+ public static int getScrollIndicators(View view) {
+ return view.getScrollIndicators();
+ }
+}
diff --git a/v4/api23/android/support/v4/widget/TextViewCompatApi23.java b/v4/api23/android/support/v4/widget/TextViewCompatApi23.java
new file mode 100644
index 0000000000..8370bfcd87
--- /dev/null
+++ b/v4/api23/android/support/v4/widget/TextViewCompatApi23.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 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.support.v4.widget;
+
+import android.support.annotation.IdRes;
+import android.support.annotation.NonNull;
+import android.widget.TextView;
+
+class TextViewCompatApi23 {
+ public static void setTextAppearance(@NonNull TextView textView, @IdRes int resId) {
+ textView.setTextAppearance(resId);
+ }
+}
diff --git a/v4/build.gradle b/v4/build.gradle
index a056973e6d..ba65cabb07 100644
--- a/v4/build.gradle
+++ b/v4/build.gradle
@@ -64,6 +64,10 @@ dependencies {
// depend on the generation of this jar. This is done below
// when manipulating the libraryVariants.
compile files(internalJar.archivePath)
+
+ androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
+ androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'
+ testCompile 'junit:junit:4.12'
}
android {
@@ -73,6 +77,8 @@ android {
minSdkVersion 4
// TODO: get target from branch
//targetSdkVersion 19
+
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
sourceSets {
@@ -82,6 +88,8 @@ android {
androidTest.setRoot('tests')
androidTest.java.srcDir 'tests/java'
+ androidTest.res.srcDir 'tests/res'
+ androidTest.manifest.srcFile 'tests/AndroidManifest.xml'
}
lintOptions {
@@ -93,6 +101,10 @@ android {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
+
+ testOptions {
+ unitTests.returnDefaultValues = true
+ }
}
android.libraryVariants.all { variant ->
@@ -124,6 +136,8 @@ android.libraryVariants.all { variant ->
def sourcesJarTask = project.tasks.create(name: "sourceJar${suffix}", type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
+ exclude('android/content/pm/**')
+ exclude('android/service/media/**')
}
project.ext.allSS.each { ss ->
@@ -135,6 +149,17 @@ android.libraryVariants.all { variant ->
artifacts.add('archives', sourcesJarTask);
}
+// TODO make this generic for all projects
+afterEvaluate {
+ def originalTask = tasks['packageDebugAndroidTest']
+ tasks['assembleDebugAndroidTest'].doLast {
+ copy {
+ from(originalTask.outputFile)
+ into(rootProject.ext.testApkDistOut)
+ }
+ }
+}
+
uploadArchives {
repositories {
mavenDeployer {
diff --git a/v4/donut/android/support/v4/animation/ValueAnimatorCompat.java b/v4/donut/android/support/v4/animation/ValueAnimatorCompat.java
index 6d98c97719..07cc602708 100644
--- a/v4/donut/android/support/v4/animation/ValueAnimatorCompat.java
+++ b/v4/donut/android/support/v4/animation/ValueAnimatorCompat.java
@@ -19,7 +19,7 @@ package android.support.v4.animation;
import android.view.View;
/**
- * Compatibility implementation for {@link android.animation.Animator}.
+ * Compatibility implementation for {@code android.animation.ValueAnimator}.
*
* @hide
*/
diff --git a/v4/donut/android/support/v4/graphics/drawable/DrawableCompatBase.java b/v4/donut/android/support/v4/graphics/drawable/DrawableCompatBase.java
index 4809618527..fe0163dd61 100644
--- a/v4/donut/android/support/v4/graphics/drawable/DrawableCompatBase.java
+++ b/v4/donut/android/support/v4/graphics/drawable/DrawableCompatBase.java
@@ -27,19 +27,19 @@ class DrawableCompatBase {
public static void setTint(Drawable drawable, int tint) {
if (drawable instanceof DrawableWrapper) {
- ((DrawableWrapper) drawable).setTint(tint);
+ ((DrawableWrapper) drawable).setCompatTint(tint);
}
}
public static void setTintList(Drawable drawable, ColorStateList tint) {
if (drawable instanceof DrawableWrapper) {
- ((DrawableWrapper) drawable).setTintList(tint);
+ ((DrawableWrapper) drawable).setCompatTintList(tint);
}
}
public static void setTintMode(Drawable drawable, PorterDuff.Mode tintMode) {
if (drawable instanceof DrawableWrapper) {
- ((DrawableWrapper) drawable).setTintMode(tintMode);
+ ((DrawableWrapper) drawable).setCompatTintMode(tintMode);
}
}
diff --git a/v4/donut/android/support/v4/graphics/drawable/DrawableWrapper.java b/v4/donut/android/support/v4/graphics/drawable/DrawableWrapper.java
index 1073f344c6..edbe5ad9d0 100644
--- a/v4/donut/android/support/v4/graphics/drawable/DrawableWrapper.java
+++ b/v4/donut/android/support/v4/graphics/drawable/DrawableWrapper.java
@@ -28,11 +28,11 @@ import android.graphics.drawable.Drawable;
*/
public interface DrawableWrapper {
- void setTint(int tint);
+ void setCompatTint(int tint);
- void setTintList(ColorStateList tint);
+ void setCompatTintList(ColorStateList tint);
- void setTintMode(PorterDuff.Mode tintMode);
+ void setCompatTintMode(PorterDuff.Mode tintMode);
Drawable getWrappedDrawable();
diff --git a/v4/donut/android/support/v4/graphics/drawable/DrawableWrapperDonut.java b/v4/donut/android/support/v4/graphics/drawable/DrawableWrapperDonut.java
index 9293520455..300e2e8ce1 100644
--- a/v4/donut/android/support/v4/graphics/drawable/DrawableWrapperDonut.java
+++ b/v4/donut/android/support/v4/graphics/drawable/DrawableWrapperDonut.java
@@ -89,7 +89,8 @@ class DrawableWrapperDonut extends Drawable implements Drawable.Callback, Drawab
@Override
public boolean isStateful() {
- return (mTintList != null && mTintList.isStateful()) || mDrawable.isStateful();
+ final ColorStateList tintList = isCompatTintEnabled() ? mTintList : null;
+ return (tintList != null && tintList.isStateful()) || mDrawable.isStateful();
}
@Override
@@ -188,30 +189,38 @@ class DrawableWrapperDonut extends Drawable implements Drawable.Callback, Drawab
}
@Override
- public void setTint(int tint) {
- setTintList(ColorStateList.valueOf(tint));
+ public void setCompatTint(int tint) {
+ setCompatTintList(ColorStateList.valueOf(tint));
}
@Override
- public void setTintList(ColorStateList tint) {
- mTintList = tint;
- updateTint(getState());
+ public void setCompatTintList(ColorStateList tint) {
+ if (mTintList != tint) {
+ mTintList = tint;
+ updateTint(getState());
+ }
}
@Override
- public void setTintMode(PorterDuff.Mode tintMode) {
- mTintMode = tintMode;
- updateTint(getState());
+ public void setCompatTintMode(PorterDuff.Mode tintMode) {
+ if (mTintMode != tintMode) {
+ mTintMode = tintMode;
+ updateTint(getState());
+ }
}
private boolean updateTint(int[] state) {
+ if (!isCompatTintEnabled()) {
+ // If compat tinting is not enabled, fail fast
+ return false;
+ }
+
if (mTintList != null && mTintMode != null) {
final int color = mTintList.getColorForState(state, mTintList.getDefaultColor());
- final PorterDuff.Mode mode = mTintMode;
- if (!mColorFilterSet || color != mCurrentColor || mode != mCurrentMode) {
- setColorFilter(color, mode);
+ if (!mColorFilterSet || color != mCurrentColor || mTintMode != mCurrentMode) {
+ setColorFilter(color, mTintMode);
mCurrentColor = color;
- mCurrentMode = mode;
+ mCurrentMode = mTintMode;
mColorFilterSet = true;
return true;
}
@@ -236,13 +245,26 @@ class DrawableWrapperDonut extends Drawable implements Drawable.Callback, Drawab
if (mDrawable != null) {
mDrawable.setCallback(null);
}
-
- mDrawable = drawable;
+ mDrawable = null;
if (drawable != null) {
+ // Copy over the bounds from the drawable
+ setBounds(drawable.getBounds());
+ // Set ourselves as the callback for invalidations
drawable.setCallback(this);
+ } else {
+ // Clear our bounds
+ setBounds(0, 0, 0, 0);
}
+
+ mDrawable = drawable;
+
// Invalidate ourselves
invalidateSelf();
}
+
+ protected boolean isCompatTintEnabled() {
+ // It's enabled by default on Donut
+ return true;
+ }
}
diff --git a/v4/froyo/android/support/v4/media/session/MediaSessionCompatApi8.java b/v4/froyo/android/support/v4/media/session/MediaSessionCompatApi8.java
index f49eb2b7cb..d03287fead 100644
--- a/v4/froyo/android/support/v4/media/session/MediaSessionCompatApi8.java
+++ b/v4/froyo/android/support/v4/media/session/MediaSessionCompatApi8.java
@@ -19,7 +19,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.media.AudioManager;
-public class MediaSessionCompatApi8 {
+class MediaSessionCompatApi8 {
public static void registerMediaButtonEventReceiver(Context context, ComponentName mbr) {
AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
am.registerMediaButtonEventReceiver(mbr);
diff --git a/v4/gingerbread/android/support/v4/widget/ScrollerCompatGingerbread.java b/v4/gingerbread/android/support/v4/widget/ScrollerCompatGingerbread.java
index 429e864b08..61c9a03e23 100644
--- a/v4/gingerbread/android/support/v4/widget/ScrollerCompatGingerbread.java
+++ b/v4/gingerbread/android/support/v4/widget/ScrollerCompatGingerbread.java
@@ -87,4 +87,9 @@ class ScrollerCompatGingerbread {
public static int getFinalY(Object scroller) {
return ((OverScroller) scroller).getFinalY();
}
+
+ public static boolean springBack(Object scroller, int startX, int startY, int minX, int maxX,
+ int minY, int maxY) {
+ return ((OverScroller) scroller).springBack(startX, startY, minX, maxX, minY, maxY);
+ }
}
diff --git a/v4/honeycomb/android/support/v4/content/ExecutorCompatHoneycomb.java b/v4/honeycomb/android/support/v4/content/ExecutorCompatHoneycomb.java
new file mode 100644
index 0000000000..fa6af478f6
--- /dev/null
+++ b/v4/honeycomb/android/support/v4/content/ExecutorCompatHoneycomb.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 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.support.v4.content;
+
+import android.os.AsyncTask;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Implementation of parallel executor compatibility that can call Honeycomb APIs.
+ * @hide
+ */
+class ExecutorCompatHoneycomb {
+ public static Executor getParallelExecutor() {
+ return AsyncTask.THREAD_POOL_EXECUTOR;
+ }
+}
diff --git a/v4/ics-mr1/android/support/v4/view/ViewCompatICSMr1.java b/v4/ics-mr1/android/support/v4/view/ViewCompatICSMr1.java
new file mode 100644
index 0000000000..780345c61b
--- /dev/null
+++ b/v4/ics-mr1/android/support/v4/view/ViewCompatICSMr1.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 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.support.v4.view;
+
+import android.support.annotation.Nullable;
+import android.view.View;
+import android.view.View.AccessibilityDelegate;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+/**
+ * Helper for accessing newer features in View introduced in ICS Mr1.
+ */
+class ViewCompatICSMr1 {
+ public static boolean hasOnClickListeners(View v) {
+ return v.hasOnClickListeners();
+ }
+}
diff --git a/v4/ics/android/support/v4/media/session/MediaSessionCompatApi14.java b/v4/ics/android/support/v4/media/session/MediaSessionCompatApi14.java
index de644e695d..3378e1ec86 100644
--- a/v4/ics/android/support/v4/media/session/MediaSessionCompatApi14.java
+++ b/v4/ics/android/support/v4/media/session/MediaSessionCompatApi14.java
@@ -25,7 +25,7 @@ import android.media.RemoteControlClient;
import android.os.Bundle;
import android.os.ResultReceiver;
-public class MediaSessionCompatApi14 {
+class MediaSessionCompatApi14 {
/***** RemoteControlClient States, we only need none as the others were public *******/
final static int RCC_PLAYSTATE_NONE = 0;
@@ -224,7 +224,7 @@ public class MediaSessionCompatApi14 {
}
}
- public static interface Callback {
+ static interface Callback {
public void onCommand(String command, Bundle extras, ResultReceiver cb);
public boolean onMediaButtonEvent(Intent mediaButtonIntent);
diff --git a/v4/ics/android/support/v4/view/ViewParentCompatICS.java b/v4/ics/android/support/v4/view/ViewParentCompatICS.java
index 251de0e0d0..f9fc5a5f74 100644
--- a/v4/ics/android/support/v4/view/ViewParentCompatICS.java
+++ b/v4/ics/android/support/v4/view/ViewParentCompatICS.java
@@ -23,7 +23,7 @@ import android.view.accessibility.AccessibilityEvent;
/**
* ICS-specific ViewParent API implementation.
*/
-public class ViewParentCompatICS {
+class ViewParentCompatICS {
public static boolean requestSendAccessibilityEvent(
ViewParent parent, View child, AccessibilityEvent event) {
return parent.requestSendAccessibilityEvent(child, event);
diff --git a/v4/java/android/support/v4/animation/AnimatorCompatHelper.java b/v4/java/android/support/v4/animation/AnimatorCompatHelper.java
index 8fa3679e6b..6ebe5c84ad 100644
--- a/v4/java/android/support/v4/animation/AnimatorCompatHelper.java
+++ b/v4/java/android/support/v4/animation/AnimatorCompatHelper.java
@@ -19,9 +19,12 @@ package android.support.v4.animation;
import android.os.Build;
import android.view.View;
-abstract public class AnimatorCompatHelper {
+/**
+ * @hide
+ */
+public final class AnimatorCompatHelper {
- static AnimatorProvider IMPL;
+ private final static AnimatorProvider IMPL;
static {
if (Build.VERSION.SDK_INT >= 12) {
@@ -35,9 +38,7 @@ abstract public class AnimatorCompatHelper {
return IMPL.emptyValueAnimator();
}
- AnimatorCompatHelper() {
-
- }
+ private AnimatorCompatHelper() {}
public static void clearInterpolator(View view) {
IMPL.clearInterpolator(view);
diff --git a/v4/java/android/support/v4/app/FragmentActivity.java b/v4/java/android/support/v4/app/FragmentActivity.java
index 1dd6d018d9..59881a21e6 100644
--- a/v4/java/android/support/v4/app/FragmentActivity.java
+++ b/v4/java/android/support/v4/app/FragmentActivity.java
@@ -27,6 +27,7 @@ import android.os.Message;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.v4.media.session.MediaControllerCompat;
import android.support.v4.util.SimpleArrayMap;
import android.util.AttributeSet;
import android.util.Log;
@@ -124,6 +125,8 @@ public class FragmentActivity extends BaseFragmentActivityHoneycomb implements
SimpleArrayMap<String, LoaderManager> loaders;
}
+ MediaControllerCompat mMediaController;
+
// ------------------------------------------------------------------------
// HOOKS INTO ACTIVITY
// ------------------------------------------------------------------------
@@ -169,6 +172,39 @@ public class FragmentActivity extends BaseFragmentActivityHoneycomb implements
}
/**
+ * Sets a {@link MediaControllerCompat} for later retrieval via
+ * {@link #getSupportMediaController()}.
+ *
+ * <p>On API 21 and later, this controller will be tied to the window of the activity and
+ * media key and volume events which are received while the Activity is in the foreground
+ * will be forwarded to the controller and used to invoke transport controls or adjust the
+ * volume. Prior to API 21, the global handling of media key and volume events through an
+ * active {@link android.support.v4.media.session.MediaSessionCompat} and media button receiver
+ * will still be respected.</p>
+ *
+ * @param mediaController The controller for the session which should receive
+ * media keys and volume changes on API 21 and later.
+ * @see #setMediaController(android.media.session.MediaController)
+ */
+ final public void setSupportMediaController(MediaControllerCompat mediaController) {
+ mMediaController = mediaController;
+ if (android.os.Build.VERSION.SDK_INT >= 21) {
+ ActivityCompat21.setMediaController(this, mediaController.getMediaController());
+ }
+ }
+
+ /**
+ * Retrieves the current {@link MediaControllerCompat} for sending media key and volume events.
+ *
+ * @return The controller which should receive events.
+ * @see #setSupportMediaController(android.support.v4.media.session.MediaController)
+ * @see #getMediaController()
+ */
+ final public MediaControllerCompat getSupportMediaController() {
+ return mMediaController;
+ }
+
+ /**
* Reverses the Activity Scene entry Transition and triggers the calling Activity
* to reverse its exit Transition. When the exit Transition completes,
* {@link #finish()} is called. If no entry Transition was used, finish() is called
diff --git a/v4/java/android/support/v4/app/FragmentManager.java b/v4/java/android/support/v4/app/FragmentManager.java
index adf8892a2f..50bc88bc20 100644
--- a/v4/java/android/support/v4/app/FragmentManager.java
+++ b/v4/java/android/support/v4/app/FragmentManager.java
@@ -52,6 +52,7 @@ import android.view.ViewGroup;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -414,8 +415,9 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
static class AnimateOnHWLayerIfNeededListener implements AnimationListener {
+ private AnimationListener mOrignalListener = null;
private boolean mShouldRunOnHWLayer = false;
- private View mView;
+ private View mView = null;
public AnimateOnHWLayerIfNeededListener(final View v, Animation anim) {
if (v == null || anim == null) {
return;
@@ -423,24 +425,38 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
mView = v;
}
+ public AnimateOnHWLayerIfNeededListener(final View v, Animation anim,
+ AnimationListener listener) {
+ if (v == null || anim == null) {
+ return;
+ }
+ mOrignalListener = listener;
+ mView = v;
+ }
+
@Override
@CallSuper
public void onAnimationStart(Animation animation) {
- mShouldRunOnHWLayer = shouldRunOnHWLayer(mView, animation);
- if (mShouldRunOnHWLayer) {
- mView.post(new Runnable() {
- @Override
- public void run() {
- ViewCompat.setLayerType(mView, ViewCompat.LAYER_TYPE_HARDWARE, null);
- }
- });
+ if (mView != null) {
+ mShouldRunOnHWLayer = shouldRunOnHWLayer(mView, animation);
+ if (mShouldRunOnHWLayer) {
+ mView.post(new Runnable() {
+ @Override
+ public void run() {
+ ViewCompat.setLayerType(mView, ViewCompat.LAYER_TYPE_HARDWARE, null);
+ }
+ });
+ }
+ }
+ if (mOrignalListener != null) {
+ mOrignalListener.onAnimationStart(animation);
}
}
@Override
@CallSuper
public void onAnimationEnd(Animation animation) {
- if (mShouldRunOnHWLayer) {
+ if (mView != null && mShouldRunOnHWLayer) {
mView.post(new Runnable() {
@Override
public void run() {
@@ -448,10 +464,16 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
}
});
}
+ if (mOrignalListener != null) {
+ mOrignalListener.onAnimationEnd(animation);
+ }
}
@Override
public void onAnimationRepeat(Animation animation) {
+ if (mOrignalListener != null) {
+ mOrignalListener.onAnimationRepeat(animation);
+ }
}
}
@@ -476,6 +498,8 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
FragmentController mController;
FragmentContainer mContainer;
Fragment mParent;
+
+ static Field sAnimationListenerField = null;
boolean mNeedMenuInvalidate;
boolean mStateSaved;
@@ -509,7 +533,8 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
}
static boolean shouldRunOnHWLayer(View v, Animation anim) {
- return ViewCompat.getLayerType(v) == ViewCompat.LAYER_TYPE_NONE
+ return Build.VERSION.SDK_INT >= 19
+ && ViewCompat.getLayerType(v) == ViewCompat.LAYER_TYPE_NONE
&& ViewCompat.hasOverlappingRendering(v)
&& modifiesAlpha(anim);
}
@@ -914,7 +939,23 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
return;
}
if (shouldRunOnHWLayer(v, anim)) {
- anim.setAnimationListener(new AnimateOnHWLayerIfNeededListener(v, anim));
+ AnimationListener originalListener = null;
+ try {
+ if (sAnimationListenerField == null) {
+ sAnimationListenerField = Animation.class.getDeclaredField("mListener");
+ sAnimationListenerField.setAccessible(true);
+ }
+ originalListener = (AnimationListener) sAnimationListenerField.get(anim);
+ } catch (NoSuchFieldException e) {
+ Log.e(TAG, "No field with the name mListener is found in Animation class", e);
+ } catch (IllegalAccessException e) {
+ Log.e(TAG, "Cannot access Animation's mListener field", e);
+ }
+ // If there's already a listener set on the animation, we need wrap the new listener
+ // around the existing listener, so that they will both get animation listener
+ // callbacks.
+ anim.setAnimationListener(new AnimateOnHWLayerIfNeededListener(v, anim,
+ originalListener));
}
}
diff --git a/v4/java/android/support/v4/app/NotificationCompat.java b/v4/java/android/support/v4/app/NotificationCompat.java
index b206e95243..e23c11c8bd 100644
--- a/v4/java/android/support/v4/app/NotificationCompat.java
+++ b/v4/java/android/support/v4/app/NotificationCompat.java
@@ -2247,7 +2247,7 @@ public class NotificationCompat {
* Size value for use with {@link #setCustomSizePreset} to show this notification with
* default sizing.
* <p>For custom display notifications created using {@link #setDisplayIntent},
- * the default is {@link #SIZE_LARGE}. All other notifications size automatically based
+ * the default is {@link #SIZE_MEDIUM}. All other notifications size automatically based
* on their content.
*/
public static final int SIZE_DEFAULT = 0;
diff --git a/v4/java/android/support/v4/content/ContextCompat.java b/v4/java/android/support/v4/content/ContextCompat.java
index b8029d1b6c..29629e7323 100644
--- a/v4/java/android/support/v4/content/ContextCompat.java
+++ b/v4/java/android/support/v4/content/ContextCompat.java
@@ -403,7 +403,7 @@ public class ContextCompat {
*
* @see android.content.Context.getFilesDir
*/
- public final File getNoBackupFilesDir(Context context) {
+ public static File getNoBackupFilesDir(Context context) {
final int version = Build.VERSION.SDK_INT;
if (version >= 21) {
return ContextCompatApi21.getNoBackupFilesDir(context);
@@ -428,7 +428,7 @@ public class ContextCompat {
*
* @return The path of the directory holding application code cache files.
*/
- public final File getCodeCacheDir(Context context) {
+ public static File getCodeCacheDir(Context context) {
final int version = Build.VERSION.SDK_INT;
if (version >= 21) {
return ContextCompatApi21.getCodeCacheDir(context);
diff --git a/v4/java/android/support/v4/content/ParallelExecutorCompat.java b/v4/java/android/support/v4/content/ParallelExecutorCompat.java
new file mode 100644
index 0000000000..c23470b46b
--- /dev/null
+++ b/v4/java/android/support/v4/content/ParallelExecutorCompat.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 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.support.v4.content;
+
+import android.os.Build;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Helper for accessing a shared parallel Executor instance
+ * introduced after API level 4 in a backwards compatible fashion.
+ */
+public class ParallelExecutorCompat {
+ public static Executor getParallelExecutor() {
+ if (Build.VERSION.SDK_INT >= 11) {
+ // From API 11 onwards, return AsyncTask.THREAD_POOL_EXECUTOR
+ return ExecutorCompatHoneycomb.getParallelExecutor();
+ } else {
+ return ModernAsyncTask.THREAD_POOL_EXECUTOR;
+ }
+ }
+}
diff --git a/v4/java/android/support/v4/content/res/ResourcesCompat.java b/v4/java/android/support/v4/content/res/ResourcesCompat.java
index 252977b4a8..ce5f658c09 100644
--- a/v4/java/android/support/v4/content/res/ResourcesCompat.java
+++ b/v4/java/android/support/v4/content/res/ResourcesCompat.java
@@ -16,11 +16,18 @@
package android.support.v4.content.res;
+import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.content.res.Resources.Theme;
import android.graphics.drawable.Drawable;
-import android.os.Build;
+import android.support.annotation.ColorInt;
+import android.support.annotation.ColorRes;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import static android.os.Build.VERSION.SDK_INT;
/**
* Helper for accessing features in {@link android.content.res.Resources}
@@ -45,11 +52,11 @@ public class ResourcesCompat {
* @throws NotFoundException Throws NotFoundException if the given ID does
* not exist.
*/
+ @Nullable
@SuppressWarnings("deprecation")
- public static Drawable getDrawable(Resources res, int id, Theme theme)
- throws NotFoundException {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 21) {
+ public static Drawable getDrawable(@NonNull Resources res, @DrawableRes int id,
+ @Nullable Theme theme) throws NotFoundException {
+ if (SDK_INT >= 21) {
return ResourcesCompatApi21.getDrawable(res, id, theme);
} else {
return res.getDrawable(id);
@@ -65,7 +72,7 @@ public class ResourcesCompat {
* this method simply calls through to {@link Resources#getDrawable(int)}.
* <p>
* Prior to API level 21, the theme will not be applied and this method
- * calls through to Resources.getDrawableForDensity(int, int).
+ * calls through to Resources#getDrawableForDensity(int, int).
*
* @param id The desired resource identifier, as generated by the aapt
* tool. This integer encodes the package, type, and resource
@@ -76,18 +83,76 @@ public class ResourcesCompat {
* {@code null}.
* @return Drawable An object that can be used to draw this resource.
* @throws NotFoundException Throws NotFoundException if the given ID does
- * not exist.
+ * not exist.
*/
+ @Nullable
@SuppressWarnings("deprecation")
- public static Drawable getDrawableForDensity(Resources res, int id, int density, Theme theme)
- throws NotFoundException {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 21) {
+ public static Drawable getDrawableForDensity(@NonNull Resources res, @DrawableRes int id,
+ int density, @Nullable Theme theme) throws NotFoundException {
+ if (SDK_INT >= 21) {
return ResourcesCompatApi21.getDrawableForDensity(res, id, density, theme);
- } else if (version >= 15) {
+ } else if (SDK_INT >= 15) {
return ResourcesCompatIcsMr1.getDrawableForDensity(res, id, density);
} else {
return res.getDrawable(id);
}
}
+
+ /**
+ * Returns a themed color integer associated with a particular resource ID.
+ * If the resource holds a complex {@link ColorStateList}, then the default
+ * color from the set is returned.
+ * <p>
+ * Prior to API level 23, the theme will not be applied and this method
+ * calls through to {@link Resources#getColor(int)}.
+ *
+ * @param id The desired resource identifier, as generated by the aapt
+ * tool. This integer encodes the package, type, and resource
+ * entry. The value 0 is an invalid identifier.
+ * @param theme The theme used to style the color attributes, may be
+ * {@code null}.
+ * @return A single color value in the form {@code 0xAARRGGBB}.
+ * @throws NotFoundException Throws NotFoundException if the given ID does
+ * not exist.
+ */
+ @ColorInt
+ @SuppressWarnings("deprecation")
+ public static int getColor(@NonNull Resources res, @ColorRes int id, @Nullable Theme theme)
+ throws NotFoundException {
+ if (SDK_INT >= 23) {
+ return ResourcesCompatApi23.getColor(res, id, theme);
+ } else {
+ return res.getColor(id);
+ }
+ }
+
+ /**
+ * Returns a themed color state list associated with a particular resource
+ * ID. The resource may contain either a single raw color value or a
+ * complex {@link ColorStateList} holding multiple possible colors.
+ * <p>
+ * Prior to API level 23, the theme will not be applied and this method
+ * calls through to {@link Resources#getColorStateList(int)}.
+ *
+ * @param id The desired resource identifier of a {@link ColorStateList},
+ * as generated by the aapt tool. This integer encodes the
+ * package, type, and resource entry. The value 0 is an invalid
+ * identifier.
+ * @param theme The theme used to style the color attributes, may be
+ * {@code null}.
+ * @return A themed ColorStateList object containing either a single solid
+ * color or multiple colors that can be selected based on a state.
+ * @throws NotFoundException Throws NotFoundException if the given ID does
+ * not exist.
+ */
+ @Nullable
+ @SuppressWarnings("deprecation")
+ public static ColorStateList getColorStateList(@NonNull Resources res, @ColorRes int id,
+ @Nullable Theme theme) throws NotFoundException {
+ if (SDK_INT >= 23) {
+ return ResourcesCompatApi23.getColorStateList(res, id, theme);
+ } else {
+ return res.getColorStateList(id);
+ }
+ }
}
diff --git a/v4/java/android/support/v4/graphics/ColorUtils.java b/v4/java/android/support/v4/graphics/ColorUtils.java
index aac809bcea..4d9d9b279b 100644
--- a/v4/java/android/support/v4/graphics/ColorUtils.java
+++ b/v4/java/android/support/v4/graphics/ColorUtils.java
@@ -17,6 +17,10 @@
package android.support.v4.graphics;
import android.graphics.Color;
+import android.support.annotation.ColorInt;
+import android.support.annotation.FloatRange;
+import android.support.annotation.IntRange;
+import android.support.annotation.NonNull;
/**
* A set of color-related utility methods, building upon those available in {@code Color}.
@@ -24,14 +28,14 @@ import android.graphics.Color;
public class ColorUtils {
private static final int MIN_ALPHA_SEARCH_MAX_ITERATIONS = 10;
- private static final int MIN_ALPHA_SEARCH_PRECISION = 10;
+ private static final int MIN_ALPHA_SEARCH_PRECISION = 1;
private ColorUtils() {}
/**
* Composite two potentially translucent colors over each other and returns the result.
*/
- public static int compositeColors(int foreground, int background) {
+ public static int compositeColors(@ColorInt int foreground, @ColorInt int background) {
int bgAlpha = Color.alpha(background);
int fgAlpha = Color.alpha(foreground);
int a = compositeAlpha(fgAlpha, bgAlpha);
@@ -57,10 +61,13 @@ public class ColorUtils {
/**
* Returns the luminance of a color.
- *
- * Formula defined here: http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
+ * <p>
+ * Formula defined
+ * <a href="http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef">here</a>.
+ * </p>
*/
- public static double calculateLuminance(int color) {
+ @FloatRange(from = 0.0, to = 1.0)
+ public static double calculateLuminance(@ColorInt int color) {
double red = Color.red(color) / 255d;
red = red < 0.03928 ? red / 12.92 : Math.pow((red + 0.055) / 1.055, 2.4);
@@ -80,9 +87,10 @@ public class ColorUtils {
* Formula defined
* <a href="http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef">here</a>.
*/
- public static double calculateContrast(int foreground, int background) {
+ public static double calculateContrast(@ColorInt int foreground, @ColorInt int background) {
if (Color.alpha(background) != 255) {
- throw new IllegalArgumentException("background can not be translucent");
+ throw new IllegalArgumentException("background can not be translucent: #"
+ + Integer.toHexString(background));
}
if (Color.alpha(foreground) < 255) {
// If the foreground is translucent, composite the foreground over the background
@@ -106,10 +114,11 @@ public class ColorUtils {
* @param minContrastRatio the minimum contrast ratio.
* @return the alpha value in the range 0-255, or -1 if no value could be calculated.
*/
- public static int calculateMinimumAlpha(int foreground, int background,
+ public static int calculateMinimumAlpha(@ColorInt int foreground, @ColorInt int background,
float minContrastRatio) {
if (Color.alpha(background) != 255) {
- throw new IllegalArgumentException("background can not be translucent");
+ throw new IllegalArgumentException("background can not be translucent: #"
+ + Integer.toHexString(background));
}
// First lets check that a fully opaque foreground has sufficient contrast
@@ -158,7 +167,9 @@ public class ColorUtils {
* @param b blue component value [0..255]
* @param hsl 3 element array which holds the resulting HSL components.
*/
- public static void RGBToHSL(int r, int g, int b, float[] hsl) {
+ public static void RGBToHSL(@IntRange(from = 0x0, to = 0xFF) int r,
+ @IntRange(from = 0x0, to = 0xFF) int g, @IntRange(from = 0x0, to = 0xFF) int b,
+ @NonNull float[] hsl) {
final float rf = r / 255f;
final float gf = g / 255f;
final float bf = b / 255f;
@@ -206,7 +217,7 @@ public class ColorUtils {
* @param color the ARGB color to convert. The alpha component is ignored.
* @param hsl 3 element array which holds the resulting HSL components.
*/
- public static void colorToHSL(int color, float[] hsl) {
+ public static void colorToHSL(@ColorInt int color, @NonNull float[] hsl) {
RGBToHSL(Color.red(color), Color.green(color), Color.blue(color), hsl);
}
@@ -222,7 +233,8 @@ public class ColorUtils {
* @param hsl 3 element array which holds the input HSL components.
* @return the resulting RGB color
*/
- public static int HSLToColor(float[] hsl) {
+ @ColorInt
+ public static int HSLToColor(@NonNull float[] hsl) {
final float h = hsl[0];
final float s = hsl[1];
final float l = hsl[2];
@@ -279,7 +291,9 @@ public class ColorUtils {
/**
* Set the alpha component of {@code color} to be {@code alpha}.
*/
- public static int setAlphaComponent(int color, int alpha) {
+ @ColorInt
+ public static int setAlphaComponent(@ColorInt int color,
+ @IntRange(from = 0x0, to = 0xFF) int alpha) {
if (alpha < 0 || alpha > 255) {
throw new IllegalArgumentException("alpha must be between 0 and 255.");
}
diff --git a/v4/java/android/support/v4/graphics/drawable/DrawableCompat.java b/v4/java/android/support/v4/graphics/drawable/DrawableCompat.java
index 88b5f4a6c6..64ae075a00 100644
--- a/v4/java/android/support/v4/graphics/drawable/DrawableCompat.java
+++ b/v4/java/android/support/v4/graphics/drawable/DrawableCompat.java
@@ -123,7 +123,7 @@ public class DrawableCompat {
@Override
public int getLayoutDirection(Drawable drawable) {
final int dir = DrawableCompatJellybeanMr1.getLayoutDirection(drawable);
- return dir < 0 ? dir : ViewCompat.LAYOUT_DIRECTION_LTR;
+ return dir >= 0 ? dir : ViewCompat.LAYOUT_DIRECTION_LTR;
}
}
diff --git a/v4/java/android/support/v4/media/MediaBrowserCompat.java b/v4/java/android/support/v4/media/MediaBrowserCompat.java
new file mode 100644
index 0000000000..dcce7f57c2
--- /dev/null
+++ b/v4/java/android/support/v4/media/MediaBrowserCompat.java
@@ -0,0 +1,1243 @@
+/*
+ * Copyright (C) 2015 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.support.v4.media;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.support.annotation.IntDef;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.app.BundleCompat;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.MediaSessionCompat;
+import android.support.v4.os.ResultReceiver;
+import android.support.v4.util.ArrayMap;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+
+import static android.support.v4.media.MediaBrowserProtocol.*;
+
+/**
+ * Browses media content offered by a {@link MediaBrowserServiceCompat}.
+ * <p>
+ * This object is not thread-safe. All calls should happen on the thread on which the browser
+ * was constructed.
+ * </p>
+ */
+public final class MediaBrowserCompat {
+ private static final String TAG = "MediaBrowserCompat";
+
+ private final MediaBrowserImpl mImpl;
+
+ /**
+ * Creates a media browser for the specified media browse service.
+ *
+ * @param context The context.
+ * @param serviceComponent The component name of the media browse service.
+ * @param callback The connection callback.
+ * @param rootHints An optional bundle of service-specific arguments to send
+ * to the media browse service when connecting and retrieving the root id
+ * for browsing, or null if none. The contents of this bundle may affect
+ * the information returned when browsing.
+ */
+ public MediaBrowserCompat(Context context, ComponentName serviceComponent,
+ ConnectionCallback callback, Bundle rootHints) {
+ if (android.os.Build.VERSION.SDK_INT >= 23) {
+ mImpl = new MediaBrowserImplApi23(context, serviceComponent, callback, rootHints);
+ } else if (android.os.Build.VERSION.SDK_INT >= 21) {
+ mImpl = new MediaBrowserImplApi21(context, serviceComponent, callback, rootHints);
+ } else {
+ mImpl = new MediaBrowserImplBase(context, serviceComponent, callback, rootHints);
+ }
+ }
+
+ /**
+ * Connects to the media browse service.
+ * <p>
+ * The connection callback specified in the constructor will be invoked
+ * when the connection completes or fails.
+ * </p>
+ */
+ public void connect() {
+ mImpl.connect();
+ }
+
+ /**
+ * Disconnects from the media browse service.
+ * After this, no more callbacks will be received.
+ */
+ public void disconnect() {
+ mImpl.disconnect();
+ }
+
+ /**
+ * Returns whether the browser is connected to the service.
+ */
+ public boolean isConnected() {
+ return mImpl.isConnected();
+ }
+
+ /**
+ * Gets the service component that the media browser is connected to.
+ */
+ public @NonNull
+ ComponentName getServiceComponent() {
+ return mImpl.getServiceComponent();
+ }
+
+ /**
+ * Gets the root id.
+ * <p>
+ * Note that the root id may become invalid or change when when the
+ * browser is disconnected.
+ * </p>
+ *
+ * @throws IllegalStateException if not connected.
+ */
+ public @NonNull String getRoot() {
+ return mImpl.getRoot();
+ }
+
+ /**
+ * Gets any extras for the media service.
+ *
+ * @throws IllegalStateException if not connected.
+ */
+ public @Nullable
+ Bundle getExtras() {
+ return mImpl.getExtras();
+ }
+
+ /**
+ * Gets the media session token associated with the media browser.
+ * <p>
+ * Note that the session token may become invalid or change when when the
+ * browser is disconnected.
+ * </p>
+ *
+ * @return The session token for the browser, never null.
+ *
+ * @throws IllegalStateException if not connected.
+ */
+ public @NonNull MediaSessionCompat.Token getSessionToken() {
+ return mImpl.getSessionToken();
+ }
+
+ /**
+ * Queries for information about the media items that are contained within
+ * the specified id and subscribes to receive updates when they change.
+ * <p>
+ * The list of subscriptions is maintained even when not connected and is
+ * restored after reconnection. It is ok to subscribe while not connected
+ * but the results will not be returned until the connection completes.
+ * </p>
+ * <p>
+ * If the id is already subscribed with a different callback then the new
+ * callback will replace the previous one and the child data will be
+ * reloaded.
+ * </p>
+ *
+ * @param parentId The id of the parent media item whose list of children
+ * will be subscribed.
+ * @param callback The callback to receive the list of children.
+ */
+ public void subscribe(@NonNull String parentId, @NonNull SubscriptionCallback callback) {
+ mImpl.subscribe(parentId, callback);
+ }
+
+ /**
+ * Unsubscribes for changes to the children of the specified media id.
+ * <p>
+ * The query callback will no longer be invoked for results associated with
+ * this id once this method returns.
+ * </p>
+ *
+ * @param parentId The id of the parent media item whose list of children
+ * will be unsubscribed.
+ */
+ public void unsubscribe(@NonNull String parentId) {
+ mImpl.unsubscribe(parentId);
+ }
+
+ /**
+ * Retrieves a specific {@link MediaItem} from the connected service. Not
+ * all services may support this, so falling back to subscribing to the
+ * parent's id should be used when unavailable.
+ *
+ * @param mediaId The id of the item to retrieve.
+ * @param cb The callback to receive the result on.
+ */
+ public void getItem(final @NonNull String mediaId, @NonNull final ItemCallback cb) {
+ mImpl.getItem(mediaId, cb);
+ }
+
+ public static class MediaItem implements Parcelable {
+ private final int mFlags;
+ private final MediaDescriptionCompat mDescription;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag=true, value = { FLAG_BROWSABLE, FLAG_PLAYABLE })
+ public @interface Flags { }
+
+ /**
+ * Flag: Indicates that the item has children of its own.
+ */
+ public static final int FLAG_BROWSABLE = 1 << 0;
+
+ /**
+ * Flag: Indicates that the item is playable.
+ * <p>
+ * The id of this item may be passed to
+ * {@link MediaControllerCompat.TransportControls#playFromMediaId(String, Bundle)}
+ * to start playing it.
+ * </p>
+ */
+ public static final int FLAG_PLAYABLE = 1 << 1;
+
+ /**
+ * Create a new MediaItem for use in browsing media.
+ * @param description The description of the media, which must include a
+ * media id.
+ * @param flags The flags for this item.
+ */
+ public MediaItem(@NonNull MediaDescriptionCompat description, @Flags int flags) {
+ if (description == null) {
+ throw new IllegalArgumentException("description cannot be null");
+ }
+ if (TextUtils.isEmpty(description.getMediaId())) {
+ throw new IllegalArgumentException("description must have a non-empty media id");
+ }
+ mFlags = flags;
+ mDescription = description;
+ }
+
+ /**
+ * Private constructor.
+ */
+ private MediaItem(Parcel in) {
+ mFlags = in.readInt();
+ mDescription = MediaDescriptionCompat.CREATOR.createFromParcel(in);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(mFlags);
+ mDescription.writeToParcel(out, flags);
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("MediaItem{");
+ sb.append("mFlags=").append(mFlags);
+ sb.append(", mDescription=").append(mDescription);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ public static final Parcelable.Creator<MediaItem> CREATOR =
+ new Parcelable.Creator<MediaItem>() {
+ @Override
+ public MediaItem createFromParcel(Parcel in) {
+ return new MediaItem(in);
+ }
+
+ @Override
+ public MediaItem[] newArray(int size) {
+ return new MediaItem[size];
+ }
+ };
+
+ /**
+ * Gets the flags of the item.
+ */
+ public @Flags int getFlags() {
+ return mFlags;
+ }
+
+ /**
+ * Returns whether this item is browsable.
+ * @see #FLAG_BROWSABLE
+ */
+ public boolean isBrowsable() {
+ return (mFlags & FLAG_BROWSABLE) != 0;
+ }
+
+ /**
+ * Returns whether this item is playable.
+ * @see #FLAG_PLAYABLE
+ */
+ public boolean isPlayable() {
+ return (mFlags & FLAG_PLAYABLE) != 0;
+ }
+
+ /**
+ * Returns the description of the media.
+ */
+ public @NonNull MediaDescriptionCompat getDescription() {
+ return mDescription;
+ }
+
+ /**
+ * Returns the media id for this item.
+ */
+ public @NonNull String getMediaId() {
+ return mDescription.getMediaId();
+ }
+ }
+
+
+ /**
+ * Callbacks for connection related events.
+ */
+ public static class ConnectionCallback {
+ final Object mConnectionCallbackObj;
+
+ public ConnectionCallback() {
+ if (android.os.Build.VERSION.SDK_INT >= 21) {
+ mConnectionCallbackObj =
+ MediaBrowserCompatApi21.createConnectionCallback(new StubApi21());
+ } else {
+ mConnectionCallbackObj = null;
+ }
+ }
+
+ /**
+ * Invoked after {@link MediaBrowserCompat#connect()} when the request has successfully
+ * completed.
+ */
+ public void onConnected() {
+ }
+
+ /**
+ * Invoked when the client is disconnected from the media browser.
+ */
+ public void onConnectionSuspended() {
+ }
+
+ /**
+ * Invoked when the connection to the media browser failed.
+ */
+ public void onConnectionFailed() {
+ }
+
+
+ private class StubApi21 implements MediaBrowserCompatApi21.ConnectionCallback {
+ @Override
+ public void onConnected() {
+ ConnectionCallback.this.onConnected();
+ }
+
+ @Override
+ public void onConnectionSuspended() {
+ ConnectionCallback.this.onConnectionSuspended();
+ }
+
+ @Override
+ public void onConnectionFailed() {
+ ConnectionCallback.this.onConnectionFailed();
+ }
+ }
+ }
+
+ /**
+ * Callbacks for subscription related events.
+ */
+ public static abstract class SubscriptionCallback {
+ final Object mSubscriptionCallbackObj;
+
+ public SubscriptionCallback() {
+ if (android.os.Build.VERSION.SDK_INT >= 21) {
+ mSubscriptionCallbackObj =
+ MediaBrowserCompatApi21.createSubscriptionCallback(new StubApi21());
+ } else {
+ mSubscriptionCallbackObj = null;
+ }
+ }
+
+ /**
+ * Called when the list of children is loaded or updated.
+ *
+ * @param parentId The media id of the parent media item.
+ * @param children The children which were loaded, or null if the id is invalid.
+ */
+ public void onChildrenLoaded(@NonNull String parentId, List<MediaItem> children) {
+ }
+
+ /**
+ * Called when the id doesn't exist or other errors in subscribing.
+ * <p>
+ * If this is called, the subscription remains until {@link MediaBrowserCompat#unsubscribe}
+ * called, because some errors may heal themselves.
+ * </p>
+ *
+ * @param parentId The media id of the parent media item whose children could
+ * not be loaded.
+ */
+ public void onError(@NonNull String parentId) {
+ }
+
+ private class StubApi21 implements MediaBrowserCompatApi21.SubscriptionCallback {
+ @Override
+ public void onChildrenLoaded(@NonNull String parentId, @NonNull List<Parcel> children) {
+ List<MediaBrowserCompat.MediaItem> mediaItems = null;
+ if (children != null) {
+ mediaItems = new ArrayList<>();
+ for (Parcel parcel : children) {
+ parcel.setDataPosition(0);
+ mediaItems.add(
+ MediaBrowserCompat.MediaItem.CREATOR.createFromParcel(parcel));
+ parcel.recycle();
+ }
+ }
+ SubscriptionCallback.this.onChildrenLoaded(parentId, mediaItems);
+ }
+
+ @Override
+ public void onError(@NonNull String parentId) {
+ SubscriptionCallback.this.onError(parentId);
+ }
+ }
+ }
+
+ /**
+ * Callback for receiving the result of {@link #getItem}.
+ */
+ public static abstract class ItemCallback {
+ final Object mItemCallbackObj;
+
+ public ItemCallback() {
+ if (android.os.Build.VERSION.SDK_INT >= 23) {
+ mItemCallbackObj = MediaBrowserCompatApi23.createItemCallback(new StubApi23());
+ } else {
+ mItemCallbackObj = null;
+ }
+ }
+
+ /**
+ * Called when the item has been returned by the browser service.
+ *
+ * @param item The item that was returned or null if it doesn't exist.
+ */
+ public void onItemLoaded(MediaItem item) {
+ }
+
+ /**
+ * Called when the item doesn't exist or there was an error retrieving it.
+ *
+ * @param itemId The media id of the media item which could not be loaded.
+ */
+ public void onError(@NonNull String itemId) {
+ }
+
+ private class StubApi23 implements MediaBrowserCompatApi23.ItemCallback {
+ @Override
+ public void onItemLoaded(Parcel itemParcel) {
+ itemParcel.setDataPosition(0);
+ MediaItem item = MediaBrowserCompat.MediaItem.CREATOR.createFromParcel(itemParcel);
+ itemParcel.recycle();
+ ItemCallback.this.onItemLoaded(item);
+ }
+
+ @Override
+ public void onError(@NonNull String itemId) {
+ ItemCallback.this.onError(itemId);
+ }
+ }
+ }
+
+ interface MediaBrowserImpl {
+ void connect();
+ void disconnect();
+ boolean isConnected();
+ ComponentName getServiceComponent();
+ @NonNull String getRoot();
+ @Nullable Bundle getExtras();
+ @NonNull MediaSessionCompat.Token getSessionToken();
+ void subscribe(@NonNull String parentId, @NonNull SubscriptionCallback callback);
+ void unsubscribe(@NonNull String parentId);
+ void getItem(final @NonNull String mediaId, @NonNull final ItemCallback cb);
+ }
+
+ static class MediaBrowserImplBase implements MediaBrowserImpl {
+ private static final boolean DBG = false;
+
+ private static final int CONNECT_STATE_DISCONNECTED = 0;
+ private static final int CONNECT_STATE_CONNECTING = 1;
+ private static final int CONNECT_STATE_CONNECTED = 2;
+ private static final int CONNECT_STATE_SUSPENDED = 3;
+
+ private final Context mContext;
+ private final ComponentName mServiceComponent;
+ private final ConnectionCallback mCallback;
+ private final Bundle mRootHints;
+ private final CallbackHandler mHandler = new CallbackHandler();
+ private final ArrayMap<String,Subscription> mSubscriptions = new ArrayMap<>();
+
+ private int mState = CONNECT_STATE_DISCONNECTED;
+ private MediaServiceConnection mServiceConnection;
+ private ServiceBinderWrapper mServiceBinderWrapper;
+ private Messenger mCallbacksMessenger;
+ private String mRootId;
+ private MediaSessionCompat.Token mMediaSessionToken;
+ private Bundle mExtras;
+
+ public MediaBrowserImplBase(Context context, ComponentName serviceComponent,
+ ConnectionCallback callback, Bundle rootHints) {
+ if (context == null) {
+ throw new IllegalArgumentException("context must not be null");
+ }
+ if (serviceComponent == null) {
+ throw new IllegalArgumentException("service component must not be null");
+ }
+ if (callback == null) {
+ throw new IllegalArgumentException("connection callback must not be null");
+ }
+ mContext = context;
+ mServiceComponent = serviceComponent;
+ mCallback = callback;
+ mRootHints = rootHints;
+ }
+
+ public void connect() {
+ if (mState != CONNECT_STATE_DISCONNECTED) {
+ throw new IllegalStateException("connect() called while not disconnected (state="
+ + getStateLabel(mState) + ")");
+ }
+ // TODO: remove this extra check.
+ if (DBG) {
+ if (mServiceConnection != null) {
+ throw new RuntimeException("mServiceConnection should be null. Instead it is "
+ + mServiceConnection);
+ }
+ }
+ if (mServiceBinderWrapper != null) {
+ throw new RuntimeException("mServiceBinderWrapper should be null. Instead it is "
+ + mServiceBinderWrapper);
+ }
+ if (mCallbacksMessenger != null) {
+ throw new RuntimeException("mCallbacksMessenger should be null. Instead it is "
+ + mCallbacksMessenger);
+ }
+
+ mState = CONNECT_STATE_CONNECTING;
+
+ final Intent intent = new Intent(MediaBrowserServiceCompat.SERVICE_INTERFACE);
+ intent.setComponent(mServiceComponent);
+
+ final ServiceConnection thisConnection = mServiceConnection =
+ new MediaServiceConnection();
+
+ boolean bound = false;
+ try {
+ bound = mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
+ } catch (Exception ex) {
+ Log.e(TAG, "Failed binding to service " + mServiceComponent);
+ }
+
+ if (!bound) {
+ // Tell them that it didn't work. We are already on the main thread,
+ // but we don't want to do callbacks inside of connect(). So post it,
+ // and then check that we are on the same ServiceConnection. We know
+ // we won't also get an onServiceConnected or onServiceDisconnected,
+ // so we won't be doing double callbacks.
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ // Ensure that nobody else came in or tried to connect again.
+ if (thisConnection == mServiceConnection) {
+ forceCloseConnection();
+ mCallback.onConnectionFailed();
+ }
+ }
+ });
+ }
+
+ if (DBG) {
+ Log.d(TAG, "connect...");
+ dump();
+ }
+ }
+
+ public void disconnect() {
+ // It's ok to call this any state, because allowing this lets apps not have
+ // to check isConnected() unnecessarily. They won't appreciate the extra
+ // assertions for this. We do everything we can here to go back to a sane state.
+ if (mCallbacksMessenger != null) {
+ try {
+ mServiceBinderWrapper.disconnect();
+ } catch (RemoteException ex) {
+ // We are disconnecting anyway. Log, just for posterity but it's not
+ // a big problem.
+ Log.w(TAG, "RemoteException during connect for " + mServiceComponent);
+ }
+ }
+ forceCloseConnection();
+
+ if (DBG) {
+ Log.d(TAG, "disconnect...");
+ dump();
+ }
+ }
+
+ /**
+ * Null out the variables and unbind from the service. This doesn't include
+ * calling disconnect on the service, because we only try to do that in the
+ * clean shutdown cases.
+ * <p>
+ * Everywhere that calls this EXCEPT for disconnect() should follow it with
+ * a call to mCallback.onConnectionFailed(). Disconnect doesn't do that callback
+ * for a clean shutdown, but everywhere else is a dirty shutdown and should
+ * notify the app.
+ */
+ private void forceCloseConnection() {
+ if (mServiceConnection != null) {
+ mContext.unbindService(mServiceConnection);
+ }
+ mState = CONNECT_STATE_DISCONNECTED;
+ mServiceConnection = null;
+ mServiceBinderWrapper = null;
+ mCallbacksMessenger = null;
+ mRootId = null;
+ mMediaSessionToken = null;
+ }
+
+ public boolean isConnected() {
+ return mState == CONNECT_STATE_CONNECTED;
+ }
+
+ public @NonNull
+ ComponentName getServiceComponent() {
+ if (!isConnected()) {
+ throw new IllegalStateException("getServiceComponent() called while not connected" +
+ " (state=" + mState + ")");
+ }
+ return mServiceComponent;
+ }
+
+ public @NonNull String getRoot() {
+ if (!isConnected()) {
+ throw new IllegalStateException("getRoot() called while not connected"
+ + "(state=" + getStateLabel(mState) + ")");
+ }
+ return mRootId;
+ }
+
+ public @Nullable
+ Bundle getExtras() {
+ if (!isConnected()) {
+ throw new IllegalStateException("getExtras() called while not connected (state="
+ + getStateLabel(mState) + ")");
+ }
+ return mExtras;
+ }
+
+ public @NonNull MediaSessionCompat.Token getSessionToken() {
+ if (!isConnected()) {
+ throw new IllegalStateException("getSessionToken() called while not connected"
+ + "(state=" + mState + ")");
+ }
+ return mMediaSessionToken;
+ }
+
+ public void subscribe(@NonNull String parentId, @NonNull SubscriptionCallback callback) {
+ // Check arguments.
+ if (parentId == null) {
+ throw new IllegalArgumentException("parentId is null");
+ }
+ if (callback == null) {
+ throw new IllegalArgumentException("callback is null");
+ }
+
+ // Update or create the subscription.
+ Subscription sub = mSubscriptions.get(parentId);
+ boolean newSubscription = sub == null;
+ if (newSubscription) {
+ sub = new Subscription(parentId);
+ mSubscriptions.put(parentId, sub);
+ }
+ sub.callback = callback;
+
+ // If we are connected, tell the service that we are watching. If we aren't
+ // connected, the service will be told when we connect.
+ if (mState == CONNECT_STATE_CONNECTED) {
+ try {
+ mServiceBinderWrapper.addSubscription(parentId);
+ } catch (RemoteException ex) {
+ // Process is crashing. We will disconnect, and upon reconnect we will
+ // automatically reregister. So nothing to do here.
+ Log.d(TAG, "addSubscription failed with RemoteException parentId=" + parentId);
+ }
+ }
+ }
+
+ public void unsubscribe(@NonNull String parentId) {
+ // Check arguments.
+ if (TextUtils.isEmpty(parentId)) {
+ throw new IllegalArgumentException("parentId is empty.");
+ }
+
+ // Remove from our list.
+ final Subscription sub = mSubscriptions.remove(parentId);
+
+ // Tell the service if necessary.
+ if (mState == CONNECT_STATE_CONNECTED && sub != null) {
+ try {
+ mServiceBinderWrapper.removeSubscription(parentId);
+ } catch (RemoteException ex) {
+ // Process is crashing. We will disconnect, and upon reconnect we will
+ // automatically reregister. So nothing to do here.
+ Log.d(TAG, "removeSubscription failed with RemoteException parentId="
+ + parentId);
+ }
+ }
+ }
+
+ public void getItem(final @NonNull String mediaId, @NonNull final ItemCallback cb) {
+ if (TextUtils.isEmpty(mediaId)) {
+ throw new IllegalArgumentException("mediaId is empty.");
+ }
+ if (cb == null) {
+ throw new IllegalArgumentException("cb is null.");
+ }
+ if (mState != CONNECT_STATE_CONNECTED) {
+ Log.i(TAG, "Not connected, unable to retrieve the MediaItem.");
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ cb.onError(mediaId);
+ }
+ });
+ return;
+ }
+ ResultReceiver receiver = new ResultReceiver(mHandler) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (resultCode != 0 || resultData == null
+ || !resultData.containsKey(MediaBrowserServiceCompat.KEY_MEDIA_ITEM)) {
+ cb.onError(mediaId);
+ return;
+ }
+ Parcelable item =
+ resultData.getParcelable(MediaBrowserServiceCompat.KEY_MEDIA_ITEM);
+ if (!(item instanceof MediaItem)) {
+ cb.onError(mediaId);
+ return;
+ }
+ cb.onItemLoaded((MediaItem)item);
+ }
+ };
+ try {
+ mServiceBinderWrapper.getMediaItem(mediaId, receiver);
+ } catch (RemoteException e) {
+ Log.i(TAG, "Remote error getting media item.");
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ cb.onError(mediaId);
+ }
+ });
+ }
+ }
+
+ /**
+ * For debugging.
+ */
+ private static String getStateLabel(int state) {
+ switch (state) {
+ case CONNECT_STATE_DISCONNECTED:
+ return "CONNECT_STATE_DISCONNECTED";
+ case CONNECT_STATE_CONNECTING:
+ return "CONNECT_STATE_CONNECTING";
+ case CONNECT_STATE_CONNECTED:
+ return "CONNECT_STATE_CONNECTED";
+ case CONNECT_STATE_SUSPENDED:
+ return "CONNECT_STATE_SUSPENDED";
+ default:
+ return "UNKNOWN/" + state;
+ }
+ }
+
+ private final void onServiceConnected(final Messenger callback, final String root,
+ final MediaSessionCompat.Token session, final Bundle extra) {
+ // Check to make sure there hasn't been a disconnect or a different ServiceConnection.
+ if (!isCurrent(callback, "onConnect")) {
+ return;
+ }
+ // Don't allow them to call us twice.
+ if (mState != CONNECT_STATE_CONNECTING) {
+ Log.w(TAG, "onConnect from service while mState=" + getStateLabel(mState)
+ + "... ignoring");
+ return;
+ }
+ mRootId = root;
+ mMediaSessionToken = session;
+ mExtras = extra;
+ mState = CONNECT_STATE_CONNECTED;
+
+ if (DBG) {
+ Log.d(TAG, "ServiceCallbacks.onConnect...");
+ dump();
+ }
+ mCallback.onConnected();
+
+ // we may receive some subscriptions before we are connected, so re-subscribe
+ // everything now
+ for (String id : mSubscriptions.keySet()) {
+ try {
+ mServiceBinderWrapper.addSubscription(id);
+ } catch (RemoteException ex) {
+ // Process is crashing. We will disconnect, and upon reconnect we will
+ // automatically reregister. So nothing to do here.
+ Log.d(TAG, "addSubscription failed with RemoteException parentId=" + id);
+ }
+ }
+ }
+
+ private final void onConnectionFailed(final Messenger callback) {
+ Log.e(TAG, "onConnectFailed for " + mServiceComponent);
+
+ // Check to make sure there hasn't been a disconnect or a different ServiceConnection.
+ if (!isCurrent(callback, "onConnectFailed")) {
+ return;
+ }
+ // Don't allow them to call us twice.
+ if (mState != CONNECT_STATE_CONNECTING) {
+ Log.w(TAG, "onConnect from service while mState=" + getStateLabel(mState)
+ + "... ignoring");
+ return;
+ }
+
+ // Clean up
+ forceCloseConnection();
+
+ // Tell the app.
+ mCallback.onConnectionFailed();
+ }
+
+ private final void onLoadChildren(final Messenger callback, final String parentId,
+ final List list) {
+ // Check that there hasn't been a disconnect or a different ServiceConnection.
+ if (!isCurrent(callback, "onLoadChildren")) {
+ return;
+ }
+
+ List<MediaItem> data = list;
+ if (DBG) {
+ Log.d(TAG, "onLoadChildren for " + mServiceComponent + " id=" + parentId);
+ }
+
+ // Check that the subscription is still subscribed.
+ final Subscription subscription = mSubscriptions.get(parentId);
+ if (subscription == null) {
+ if (DBG) {
+ Log.d(TAG, "onLoadChildren for id that isn't subscribed id=" + parentId);
+ }
+ return;
+ }
+
+ // Tell the app.
+ subscription.callback.onChildrenLoaded(parentId, data);
+ }
+
+ /**
+ * Return true if {@code callback} is the current ServiceCallbacks. Also logs if it's not.
+ */
+ private boolean isCurrent(Messenger callback, String funcName) {
+ if (mCallbacksMessenger != callback) {
+ if (mState != CONNECT_STATE_DISCONNECTED) {
+ Log.i(TAG, funcName + " for " + mServiceComponent + " with mCallbacksMessenger="
+ + mCallbacksMessenger + " this=" + this);
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Log internal state.
+ * @hide
+ */
+ void dump() {
+ Log.d(TAG, "MediaBrowserCompat...");
+ Log.d(TAG, " mServiceComponent=" + mServiceComponent);
+ Log.d(TAG, " mCallback=" + mCallback);
+ Log.d(TAG, " mRootHints=" + mRootHints);
+ Log.d(TAG, " mState=" + getStateLabel(mState));
+ Log.d(TAG, " mServiceConnection=" + mServiceConnection);
+ Log.d(TAG, " mServiceBinderWrapper=" + mServiceBinderWrapper);
+ Log.d(TAG, " mCallbacksMessenger=" + mCallbacksMessenger);
+ Log.d(TAG, " mRootId=" + mRootId);
+ Log.d(TAG, " mMediaSessionToken=" + mMediaSessionToken);
+ }
+
+ private class ServiceBinderWrapper {
+ private Messenger mMessenger;
+
+ public ServiceBinderWrapper(IBinder target) {
+ mMessenger = new Messenger(target);
+ }
+
+ void connect() throws RemoteException {
+ sendRequest(CLIENT_MSG_CONNECT, mContext.getPackageName(), mRootHints,
+ mCallbacksMessenger);
+ }
+
+ void disconnect() throws RemoteException {
+ sendRequest(CLIENT_MSG_DISCONNECT, null, null, mCallbacksMessenger);
+ }
+
+ void addSubscription(String parentId) throws RemoteException {
+ sendRequest(CLIENT_MSG_ADD_SUBSCRIPTION, parentId, null, mCallbacksMessenger);
+ }
+
+ void removeSubscription(String parentId) throws RemoteException {
+ sendRequest(CLIENT_MSG_REMOVE_SUBSCRIPTION, parentId, null, mCallbacksMessenger);
+ }
+
+ void getMediaItem(String mediaId, ResultReceiver receiver) throws RemoteException {
+ Bundle data = new Bundle();
+ data.putParcelable(SERVICE_DATA_RESULT_RECEIVER, receiver);
+ sendRequest(CLIENT_MSG_GET_MEDIA_ITEM, mediaId, data, null);
+ }
+
+ private void sendRequest(int what, Object obj, Bundle data, Messenger cbMessenger)
+ throws RemoteException {
+ Message msg = Message.obtain();
+ msg.what = what;
+ msg.arg1 = CLIENT_VERSION_CURRENT;
+ msg.obj = obj;
+ msg.setData(data);
+ msg.replyTo = cbMessenger;
+ mMessenger.send(msg);
+ }
+ }
+
+ /**
+ * ServiceConnection to the other app.
+ */
+ private class MediaServiceConnection implements ServiceConnection {
+ @Override
+ public void onServiceConnected(final ComponentName name, final IBinder binder) {
+ postOrRun(new Runnable() {
+ @Override
+ public void run() {
+ if (DBG) {
+ Log.d(TAG, "MediaServiceConnection.onServiceConnected name=" + name
+ + " binder=" + binder);
+ dump();
+ }
+
+ // Make sure we are still the current connection, and that they haven't
+ // called disconnect().
+ if (!isCurrent("onServiceConnected")) {
+ return;
+ }
+
+ // Save their binder
+ mServiceBinderWrapper = new ServiceBinderWrapper(binder);
+
+ // We make a new mServiceCallbacks each time we connect so that we can drop
+ // responses from previous connections.
+ mCallbacksMessenger = new Messenger(mHandler);
+
+ mState = CONNECT_STATE_CONNECTING;
+
+ // Call connect, which is async. When we get a response from that we will
+ // say that we're connected.
+ try {
+ if (DBG) {
+ Log.d(TAG, "ServiceCallbacks.onConnect...");
+ dump();
+ }
+ mServiceBinderWrapper.connect();
+ } catch (RemoteException ex) {
+ // Connect failed, which isn't good. But the auto-reconnect on the
+ // service will take over and we will come back. We will also get the
+ // onServiceDisconnected, which has all the cleanup code. So let that
+ // do it.
+ Log.w(TAG, "RemoteException during connect for " + mServiceComponent);
+ if (DBG) {
+ Log.d(TAG, "ServiceCallbacks.onConnect...");
+ dump();
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onServiceDisconnected(final ComponentName name) {
+ postOrRun(new Runnable() {
+ @Override
+ public void run() {
+ if (DBG) {
+ Log.d(TAG, "MediaServiceConnection.onServiceDisconnected name=" + name
+ + " this=" + this + " mServiceConnection=" +
+ mServiceConnection);
+ dump();
+ }
+
+ // Make sure we are still the current connection, and that they haven't
+ // called disconnect().
+ if (!isCurrent("onServiceDisconnected")) {
+ return;
+ }
+
+ // Clear out what we set in onServiceConnected
+ mServiceBinderWrapper = null;
+ mCallbacksMessenger = null;
+
+ // And tell the app that it's suspended.
+ mState = CONNECT_STATE_SUSPENDED;
+ mCallback.onConnectionSuspended();
+ }
+ });
+ }
+
+ private void postOrRun(Runnable r) {
+ if (Thread.currentThread() == mHandler.getLooper().getThread()) {
+ r.run();
+ } else {
+ mHandler.post(r);
+ }
+ }
+
+ /**
+ * Return true if this is the current ServiceConnection. Also logs if it's not.
+ */
+ private boolean isCurrent(String funcName) {
+ if (mServiceConnection != this) {
+ if (mState != CONNECT_STATE_DISCONNECTED) {
+ // Check mState, because otherwise this log is noisy.
+ Log.i(TAG, funcName + " for " + mServiceComponent +
+ " with mServiceConnection=" + mServiceConnection + " this=" + this);
+ }
+ return false;
+ }
+ return true;
+ }
+ }
+
+ private class CallbackHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ Bundle data = msg.getData();
+ switch (msg.what) {
+ case SERVICE_MSG_ON_CONNECT:
+ onServiceConnected(mCallbacksMessenger, (String) msg.obj,
+ (MediaSessionCompat.Token) data.getParcelable(
+ SERVICE_DATA_MEDIA_SESSION_TOKEN),
+ data.getBundle(SERVICE_DATA_EXTRAS));
+ break;
+ case SERVICE_MSG_ON_CONNECT_FAILED:
+ onConnectionFailed(mCallbacksMessenger);
+ break;
+ case SERVICE_MSG_ON_LOAD_CHILDREN:
+ onLoadChildren(mCallbacksMessenger, (String) msg.obj,
+ data.getParcelableArrayList(SERVICE_DATA_MEDIA_ITEM_LIST));
+ break;
+ default:
+ Log.w(TAG, "Unhandled message: " + msg
+ + "\n Client version: " + CLIENT_VERSION_CURRENT
+ + "\n Service version: " + msg.arg1);
+ }
+ }
+ }
+
+ private static class Subscription {
+ final String id;
+ SubscriptionCallback callback;
+
+ Subscription(String id) {
+ this.id = id;
+ }
+ }
+ }
+
+ static class MediaBrowserImplApi21 implements MediaBrowserImpl {
+ protected Object mBrowserObj;
+ protected Messenger mMessenger;
+ protected Handler mHandler = new Handler();
+
+ public MediaBrowserImplApi21(Context context, ComponentName serviceComponent,
+ ConnectionCallback callback, Bundle rootHints) {
+ mBrowserObj = MediaBrowserCompatApi21.createBrowser(context, serviceComponent,
+ callback.mConnectionCallbackObj, rootHints);
+ }
+
+ @Override
+ public void connect() {
+ MediaBrowserCompatApi21.connect(mBrowserObj);
+ }
+
+ @Override
+ public void disconnect() {
+ MediaBrowserCompatApi21.disconnect(mBrowserObj);
+ }
+
+ @Override
+ public boolean isConnected() {
+ return MediaBrowserCompatApi21.isConnected(mBrowserObj);
+ }
+
+ @Override
+ public ComponentName getServiceComponent() {
+ return MediaBrowserCompatApi21.getServiceComponent(mBrowserObj);
+ }
+
+ @NonNull
+ @Override
+ public String getRoot() {
+ return MediaBrowserCompatApi21.getRoot(mBrowserObj);
+ }
+
+ @Nullable
+ @Override
+ public Bundle getExtras() {
+ return MediaBrowserCompatApi21.getExtras(mBrowserObj);
+ }
+
+ @NonNull
+ @Override
+ public MediaSessionCompat.Token getSessionToken() {
+ return MediaSessionCompat.Token.fromToken(
+ MediaBrowserCompatApi21.getSessionToken(mBrowserObj));
+ }
+
+ @Override
+ public void subscribe(@NonNull String parentId, @NonNull SubscriptionCallback callback) {
+ MediaBrowserCompatApi21.subscribe(
+ mBrowserObj, parentId, callback.mSubscriptionCallbackObj);
+ }
+
+ @Override
+ public void unsubscribe(@NonNull String parentId) {
+ MediaBrowserCompatApi21.unsubscribe(mBrowserObj, parentId);
+ }
+
+ @Override
+ public void getItem(@NonNull final String mediaId, @NonNull final ItemCallback cb) {
+ if (TextUtils.isEmpty(mediaId)) {
+ throw new IllegalArgumentException("mediaId is empty.");
+ }
+ if (cb == null) {
+ throw new IllegalArgumentException("cb is null.");
+ }
+ if (!MediaBrowserCompatApi21.isConnected(mBrowserObj)) {
+ Log.i(TAG, "Not connected, unable to retrieve the MediaItem.");
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ cb.onError(mediaId);
+ }
+ });
+ return;
+ }
+ if (mMessenger == null) {
+ Bundle extras = MediaBrowserCompatApi21.getExtras(mBrowserObj);
+ IBinder serviceBinder = BundleCompat.getBinder(extras, EXTRA_MESSENGER_BINDER);
+ if (serviceBinder != null) {
+ mMessenger = new Messenger(serviceBinder);
+ }
+ }
+ if (mMessenger == null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ // Default framework implementation.
+ cb.onItemLoaded(null);
+ }
+ });
+ return;
+ }
+ ResultReceiver receiver = new ResultReceiver(mHandler) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ if (resultCode != 0 || resultData == null
+ || !resultData.containsKey(MediaBrowserServiceCompat.KEY_MEDIA_ITEM)) {
+ cb.onError(mediaId);
+ return;
+ }
+ Parcelable item =
+ resultData.getParcelable(MediaBrowserServiceCompat.KEY_MEDIA_ITEM);
+ if (!(item instanceof MediaItem)) {
+ cb.onError(mediaId);
+ return;
+ }
+ cb.onItemLoaded((MediaItem)item);
+ }
+ };
+ try {
+ Bundle data = new Bundle();
+ data.putParcelable(SERVICE_DATA_RESULT_RECEIVER, receiver);
+ sendRequest(CLIENT_MSG_GET_MEDIA_ITEM, mediaId, data, null);
+ } catch (RemoteException e) {
+ Log.i(TAG, "Remote error getting media item.");
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ cb.onError(mediaId);
+ }
+ });
+ }
+ }
+
+ private void sendRequest(int what, Object obj, Bundle data, Messenger cbMessenger)
+ throws RemoteException {
+ Message msg = Message.obtain();
+ msg.what = what;
+ msg.arg1 = CLIENT_VERSION_CURRENT;
+ msg.obj = obj;
+ msg.setData(data);
+ msg.replyTo = cbMessenger;
+ mMessenger.send(msg);
+ }
+ }
+
+ static class MediaBrowserImplApi23 extends MediaBrowserImplApi21 {
+ public MediaBrowserImplApi23(Context context, ComponentName serviceComponent,
+ ConnectionCallback callback, Bundle rootHints) {
+ super(context, serviceComponent, callback, rootHints);
+ }
+
+ @Override
+ public void getItem(@NonNull String mediaId, @NonNull ItemCallback cb) {
+ MediaBrowserCompatApi23.getItem(mBrowserObj, mediaId, cb.mItemCallbackObj);
+ }
+ }
+}
diff --git a/v4/java/android/support/v4/media/MediaBrowserProtocol.java b/v4/java/android/support/v4/media/MediaBrowserProtocol.java
new file mode 100644
index 0000000000..7c8feb31c4
--- /dev/null
+++ b/v4/java/android/support/v4/media/MediaBrowserProtocol.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2015 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.support.v4.media;
+
+/***
+ * Defines the communication protocol for media browsers and media browser services.
+ * @hide
+ */
+class MediaBrowserProtocol {
+
+ /**
+ * MediaBrowserCompat will check the version of the connected MediaBrowserServiceCompat,
+ * and it will not send messages if they are introduced in the higher version of the
+ * MediaBrowserServiceCompat.
+ */
+ public static final int SERVICE_VERSION_1 = 1;
+ public static final int SERVICE_VERSION_CURRENT = SERVICE_VERSION_1;
+
+ /*
+ * Messages sent from the media browser service compat to the media browser compat.
+ * (Compat implementation for IMediaBrowserServiceCallbacks)
+ * DO NOT RENUMBER THESE!
+ */
+
+ /** (service v1)
+ * Sent after {@link MediaBrowserCompat#connect()} when the request has successfully
+ * completed.
+ * - arg1 : The service version
+ * - obj : The root media item id
+ * - data
+ * SERVICE_DATA_MEDIA_SESSION_TOKEN : Media session token
+ * SERVICE_DATA_EXTRAS : An extras bundle which contains EXTRA_SERVICE_VERSION
+ */
+ public static final int SERVICE_MSG_ON_CONNECT = 1;
+
+ /** (service v1)
+ * Sent after {@link MediaBrowserCompat#connect()} when the connection to the media browser
+ * failed.
+ * - arg1 : service version
+ */
+ public static final int SERVICE_MSG_ON_CONNECT_FAILED = 2;
+
+ /** (service v1)
+ * Sent when the list of children is loaded or updated.
+ * - arg1 : The service version
+ * - obj : The parent media item id
+ * - data
+ * SERVICE_DATA_MEDIA_ITEM_LIST : An array list for the media item children
+ */
+ public static final int SERVICE_MSG_ON_LOAD_CHILDREN = 3;
+
+ public static final String SERVICE_DATA_MEDIA_SESSION_TOKEN = "data_media_session_token";
+ public static final String SERVICE_DATA_EXTRAS = "data_extras";
+ public static final String SERVICE_DATA_MEDIA_ITEM_LIST = "data_media_item_list";
+ public static final String SERVICE_DATA_RESULT_RECEIVER = "data_result_receiver";
+
+ public static final String EXTRA_SERVICE_VERSION = "extra_service_version";
+ public static final String EXTRA_MESSENGER_BINDER = "extra_messenger";
+
+ /**
+ * MediaBrowserServiceCompat will check the version of the MediaBrowserCompat, and it will not
+ * send messages if they are introduced in the higher version of the MediaBrowserCompat.
+ */
+ public static final int CLIENT_VERSION_1 = 1;
+ public static final int CLIENT_VERSION_CURRENT = CLIENT_VERSION_1;
+
+ /*
+ * Messages sent from the media browser compat to the media browser service compat.
+ * (Compat implementation for IMediaBrowserService)
+ * DO NOT RENUMBER THESE!
+ */
+
+ /** (client v1)
+ * Sent to connect to the media browse service compat.
+ * - arg1 : The client version
+ * - obj : The package name
+ * - data : An optional root hints bundle of service-specific arguments
+ * - replayTo : Client messenger
+ */
+ public static final int CLIENT_MSG_CONNECT = 1;
+
+ /** (client v1)
+ * Sent to disconnect from the media browse service compat.
+ * - arg1 : The client version
+ * - replayTo : Client messenger
+ */
+ public static final int CLIENT_MSG_DISCONNECT = 2;
+
+ /** (client v1)
+ * Sent to subscribe for changes to the children of the specified media id.
+ * - arg1 : The client version
+ * - obj : The media item id
+ * - replayTo : Client messenger
+ */
+ public static final int CLIENT_MSG_ADD_SUBSCRIPTION = 3;
+
+ /** (client v1)
+ * Sent to unsubscribe for changes to the children of the specified media id.
+ * - arg1 : The client version
+ * - obj : The media item id
+ * - replayTo : Client messenger
+ */
+ public static final int CLIENT_MSG_REMOVE_SUBSCRIPTION = 4;
+
+ /** (client v1)
+ * Sent to retrieves a specific media item from the connected service.
+ * - arg1 : The client version
+ * - obj : The media item id
+ * - data
+ * SERVICE_DATA_RESULT_RECEIVER : Result receiver to get the result
+ */
+ public static final int CLIENT_MSG_GET_MEDIA_ITEM = 5;
+}
diff --git a/v4/java/android/support/v4/media/MediaBrowserServiceCompat.java b/v4/java/android/support/v4/media/MediaBrowserServiceCompat.java
new file mode 100644
index 0000000000..205e789989
--- /dev/null
+++ b/v4/java/android/support/v4/media/MediaBrowserServiceCompat.java
@@ -0,0 +1,803 @@
+/*
+ * Copyright (C) 2015 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.support.v4.media;
+
+import android.app.Service;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.app.BundleCompat;
+import android.support.v4.media.session.MediaSessionCompat;
+import android.support.v4.os.ResultReceiver;
+import android.support.v4.util.ArrayMap;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+import static android.support.v4.media.MediaBrowserProtocol.*;
+
+/**
+ * Base class for media browse services.
+ * <p>
+ * Media browse services enable applications to browse media content provided by an application
+ * and ask the application to start playing it. They may also be used to control content that
+ * is already playing by way of a {@link MediaSessionCompat}.
+ * </p>
+ *
+ * To extend this class, you must declare the service in your manifest file with
+ * an intent filter with the {@link #SERVICE_INTERFACE} action.
+ *
+ * For example:
+ * </p><pre>
+ * &lt;service android:name=".MyMediaBrowserServiceCompat"
+ * android:label="&#64;string/service_name" >
+ * &lt;intent-filter>
+ * &lt;action android:name="android.media.browse.MediaBrowserService" />
+ * &lt;/intent-filter>
+ * &lt;/service>
+ * </pre>
+ */
+public abstract class MediaBrowserServiceCompat extends Service {
+ private static final String TAG = "MediaBrowserServiceCompat";
+ private static final boolean DBG = false;
+
+ private MediaBrowserServiceImpl mImpl;
+
+ /**
+ * The {@link Intent} that must be declared as handled by the service.
+ */
+ public static final String SERVICE_INTERFACE = "android.media.browse.MediaBrowserService";
+
+ /**
+ * A key for passing the MediaItem to the ResultReceiver in getItem.
+ *
+ * @hide
+ */
+ public static final String KEY_MEDIA_ITEM = "media_item";
+
+ private final ArrayMap<IBinder, ConnectionRecord> mConnections = new ArrayMap();
+ private final ServiceHandler mHandler = new ServiceHandler();
+ MediaSessionCompat.Token mSession;
+
+ interface MediaBrowserServiceImpl {
+ void onCreate();
+ IBinder onBind(Intent intent);
+ }
+
+ class MediaBrowserServiceImplBase implements MediaBrowserServiceImpl {
+ private Messenger mMessenger;
+
+ @Override
+ public void onCreate() {
+ mMessenger = new Messenger(mHandler);
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ if (SERVICE_INTERFACE.equals(intent.getAction())) {
+ return mMessenger.getBinder();
+ }
+ return null;
+ }
+ }
+
+ class MediaBrowserServiceImplApi21 implements MediaBrowserServiceImpl {
+ private Object mServiceObj;
+
+ @Override
+ public void onCreate() {
+ mServiceObj = MediaBrowserServiceCompatApi21.createService();
+ MediaBrowserServiceCompatApi21.onCreate(mServiceObj, new ServiceImplApi21());
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return MediaBrowserServiceCompatApi21.onBind(mServiceObj, intent);
+ }
+ }
+
+ class MediaBrowserServiceImplApi23 implements MediaBrowserServiceImpl {
+ private Object mServiceObj;
+
+ @Override
+ public void onCreate() {
+ mServiceObj = MediaBrowserServiceCompatApi23.createService();
+ MediaBrowserServiceCompatApi23.onCreate(mServiceObj, new ServiceImplApi23());
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return MediaBrowserServiceCompatApi23.onBind(mServiceObj, intent);
+ }
+ }
+
+ private final class ServiceHandler extends Handler {
+ private final ServiceImpl mServiceImpl = new ServiceImpl();
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case CLIENT_MSG_CONNECT:
+ mServiceImpl.connect((String) msg.obj, msg.getData(),
+ new ServiceCallbacksCompat(msg.replyTo));
+ break;
+ case CLIENT_MSG_DISCONNECT:
+ mServiceImpl.disconnect(new ServiceCallbacksCompat(msg.replyTo));
+ break;
+ case CLIENT_MSG_ADD_SUBSCRIPTION:
+ mServiceImpl.addSubscription((String) msg.obj,
+ new ServiceCallbacksCompat(msg.replyTo));
+ break;
+ case CLIENT_MSG_REMOVE_SUBSCRIPTION:
+ mServiceImpl.removeSubscription((String) msg.obj,
+ new ServiceCallbacksCompat(msg.replyTo));
+ break;
+ case CLIENT_MSG_GET_MEDIA_ITEM:
+ mServiceImpl.getMediaItem((String) msg.obj, (ResultReceiver) msg.getData()
+ .getParcelable(SERVICE_DATA_RESULT_RECEIVER));
+ break;
+ default:
+ Log.w(TAG, "Unhandled message: " + msg
+ + "\n Service version: " + SERVICE_VERSION_CURRENT
+ + "\n Client version: " + msg.arg1);
+ }
+ }
+
+ public void postOrRun(Runnable r) {
+ if (Thread.currentThread() == getLooper().getThread()) {
+ r.run();
+ } else {
+ post(r);
+ }
+ }
+
+ public ServiceImpl getServiceImpl() {
+ return mServiceImpl;
+ }
+ }
+
+ /**
+ * All the info about a connection.
+ */
+ private class ConnectionRecord {
+ String pkg;
+ Bundle rootHints;
+ ServiceCallbacks callbacks;
+ BrowserRoot root;
+ HashSet<String> subscriptions = new HashSet();
+ }
+
+ /**
+ * Completion handler for asynchronous callback methods in {@link MediaBrowserServiceCompat}.
+ * <p>
+ * Each of the methods that takes one of these to send the result must call
+ * {@link #sendResult} to respond to the caller with the given results. If those
+ * functions return without calling {@link #sendResult}, they must instead call
+ * {@link #detach} before returning, and then may call {@link #sendResult} when
+ * they are done. If more than one of those methods is called, an exception will
+ * be thrown.
+ *
+ * @see MediaBrowserServiceCompat#onLoadChildren
+ * @see MediaBrowserServiceCompat#onLoadItem
+ */
+ public static class Result<T> {
+ private Object mDebug;
+ private boolean mDetachCalled;
+ private boolean mSendResultCalled;
+
+ Result(Object debug) {
+ mDebug = debug;
+ }
+
+ /**
+ * Send the result back to the caller.
+ */
+ public void sendResult(T result) {
+ if (mSendResultCalled) {
+ throw new IllegalStateException("sendResult() called twice for: " + mDebug);
+ }
+ mSendResultCalled = true;
+ onResultSent(result);
+ }
+
+ /**
+ * Detach this message from the current thread and allow the {@link #sendResult}
+ * call to happen later.
+ */
+ public void detach() {
+ if (mDetachCalled) {
+ throw new IllegalStateException("detach() called when detach() had already"
+ + " been called for: " + mDebug);
+ }
+ if (mSendResultCalled) {
+ throw new IllegalStateException("detach() called when sendResult() had already"
+ + " been called for: " + mDebug);
+ }
+ mDetachCalled = true;
+ }
+
+ boolean isDone() {
+ return mDetachCalled || mSendResultCalled;
+ }
+
+ /**
+ * Called when the result is sent, after assertions about not being called twice
+ * have happened.
+ */
+ void onResultSent(T result) {
+ }
+ }
+
+ private class ServiceImpl {
+ public void connect(final String pkg, final Bundle rootHints,
+ final ServiceCallbacks callbacks) {
+
+ final int uid = Binder.getCallingUid();
+ if (!isValidPackage(pkg, uid)) {
+ throw new IllegalArgumentException("Package/uid mismatch: uid=" + uid
+ + " package=" + pkg);
+ }
+
+ mHandler.postOrRun(new Runnable() {
+ @Override
+ public void run() {
+ final IBinder b = callbacks.asBinder();
+
+ // Clear out the old subscriptions. We are getting new ones.
+ mConnections.remove(b);
+
+ final ConnectionRecord connection = new ConnectionRecord();
+ connection.pkg = pkg;
+ connection.rootHints = rootHints;
+ connection.callbacks = callbacks;
+
+ connection.root =
+ MediaBrowserServiceCompat.this.onGetRoot(pkg, uid, rootHints);
+
+ // If they didn't return something, don't allow this client.
+ if (connection.root == null) {
+ Log.i(TAG, "No root for client " + pkg + " from service "
+ + getClass().getName());
+ try {
+ callbacks.onConnectFailed();
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Calling onConnectFailed() failed. Ignoring. "
+ + "pkg=" + pkg);
+ }
+ } else {
+ try {
+ mConnections.put(b, connection);
+ if (mSession != null) {
+ callbacks.onConnect(connection.root.getRootId(),
+ mSession, connection.root.getExtras());
+ }
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Calling onConnect() failed. Dropping client. "
+ + "pkg=" + pkg);
+ mConnections.remove(b);
+ }
+ }
+ }
+ });
+ }
+
+ public void disconnect(final ServiceCallbacks callbacks) {
+ mHandler.postOrRun(new Runnable() {
+ @Override
+ public void run() {
+ final IBinder b = callbacks.asBinder();
+
+ // Clear out the old subscriptions. We are getting new ones.
+ final ConnectionRecord old = mConnections.remove(b);
+ if (old != null) {
+ // TODO
+ }
+ }
+ });
+ }
+
+
+ public void addSubscription(final String id, final ServiceCallbacks callbacks) {
+ mHandler.postOrRun(new Runnable() {
+ @Override
+ public void run() {
+ final IBinder b = callbacks.asBinder();
+
+ // Get the record for the connection
+ final ConnectionRecord connection = mConnections.get(b);
+ if (connection == null) {
+ Log.w(TAG, "addSubscription for callback that isn't registered id="
+ + id);
+ return;
+ }
+
+ MediaBrowserServiceCompat.this.addSubscription(id, connection);
+ }
+ });
+ }
+
+ public void removeSubscription(final String id, final ServiceCallbacks callbacks) {
+ mHandler.postOrRun(new Runnable() {
+ @Override
+ public void run() {
+ final IBinder b = callbacks.asBinder();
+
+ ConnectionRecord connection = mConnections.get(b);
+ if (connection == null) {
+ Log.w(TAG, "removeSubscription for callback that isn't registered id="
+ + id);
+ return;
+ }
+ if (!connection.subscriptions.remove(id)) {
+ Log.w(TAG, "removeSubscription called for " + id
+ + " which is not subscribed");
+ }
+ }
+ });
+ }
+
+ public void getMediaItem(final String mediaId, final ResultReceiver receiver) {
+ if (TextUtils.isEmpty(mediaId) || receiver == null) {
+ return;
+ }
+
+ mHandler.postOrRun(new Runnable() {
+ @Override
+ public void run() {
+ performLoadItem(mediaId, receiver);
+ }
+ });
+ }
+ }
+
+ private class ServiceImplApi21 implements MediaBrowserServiceCompatApi21.ServiceImplApi21 {
+ final ServiceImpl mServiceImpl;
+
+ ServiceImplApi21() {
+ mServiceImpl = mHandler.getServiceImpl();
+ }
+
+ @Override
+ public void connect(final String pkg, final Bundle rootHints,
+ final MediaBrowserServiceCompatApi21.ServiceCallbacks callbacks) {
+ mServiceImpl.connect(pkg, rootHints, new ServiceCallbacksApi21(callbacks));
+ }
+
+ @Override
+ public void disconnect(final MediaBrowserServiceCompatApi21.ServiceCallbacks callbacks) {
+ mServiceImpl.disconnect(new ServiceCallbacksApi21(callbacks));
+ }
+
+
+ @Override
+ public void addSubscription(
+ final String id, final MediaBrowserServiceCompatApi21.ServiceCallbacks callbacks) {
+ mServiceImpl.addSubscription(id, new ServiceCallbacksApi21(callbacks));
+ }
+
+ @Override
+ public void removeSubscription(final String id,
+ final MediaBrowserServiceCompatApi21.ServiceCallbacks callbacks) {
+ mServiceImpl.removeSubscription(id, new ServiceCallbacksApi21(callbacks));
+ }
+ }
+
+ private class ServiceImplApi23 extends ServiceImplApi21
+ implements MediaBrowserServiceCompatApi23.ServiceImplApi23 {
+ @Override
+ public void getMediaItem(final String mediaId,
+ final MediaBrowserServiceCompatApi23.ItemCallback cb) {
+ ResultReceiver receiverCompat = new ResultReceiver(mHandler) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ MediaBrowserCompat.MediaItem item = resultData.getParcelable(KEY_MEDIA_ITEM);
+ Parcel itemParcel = null;
+ if (item != null) {
+ itemParcel = Parcel.obtain();
+ item.writeToParcel(itemParcel, 0);
+ }
+ cb.onItemLoaded(resultCode, resultData, itemParcel);
+ }
+ };
+ mServiceImpl.getMediaItem(mediaId, receiverCompat);
+ }
+ }
+
+ private interface ServiceCallbacks {
+ IBinder asBinder();
+ void onConnect(String root, MediaSessionCompat.Token session, Bundle extras)
+ throws RemoteException;
+ void onConnectFailed() throws RemoteException;
+ void onLoadChildren(String mediaId, List<MediaBrowserCompat.MediaItem> list)
+ throws RemoteException;
+ }
+
+ private class ServiceCallbacksCompat implements ServiceCallbacks {
+ final Messenger mCallbacks;
+
+ ServiceCallbacksCompat(Messenger callbacks) {
+ mCallbacks = callbacks;
+ }
+
+ public IBinder asBinder() {
+ return mCallbacks.getBinder();
+ }
+
+ public void onConnect(String root, MediaSessionCompat.Token session, Bundle extras)
+ throws RemoteException {
+ if (extras == null) {
+ extras = new Bundle();
+ }
+ extras.putInt(EXTRA_SERVICE_VERSION, SERVICE_VERSION_CURRENT);
+ Bundle data = new Bundle();
+ data.putParcelable(SERVICE_DATA_MEDIA_SESSION_TOKEN, session);
+ data.putBundle(SERVICE_DATA_EXTRAS, extras);
+ sendRequest(SERVICE_MSG_ON_CONNECT, root, data);
+ }
+
+ public void onConnectFailed() throws RemoteException {
+ sendRequest(SERVICE_MSG_ON_CONNECT_FAILED, null, null);
+ }
+
+ public void onLoadChildren(String mediaId, List<MediaBrowserCompat.MediaItem> list)
+ throws RemoteException {
+ Bundle data = null;
+ if (list != null) {
+ data = new Bundle();
+ data.putParcelableArrayList(SERVICE_DATA_MEDIA_ITEM_LIST,
+ list instanceof ArrayList ? (ArrayList) list : new ArrayList<>(list));
+ }
+ sendRequest(SERVICE_MSG_ON_LOAD_CHILDREN, mediaId, data);
+ }
+
+ private void sendRequest(int what, Object obj, Bundle data)
+ throws RemoteException {
+ Message msg = Message.obtain();
+ msg.what = what;
+ msg.arg1 = SERVICE_VERSION_CURRENT;
+ msg.obj = obj;
+ msg.setData(data);
+ mCallbacks.send(msg);
+ }
+ }
+
+ private class ServiceCallbacksApi21 implements ServiceCallbacks {
+ final MediaBrowserServiceCompatApi21.ServiceCallbacks mCallbacks;
+ Messenger mMessenger;
+
+ ServiceCallbacksApi21(MediaBrowserServiceCompatApi21.ServiceCallbacks callbacks) {
+ mCallbacks = callbacks;
+ }
+
+ public IBinder asBinder() {
+ return mCallbacks.asBinder();
+ }
+
+ public void onConnect(String root, MediaSessionCompat.Token session, Bundle extras)
+ throws RemoteException {
+ if (extras == null) {
+ extras = new Bundle();
+ }
+ mMessenger = new Messenger(mHandler);
+ BundleCompat.putBinder(extras, EXTRA_MESSENGER_BINDER, mMessenger.getBinder());
+ extras.putInt(EXTRA_SERVICE_VERSION, SERVICE_VERSION_CURRENT);
+ mCallbacks.onConnect(root, session.getToken(), extras);
+ }
+
+ public void onConnectFailed() throws RemoteException {
+ mCallbacks.onConnectFailed();
+ }
+
+ public void onLoadChildren(String mediaId, List<MediaBrowserCompat.MediaItem> list)
+ throws RemoteException {
+ List<Parcel> parcelList = null;
+ if (list != null) {
+ parcelList = new ArrayList<>();
+ for (MediaBrowserCompat.MediaItem item : list) {
+ Parcel parcel = Parcel.obtain();
+ item.writeToParcel(parcel, 0);
+ parcelList.add(parcel);
+ }
+ }
+ mCallbacks.onLoadChildren(mediaId, parcelList);
+ }
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ if (Build.VERSION.SDK_INT >= 23) {
+ mImpl = new MediaBrowserServiceImplApi23();
+ } else if (Build.VERSION.SDK_INT >= 21) {
+ mImpl = new MediaBrowserServiceImplApi21();
+ } else {
+ mImpl = new MediaBrowserServiceImplBase();
+ }
+ mImpl.onCreate();
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mImpl.onBind(intent);
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+ }
+
+ /**
+ * Called to get the root information for browsing by a particular client.
+ * <p>
+ * The implementation should verify that the client package has permission
+ * to access browse media information before returning the root id; it
+ * should return null if the client is not allowed to access this
+ * information.
+ * </p>
+ *
+ * @param clientPackageName The package name of the application which is
+ * requesting access to browse media.
+ * @param clientUid The uid of the application which is requesting access to
+ * browse media.
+ * @param rootHints An optional bundle of service-specific arguments to send
+ * to the media browse service when connecting and retrieving the
+ * root id for browsing, or null if none. The contents of this
+ * bundle may affect the information returned when browsing.
+ * @return The {@link BrowserRoot} for accessing this app's content or null.
+ */
+ public abstract @Nullable BrowserRoot onGetRoot(@NonNull String clientPackageName,
+ int clientUid, @Nullable Bundle rootHints);
+
+ /**
+ * Called to get information about the children of a media item.
+ * <p>
+ * Implementations must call {@link Result#sendResult result.sendResult}
+ * with the list of children. If loading the children will be an expensive
+ * operation that should be performed on another thread,
+ * {@link Result#detach result.detach} may be called before returning from
+ * this function, and then {@link Result#sendResult result.sendResult}
+ * called when the loading is complete.
+ *
+ * @param parentId The id of the parent media item whose children are to be
+ * queried.
+ * @param result The Result to send the list of children to, or null if the
+ * id is invalid.
+ */
+ public abstract void onLoadChildren(@NonNull String parentId,
+ @NonNull Result<List<MediaBrowserCompat.MediaItem>> result);
+
+ /**
+ * Called to get information about a specific media item.
+ * <p>
+ * Implementations must call {@link Result#sendResult result.sendResult}. If
+ * loading the item will be an expensive operation {@link Result#detach
+ * result.detach} may be called before returning from this function, and
+ * then {@link Result#sendResult result.sendResult} called when the item has
+ * been loaded.
+ * <p>
+ * The default implementation sends a null result.
+ *
+ * @param itemId The id for the specific
+ * {@link MediaBrowserCompat.MediaItem}.
+ * @param result The Result to send the item to, or null if the id is
+ * invalid.
+ */
+ public void onLoadItem(String itemId, Result<MediaBrowserCompat.MediaItem> result) {
+ result.sendResult(null);
+ }
+
+ /**
+ * Call to set the media session.
+ * <p>
+ * This should be called as soon as possible during the service's startup.
+ * It may only be called once.
+ *
+ * @param token The token for the service's {@link MediaSessionCompat}.
+ */
+ public void setSessionToken(final MediaSessionCompat.Token token) {
+ if (token == null) {
+ throw new IllegalArgumentException("Session token may not be null.");
+ }
+ if (mSession != null) {
+ throw new IllegalStateException("The session token has already been set.");
+ }
+ mSession = token;
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ for (IBinder key : mConnections.keySet()) {
+ ConnectionRecord connection = mConnections.get(key);
+ try {
+ connection.callbacks.onConnect(connection.root.getRootId(), token,
+ connection.root.getExtras());
+ } catch (RemoteException e) {
+ Log.w(TAG, "Connection for " + connection.pkg + " is no longer valid.");
+ mConnections.remove(key);
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Gets the session token, or null if it has not yet been created
+ * or if it has been destroyed.
+ */
+ public @Nullable MediaSessionCompat.Token getSessionToken() {
+ return mSession;
+ }
+
+ /**
+ * Notifies all connected media browsers that the children of
+ * the specified parent id have changed in some way.
+ * This will cause browsers to fetch subscribed content again.
+ *
+ * @param parentId The id of the parent media item whose
+ * children changed.
+ */
+ public void notifyChildrenChanged(@NonNull final String parentId) {
+ if (parentId == null) {
+ throw new IllegalArgumentException("parentId cannot be null in notifyChildrenChanged");
+ }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ for (IBinder binder : mConnections.keySet()) {
+ ConnectionRecord connection = mConnections.get(binder);
+ if (connection.subscriptions.contains(parentId)) {
+ performLoadChildren(parentId, connection);
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Return whether the given package is one of the ones that is owned by the uid.
+ */
+ private boolean isValidPackage(String pkg, int uid) {
+ if (pkg == null) {
+ return false;
+ }
+ final PackageManager pm = getPackageManager();
+ final String[] packages = pm.getPackagesForUid(uid);
+ final int N = packages.length;
+ for (int i=0; i<N; i++) {
+ if (packages[i].equals(pkg)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Save the subscription and if it is a new subscription send the results.
+ */
+ private void addSubscription(String id, ConnectionRecord connection) {
+ // Save the subscription
+ connection.subscriptions.add(id);
+
+ // send the results
+ performLoadChildren(id, connection);
+ }
+
+ /**
+ * Call onLoadChildren and then send the results back to the connection.
+ * <p>
+ * Callers must make sure that this connection is still connected.
+ */
+ private void performLoadChildren(final String parentId, final ConnectionRecord connection) {
+ final Result<List<MediaBrowserCompat.MediaItem>> result
+ = new Result<List<MediaBrowserCompat.MediaItem>>(parentId) {
+ @Override
+ void onResultSent(List<MediaBrowserCompat.MediaItem> list) {
+ if (mConnections.get(connection.callbacks.asBinder()) != connection) {
+ if (DBG) {
+ Log.d(TAG, "Not sending onLoadChildren result for connection that has"
+ + " been disconnected. pkg=" + connection.pkg + " id=" + parentId);
+ }
+ return;
+ }
+
+ try {
+ connection.callbacks.onLoadChildren(parentId, list);
+ } catch (RemoteException ex) {
+ // The other side is in the process of crashing.
+ Log.w(TAG, "Calling onLoadChildren() failed for id=" + parentId
+ + " package=" + connection.pkg);
+ }
+ }
+ };
+
+ onLoadChildren(parentId, result);
+
+ if (!result.isDone()) {
+ throw new IllegalStateException("onLoadChildren must call detach() or sendResult()"
+ + " before returning for package=" + connection.pkg + " id=" + parentId);
+ }
+ }
+
+ private void performLoadItem(String itemId, final ResultReceiver receiver) {
+ final Result<MediaBrowserCompat.MediaItem> result =
+ new Result<MediaBrowserCompat.MediaItem>(itemId) {
+ @Override
+ void onResultSent(MediaBrowserCompat.MediaItem item) {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(KEY_MEDIA_ITEM, item);
+ receiver.send(0, bundle);
+ }
+ };
+
+ MediaBrowserServiceCompat.this.onLoadItem(itemId, result);
+
+ if (!result.isDone()) {
+ throw new IllegalStateException("onLoadItem must call detach() or sendResult()"
+ + " before returning for id=" + itemId);
+ }
+ }
+
+ /**
+ * Contains information that the browser service needs to send to the client
+ * when first connected.
+ */
+ public static final class BrowserRoot {
+ final private String mRootId;
+ final private Bundle mExtras;
+
+ /**
+ * Constructs a browser root.
+ * @param rootId The root id for browsing.
+ * @param extras Any extras about the browser service.
+ */
+ public BrowserRoot(@NonNull String rootId, @Nullable Bundle extras) {
+ if (rootId == null) {
+ throw new IllegalArgumentException("The root id in BrowserRoot cannot be null. " +
+ "Use null for BrowserRoot instead.");
+ }
+ mRootId = rootId;
+ mExtras = extras;
+ }
+
+ /**
+ * Gets the root id for browsing.
+ */
+ public String getRootId() {
+ return mRootId;
+ }
+
+ /**
+ * Gets any extras about the brwoser service.
+ */
+ public Bundle getExtras() {
+ return mExtras;
+ }
+ }
+}
diff --git a/v4/java/android/support/v4/media/MediaMetadataCompat.java b/v4/java/android/support/v4/media/MediaMetadataCompat.java
index 088b208a4f..0d078265c9 100644
--- a/v4/java/android/support/v4/media/MediaMetadataCompat.java
+++ b/v4/java/android/support/v4/media/MediaMetadataCompat.java
@@ -78,7 +78,8 @@ public final class MediaMetadataCompat implements Parcelable {
public static final String METADATA_KEY_COMPILATION = "android.media.metadata.COMPILATION";
/**
- * The date the media was created or published as TODO determine format.
+ * The date the media was created or published. The format is unspecified
+ * but RFC 3339 is recommended.
*/
public static final String METADATA_KEY_DATE = "android.media.metadata.DATE";
@@ -360,7 +361,13 @@ public final class MediaMetadataCompat implements Parcelable {
public RatingCompat getRating(@RatingKey String key) {
RatingCompat rating = null;
try {
- rating = mBundle.getParcelable(key);
+ if (Build.VERSION.SDK_INT >= 21) {
+ // On platform version 21 or higher, mBundle stores a Rating object. Convert it to
+ // RatingCompat.
+ rating = RatingCompat.fromRating(mBundle.getParcelable(key));
+ } else {
+ rating = mBundle.getParcelable(key);
+ }
} catch (Exception e) {
// ignore, value was not a bitmap
Log.w(TAG, "Failed to retrieve a key as Rating.", e);
@@ -509,31 +516,11 @@ public final class MediaMetadataCompat implements Parcelable {
return null;
}
- Builder builder = new Builder();
- for (String key : MediaMetadataCompatApi21.keySet(metadataObj)) {
- Integer type = METADATA_KEYS_TYPE.get(key);
- if (type != null) {
- switch (type) {
- case METADATA_TYPE_BITMAP:
- builder.putBitmap(key,
- MediaMetadataCompatApi21.getBitmap(metadataObj, key));
- break;
- case METADATA_TYPE_LONG:
- builder.putLong(key,
- MediaMetadataCompatApi21.getLong(metadataObj, key));
- break;
- case METADATA_TYPE_RATING:
- builder.putRating(key, RatingCompat.fromRating(
- MediaMetadataCompatApi21.getRating(metadataObj, key)));
- break;
- case METADATA_TYPE_TEXT:
- builder.putText(key,
- MediaMetadataCompatApi21.getText(metadataObj, key));
- break;
- }
- }
- }
- MediaMetadataCompat metadata = builder.build();
+ Parcel p = Parcel.obtain();
+ MediaMetadataCompatApi21.writeToParcel(metadataObj, p, 0);
+ p.setDataPosition(0);
+ MediaMetadataCompat metadata = MediaMetadataCompat.CREATOR.createFromParcel(p);
+ p.recycle();
metadata.mMetadataObj = metadataObj;
return metadata;
}
@@ -553,31 +540,11 @@ public final class MediaMetadataCompat implements Parcelable {
return mMetadataObj;
}
- Object builderObj = MediaMetadataCompatApi21.Builder.newInstance();
- for (String key : keySet()) {
- Integer type = METADATA_KEYS_TYPE.get(key);
- if (type != null) {
- switch (type) {
- case METADATA_TYPE_BITMAP:
- MediaMetadataCompatApi21.Builder.putBitmap(builderObj, key,
- getBitmap(key));
- break;
- case METADATA_TYPE_LONG:
- MediaMetadataCompatApi21.Builder.putLong(builderObj, key,
- getLong(key));
- break;
- case METADATA_TYPE_RATING:
- MediaMetadataCompatApi21.Builder.putRating(builderObj, key,
- getRating(key).getRating());
- break;
- case METADATA_TYPE_TEXT:
- MediaMetadataCompatApi21.Builder.putText(builderObj, key,
- getText(key));
- break;
- }
- }
- }
- mMetadataObj = MediaMetadataCompatApi21.Builder.build(builderObj);
+ Parcel p = Parcel.obtain();
+ writeToParcel(p, 0);
+ p.setDataPosition(0);
+ mMetadataObj = MediaMetadataCompatApi21.createFromParcel(p);
+ p.recycle();
return mMetadataObj;
}
@@ -741,7 +708,13 @@ public final class MediaMetadataCompat implements Parcelable {
+ " key cannot be used to put a Rating");
}
}
- mBundle.putParcelable(key, value);
+ if (Build.VERSION.SDK_INT >= 21) {
+ // On platform version 21 or higher, use Rating instead of RatingCompat so mBundle
+ // can be unmarshalled.
+ mBundle.putParcelable(key, (Parcelable) value.getRating());
+ } else {
+ mBundle.putParcelable(key, value);
+ }
return this;
}
diff --git a/v4/java/android/support/v4/media/session/MediaButtonReceiver.java b/v4/java/android/support/v4/media/session/MediaButtonReceiver.java
new file mode 100644
index 0000000000..d5eb0e839a
--- /dev/null
+++ b/v4/java/android/support/v4/media/session/MediaButtonReceiver.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2015 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.support.v4.media.session;
+
+import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.support.v4.media.session.MediaControllerCompat;
+import android.support.v4.media.session.MediaSessionCompat;
+import android.view.KeyEvent;
+
+import java.util.List;
+
+/**
+ * A media button receiver receives and helps translate hardware media playback buttons,
+ * such as those found on wired and wireless headsets, into the appropriate callbacks
+ * in your app.
+ * <p />
+ * You can add this MediaButtonReceiver to your app by adding it directly to your
+ * AndroidManifest.xml:
+ * <pre>
+ * &lt;receiver android:name="android.support.v4.media.session.MediaButtonReceiver" &gt;
+ * &lt;intent-filter&gt;
+ * &lt;action android:name="android.intent.action.MEDIA_BUTTON" /&gt;
+ * &lt;/intent-filter&gt;
+ * &lt;/receiver&gt;
+ * </pre>
+ * This class assumes you have a {@link Service} in your app that controls
+ * media playback via a {@link MediaSessionCompat}. That {@link Service} must
+ * include an intent filter that also handles {@link Intent#ACTION_MEDIA_BUTTON}:
+ * <pre>
+ * &lt;service android:name="com.example.android.MediaPlaybackService" &gt;
+ * &lt;intent-filter&gt;
+ * &lt;action android:name="android.intent.action.MEDIA_BUTTON" /&gt;
+ * &lt;/intent-filter&gt;
+ * &lt;/service&gt;
+ * </pre>
+ *
+ * All {@link Intent}s sent to this MediaButtonReceiver will then be forwarded
+ * to the {@link Service}. Events can then be handled in
+ * {@link Service#onStartCommand(Intent, int, int)} by calling
+ * {@link MediaButtonReceiver#handleIntent(MediaSessionCompat, Intent)}, passing in
+ * your current {@link MediaSessionCompat}:
+ * <pre>
+ * private MediaSessionCompat mMediaSessionCompat = ...;
+ *
+ * public int onStartCommand(Intent intent, int flags, int startId) {
+ * MediaButtonReceiver.handleIntent(mMediaSessionCompat, intent);
+ * return super.onStartCommand(intent, flags, startId);
+ * }
+ * </pre>
+ *
+ * This ensures that the correct callbacks to {@link MediaSessionCompat.Callback}
+ * will be triggered based on the incoming {@link KeyEvent}.
+ */
+public class MediaButtonReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Intent queryIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+ queryIntent.setPackage(context.getPackageName());
+ PackageManager pm = context.getPackageManager();
+ List<ResolveInfo> resolveInfos = pm.queryIntentServices(queryIntent, 0);
+ if (resolveInfos.size() != 1) {
+ throw new IllegalStateException("Expected 1 Service that handles " +
+ Intent.ACTION_MEDIA_BUTTON + ", found " + resolveInfos.size());
+ }
+ ResolveInfo resolveInfo = resolveInfos.get(0);
+ ComponentName componentName = new ComponentName(resolveInfo.serviceInfo.packageName,
+ resolveInfo.serviceInfo.name);
+ intent.setComponent(componentName);
+ context.startService(intent);
+ }
+
+ /**
+ * Extracts any available {@link KeyEvent} from an {@link Intent#ACTION_MEDIA_BUTTON}
+ * intent, passing it onto the {@link MediaSessionCompat} using
+ * {@link MediaControllerCompat#dispatchMediaButtonEvent(KeyEvent)}, which in turn
+ * will trigger callbacks to the {@link MediaSessionCompat.Callback} registered via
+ * {@link MediaSessionCompat#setCallback(MediaSessionCompat.Callback)}.
+ * <p />
+ * The returned {@link KeyEvent} is non-null if any {@link KeyEvent} is found and can
+ * be used if any additional processing is needed beyond what is done in the
+ * {@link MediaSessionCompat.Callback}. An example of is to prevent redelivery of a
+ * {@link KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE} Intent in the case of the Service being
+ * restarted (which, by default, will redeliver the last received Intent).
+ * <pre>
+ * KeyEvent keyEvent = MediaButtonReceiver.handleIntent(mediaSession, intent);
+ * if (keyEvent != null && keyEvent.getKeyCode() == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) {
+ * Intent emptyIntent = new Intent(intent);
+ * emptyIntent.setAction("");
+ * startService(emptyIntent);
+ * }
+ * </pre>
+ * @param mediaSessionCompat A {@link MediaSessionCompat} that has a
+ * {@link MediaSessionCompat.Callback} set.
+ * @param intent The intent to parse.
+ * @return The extracted {@link KeyEvent} if found, or null.
+ */
+ public static KeyEvent handleIntent(MediaSessionCompat mediaSessionCompat, Intent intent) {
+ if (mediaSessionCompat == null || intent == null
+ || !Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())
+ || !intent.hasExtra(Intent.EXTRA_KEY_EVENT)) {
+ return null;
+ }
+ KeyEvent ke = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+ MediaControllerCompat mediaController = mediaSessionCompat.getController();
+ mediaController.dispatchMediaButtonEvent(ke);
+ return ke;
+ }
+}
+
diff --git a/v4/java/android/support/v4/media/session/MediaControllerCompat.java b/v4/java/android/support/v4/media/session/MediaControllerCompat.java
index 1d2180ce51..a6a5c88948 100644
--- a/v4/java/android/support/v4/media/session/MediaControllerCompat.java
+++ b/v4/java/android/support/v4/media/session/MediaControllerCompat.java
@@ -92,7 +92,9 @@ public final class MediaControllerCompat {
}
mToken = sessionToken;
- if (android.os.Build.VERSION.SDK_INT >= 21) {
+ if (android.os.Build.VERSION.SDK_INT >= 23) {
+ mImpl = new MediaControllerImplApi23(context, sessionToken);
+ } else if (android.os.Build.VERSION.SDK_INT >= 21) {
mImpl = new MediaControllerImplApi21(context, sessionToken);
} else {
mImpl = new MediaControllerImplBase(mToken);
@@ -555,7 +557,9 @@ public final class MediaControllerCompat {
}
public void post(int what, Object obj, Bundle data) {
- obtainMessage(what, obj).sendToTarget();
+ Message msg = obtainMessage(what, obj);
+ msg.setData(data);
+ msg.sendToTarget();
}
}
}
@@ -1328,6 +1332,14 @@ public final class MediaControllerCompat {
@Override
public void playFromUri(Uri uri, Bundle extras) {
+ if (uri == null || Uri.EMPTY.equals(uri)) {
+ throw new IllegalArgumentException(
+ "You must specify a non-empty Uri for playFromUri.");
+ }
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(MediaSessionCompat.ACTION_ARGUMENT_URI, uri);
+ bundle.putParcelable(MediaSessionCompat.ACTION_ARGUMENT_EXTRAS, extras);
+ sendCustomAction(MediaSessionCompat.ACTION_PLAY_FROM_URI, bundle);
}
@Override
diff --git a/v4/java/android/support/v4/media/session/MediaSessionCompat.java b/v4/java/android/support/v4/media/session/MediaSessionCompat.java
index fa963df305..d35ada60ee 100644
--- a/v4/java/android/support/v4/media/session/MediaSessionCompat.java
+++ b/v4/java/android/support/v4/media/session/MediaSessionCompat.java
@@ -19,9 +19,12 @@ package android.support.v4.media.session;
import android.app.Activity;
import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
@@ -77,6 +80,8 @@ import java.util.List;
* backwards compatible fashion.
*/
public class MediaSessionCompat {
+ private static final String TAG = "MediaSessionCompat";
+
private final MediaSessionImpl mImpl;
private final MediaControllerCompat mController;
private final ArrayList<OnActiveChangeListener>
@@ -102,12 +107,51 @@ public class MediaSessionCompat {
public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 1 << 1;
/**
+ * Custom action to invoke playFromUri() for the forward compatibility.
+ *
+ * @hide
+ */
+ public static final String ACTION_PLAY_FROM_URI =
+ "android.support.v4.media.session.action.PLAY_FROM_URI";
+
+ /**
+ * Argument for use with {@link #ACTION_PLAY_FROM_URI} indicating URI to play.
+ *
+ * @hide
+ */
+ public static final String ACTION_ARGUMENT_URI =
+ "android.support.v4.media.session.action.ARGUMENT_URI";
+
+ /**
+ * Argument for use with {@link #ACTION_PLAY_FROM_URI} indicating extra bundle.
+ *
+ * @hide
+ */
+ public static final String ACTION_ARGUMENT_EXTRAS =
+ "android.support.v4.media.session.action.ARGUMENT_EXTRAS";
+
+ /**
+ * Creates a new session using a media button receiver from your manifest.
+ * Note that a media button receiver is required to support platform versions
+ * earlier than {@link android.os.Build.VERSION_CODES#LOLLIPOP}.
+ *
+ * @param context The context.
+ * @param tag A short name for debugging purposes.
+ */
+ public MediaSessionCompat(Context context, String tag) {
+ this(context, tag, null, null);
+ }
+
+ /**
* Creates a new session.
*
* @param context The context.
* @param tag A short name for debugging purposes.
* @param mediaButtonEventReceiver The component name for your receiver.
- * This must be non-null to support platform versions earlier
+ * If null, this will attempt to find an appropriate
+ * {@link BroadcastReceiver} that handles
+ * {@link Intent#ACTION_MEDIA_BUTTON} from your manifest.
+ * A receiver is required to support platform versions earlier
* than {@link android.os.Build.VERSION_CODES#LOLLIPOP}.
* @param mbrIntent The PendingIntent for your receiver component that
* handles media button events. This is optional and will be used
@@ -123,6 +167,24 @@ public class MediaSessionCompat {
throw new IllegalArgumentException("tag must not be null or empty");
}
+ if (mediaButtonEventReceiver == null) {
+ Intent queryIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+ queryIntent.setPackage(context.getPackageName());
+ PackageManager pm = context.getPackageManager();
+ List<ResolveInfo> resolveInfos = pm.queryBroadcastReceivers(queryIntent, 0);
+ // If none are found, assume we are running on a newer platform version that does
+ // not require a media button receiver ComponentName. Later code will double check
+ // this assumption and throw an error if needed
+ if (resolveInfos.size() == 1) {
+ ResolveInfo resolveInfo = resolveInfos.get(0);
+ mediaButtonEventReceiver = new ComponentName(resolveInfo.activityInfo.packageName,
+ resolveInfo.activityInfo.name);
+ } else if (resolveInfos.size() > 1) {
+ Log.w(TAG, "More than one BroadcastReceiver that handles " +
+ Intent.ACTION_MEDIA_BUTTON + " was found, using null. Provide a " +
+ "specific ComponentName to use as this session's media button receiver");
+ }
+ }
if (mediaButtonEventReceiver != null && mbrIntent == null) {
// construct a PendingIntent for the media button
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
@@ -250,8 +312,8 @@ public class MediaSessionCompat {
* <p>
* On platforms earlier than
* {@link android.os.Build.VERSION_CODES#LOLLIPOP},
- * {@link #setMediaButtonReceiver(PendingIntent)} must be called before
- * setting this to true.
+ * a media button event receiver should be set via the constructor to
+ * receive media button events.
*
* @param active Whether this session is active or not.
*/
@@ -675,7 +737,13 @@ public class MediaSessionCompat {
@Override
public void onCustomAction(String action, Bundle extras) {
- Callback.this.onCustomAction(action, extras);
+ if (action.equals(ACTION_PLAY_FROM_URI)) {
+ Uri uri = (Uri) extras.getParcelable(ACTION_ARGUMENT_URI);
+ Bundle bundle = (Bundle) extras.getParcelable(ACTION_ARGUMENT_EXTRAS);
+ Callback.this.onPlayFromUri(uri, bundle);
+ } else {
+ Callback.this.onCustomAction(action, extras);
+ }
}
}
@@ -1309,7 +1377,7 @@ public class MediaSessionCompat {
if (!mIsMbrRegistered && (mFlags & FLAG_HANDLES_MEDIA_BUTTONS) != 0) {
if (android.os.Build.VERSION.SDK_INT >= 18) {
MediaSessionCompatApi18.registerMediaButtonEventReceiver(mContext,
- mMediaButtonEventReceiver);
+ mMediaButtonEventReceiver, mComponentName);
} else {
MediaSessionCompatApi8.registerMediaButtonEventReceiver(mContext,
mComponentName);
@@ -1318,7 +1386,7 @@ public class MediaSessionCompat {
} else if (mIsMbrRegistered && (mFlags & FLAG_HANDLES_MEDIA_BUTTONS) == 0) {
if (android.os.Build.VERSION.SDK_INT >= 18) {
MediaSessionCompatApi18.unregisterMediaButtonEventReceiver(mContext,
- mMediaButtonEventReceiver);
+ mMediaButtonEventReceiver, mComponentName);
} else {
MediaSessionCompatApi8.unregisterMediaButtonEventReceiver(mContext,
mComponentName);
@@ -1348,7 +1416,7 @@ public class MediaSessionCompat {
if (mIsMbrRegistered) {
if (android.os.Build.VERSION.SDK_INT >= 18) {
MediaSessionCompatApi18.unregisterMediaButtonEventReceiver(mContext,
- mMediaButtonEventReceiver);
+ mMediaButtonEventReceiver, mComponentName);
} else {
MediaSessionCompatApi8.unregisterMediaButtonEventReceiver(mContext,
mComponentName);
@@ -1373,7 +1441,7 @@ public class MediaSessionCompat {
mVolumeProvider.onAdjustVolume(direction);
}
} else {
- mAudioManager.adjustStreamVolume(direction, mLocalStream, flags);
+ mAudioManager.adjustStreamVolume(mLocalStream, direction, flags);
}
}
@@ -1928,7 +1996,8 @@ public class MediaSessionCompat {
@Override
public void setCallback(Callback callback, Handler handler) {
- MediaSessionCompatApi21.setCallback(mSessionObj, callback.mCallbackObj, handler);
+ MediaSessionCompatApi21.setCallback(mSessionObj,
+ callback == null ? null : callback.mCallbackObj, handler);
}
@Override
@@ -1974,12 +2043,14 @@ public class MediaSessionCompat {
@Override
public void setPlaybackState(PlaybackStateCompat state) {
- MediaSessionCompatApi21.setPlaybackState(mSessionObj, state.getPlaybackState());
+ MediaSessionCompatApi21.setPlaybackState(mSessionObj,
+ state == null ? null : state.getPlaybackState());
}
@Override
public void setMetadata(MediaMetadataCompat metadata) {
- MediaSessionCompatApi21.setMetadata(mSessionObj, metadata.getMediaMetadata());
+ MediaSessionCompatApi21.setMetadata(mSessionObj,
+ metadata == null ? null : metadata.getMediaMetadata());
}
@Override
diff --git a/v4/java/android/support/v4/os/IResultReceiver.aidl b/v4/java/android/support/v4/os/IResultReceiver.aidl
new file mode 100644
index 0000000000..cd23ff3450
--- /dev/null
+++ b/v4/java/android/support/v4/os/IResultReceiver.aidl
@@ -0,0 +1,24 @@
+/*
+** Copyright 2015, 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.support.v4.os;
+
+import android.os.Bundle;
+
+/** @hide */
+oneway interface IResultReceiver {
+ void send(int resultCode, in Bundle resultData);
+}
diff --git a/v4/java/android/support/v4/os/ResultReceiver.aidl b/v4/java/android/support/v4/os/ResultReceiver.aidl
new file mode 100644
index 0000000000..81c81f6a93
--- /dev/null
+++ b/v4/java/android/support/v4/os/ResultReceiver.aidl
@@ -0,0 +1,19 @@
+/*
+** Copyright 2015, 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.support.v4.os;
+
+parcelable ResultReceiver;
diff --git a/v4/java/android/support/v4/os/ResultReceiver.java b/v4/java/android/support/v4/os/ResultReceiver.java
new file mode 100644
index 0000000000..f0dc00158a
--- /dev/null
+++ b/v4/java/android/support/v4/os/ResultReceiver.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2015 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.support.v4.os;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.support.v4.os.IResultReceiver;
+
+/**
+ * Generic interface for receiving a callback result from someone. Use this
+ * by creating a subclass and implement {@link #onReceiveResult}, which you can
+ * then pass to others and send through IPC, and receive results they
+ * supply with {@link #send}.
+ *
+ * <p>Note: the implementation underneath is just a simple wrapper around
+ * a {@link Binder} that is used to perform the communication. This means
+ * semantically you should treat it as such: this class does not impact process
+ * lifecycle management (you must be using some higher-level component to tell
+ * the system that your process needs to continue running), the connection will
+ * break if your process goes away for any reason, etc.</p>
+ * @hide
+ */
+public class ResultReceiver implements Parcelable {
+ final boolean mLocal;
+ final Handler mHandler;
+
+ IResultReceiver mReceiver;
+
+ class MyRunnable implements Runnable {
+ final int mResultCode;
+ final Bundle mResultData;
+
+ MyRunnable(int resultCode, Bundle resultData) {
+ mResultCode = resultCode;
+ mResultData = resultData;
+ }
+
+ public void run() {
+ onReceiveResult(mResultCode, mResultData);
+ }
+ }
+
+ class MyResultReceiver extends IResultReceiver.Stub {
+ public void send(int resultCode, Bundle resultData) {
+ if (mHandler != null) {
+ mHandler.post(new MyRunnable(resultCode, resultData));
+ } else {
+ onReceiveResult(resultCode, resultData);
+ }
+ }
+ }
+
+ /**
+ * Create a new ResultReceive to receive results. Your
+ * {@link #onReceiveResult} method will be called from the thread running
+ * <var>handler</var> if given, or from an arbitrary thread if null.
+ */
+ public ResultReceiver(Handler handler) {
+ mLocal = true;
+ mHandler = handler;
+ }
+
+ /**
+ * Deliver a result to this receiver. Will call {@link #onReceiveResult},
+ * always asynchronously if the receiver has supplied a Handler in which
+ * to dispatch the result.
+ * @param resultCode Arbitrary result code to deliver, as defined by you.
+ * @param resultData Any additional data provided by you.
+ */
+ public void send(int resultCode, Bundle resultData) {
+ if (mLocal) {
+ if (mHandler != null) {
+ mHandler.post(new MyRunnable(resultCode, resultData));
+ } else {
+ onReceiveResult(resultCode, resultData);
+ }
+ return;
+ }
+
+ if (mReceiver != null) {
+ try {
+ mReceiver.send(resultCode, resultData);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ /**
+ * Override to receive results delivered to this object.
+ *
+ * @param resultCode Arbitrary result code delivered by the sender, as
+ * defined by the sender.
+ * @param resultData Any additional data provided by the sender.
+ */
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ synchronized (this) {
+ if (mReceiver == null) {
+ mReceiver = new MyResultReceiver();
+ }
+ out.writeStrongBinder(mReceiver.asBinder());
+ }
+ }
+
+ ResultReceiver(Parcel in) {
+ mLocal = false;
+ mHandler = null;
+ mReceiver = IResultReceiver.Stub.asInterface(in.readStrongBinder());
+ }
+
+ public static final Parcelable.Creator<ResultReceiver> CREATOR
+ = new Parcelable.Creator<ResultReceiver>() {
+ public ResultReceiver createFromParcel(Parcel in) {
+ return new ResultReceiver(in);
+ }
+ public ResultReceiver[] newArray(int size) {
+ return new ResultReceiver[size];
+ }
+ };
+}
diff --git a/v4/java/android/support/v4/view/ActionProvider.java b/v4/java/android/support/v4/view/ActionProvider.java
index d195a3a5b6..070ea46517 100644
--- a/v4/java/android/support/v4/view/ActionProvider.java
+++ b/v4/java/android/support/v4/view/ActionProvider.java
@@ -60,6 +60,63 @@ import android.view.View;
* </code></pre>
* </li></ul></p>
*
+ * <h3>Creating a custom action provider</h3>
+ *
+ * <p>To create a custom action provider, extend ActionProvider and implement
+ * its callback methods as necessary. In particular, implement the following
+ * methods:</p>
+ *
+ * <dl>
+ * <dt>{@link #ActionProvider ActionProvider()} constructor</dt>
+ * <dd>This constructor is passed the application context. You should
+ * save the context in a member field to use in the other callback methods.</dd>
+ *
+ * <dt>{@link #onCreateActionView onCreateActionView(MenuItem)}</dt>
+ * <dd>The system calls this method when the action provider is created.
+ * You define the action provider's layout through the implementation of this
+ * method. Use the context acquired
+ * from the constructor to instantiate a {@link android.view.LayoutInflater} and
+ * inflate your action provider's layout from an XML resource, then hook up
+ * event listeners for the view's components. For example:
+ *
+ *<pre>
+ * public View onCreateActionView(MenuItem forItem) {
+ * // Inflate the action provider to be shown on the action bar.
+ * LayoutInflater layoutInflater = LayoutInflater.from(mContext);
+ * View providerView =
+ * layoutInflater.inflate(R.layout.my_action_provider, null);
+ * ImageButton button =
+ * (ImageButton) providerView.findViewById(R.id.button);
+ * button.setOnClickListener(new View.OnClickListener() {
+ * &#64;Override
+ * public void onClick(View v) {
+ * // Do something...
+ * }
+ * });
+ * return providerView;
+ * }</pre>
+ * </dd>
+ *
+ * <dt>{@link #onPerformDefaultAction onPerformDefaultAction()}</dt>
+ * <dd><p>The system calls this method when the user selects a menu item from the action
+ * overflow. The action provider should perform a default action for the
+ * menu item. The system does not call this method if the menu item opens a submenu.</p>
+ *
+ * <p>If your action provider presents a submenu through the
+ * {@link #onPrepareSubMenu onPrepareSubMenu()} callback, the submenu
+ * appears even if the action provider is in the overflow menu.
+ * Thus, the system never calls {@link #onPerformDefaultAction
+ * onPerformDefaultAction()} if there is a submenu.</p>
+ *
+ * <p class="note"> <strong>Note:</strong> An activity or a fragment that
+ * implements <code>onOptionsItemSelected()</code> can override the action
+ * provider's default behavior (unless it uses a submenu) by handling the
+ * item-selected event and returning <code>true</code>. In this case, the
+ * system does not call
+ * {@link #onPerformDefaultAction onPerformDefaultAction()}.</p></dd>
+ * </dl>
+ *
+ *
* @see android.support.v4.view.MenuItemCompat#setActionProvider(android.view.MenuItem, ActionProvider)
* @see android.support.v4.view.MenuItemCompat#getActionProvider(android.view.MenuItem)
*/
diff --git a/v4/java/android/support/v4/view/PagerAdapter.java b/v4/java/android/support/v4/view/PagerAdapter.java
index ef524047d0..55fb9c1324 100644
--- a/v4/java/android/support/v4/view/PagerAdapter.java
+++ b/v4/java/android/support/v4/view/PagerAdapter.java
@@ -76,7 +76,8 @@ import android.view.ViewGroup;
* the method {@link #getItemPosition(Object)}.</p>
*/
public abstract class PagerAdapter {
- private DataSetObservable mObservable = new DataSetObservable();
+ private final DataSetObservable mObservable = new DataSetObservable();
+ private DataSetObserver mViewPagerObserver;
public static final int POSITION_UNCHANGED = -1;
public static final int POSITION_NONE = -2;
@@ -273,6 +274,11 @@ public abstract class PagerAdapter {
* and associated views should update.
*/
public void notifyDataSetChanged() {
+ synchronized (this) {
+ if (mViewPagerObserver != null) {
+ mViewPagerObserver.onChanged();
+ }
+ }
mObservable.notifyChanged();
}
@@ -294,6 +300,12 @@ public abstract class PagerAdapter {
mObservable.unregisterObserver(observer);
}
+ void setViewPagerObserver(DataSetObserver observer) {
+ synchronized (this) {
+ mViewPagerObserver = observer;
+ }
+ }
+
/**
* This method may be called by the ViewPager to obtain a title string
* to describe the specified page. This method may return null
diff --git a/v4/java/android/support/v4/view/ViewCompat.java b/v4/java/android/support/v4/view/ViewCompat.java
index d3dce894bb..b88d7e5b92 100644
--- a/v4/java/android/support/v4/view/ViewCompat.java
+++ b/v4/java/android/support/v4/view/ViewCompat.java
@@ -27,6 +27,7 @@ import android.os.Bundle;
import android.support.annotation.FloatRange;
import android.support.annotation.IdRes;
import android.support.annotation.IntDef;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat;
@@ -276,6 +277,73 @@ public class ViewCompat {
*/
public static final int SCROLL_AXIS_VERTICAL = 1 << 1;
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true,
+ value = {
+ SCROLL_INDICATOR_TOP,
+ SCROLL_INDICATOR_BOTTOM,
+ SCROLL_INDICATOR_LEFT,
+ SCROLL_INDICATOR_RIGHT,
+ SCROLL_INDICATOR_START,
+ SCROLL_INDICATOR_END,
+ })
+ public @interface ScrollIndicators {}
+
+ /**
+ * Scroll indicator direction for the top edge of the view.
+ *
+ * @see #setScrollIndicators(int)
+ * @see #setScrollIndicators(int, int)
+ * @see #getScrollIndicators()
+ */
+ public static final int SCROLL_INDICATOR_TOP = 0x1;
+
+ /**
+ * Scroll indicator direction for the bottom edge of the view.
+ *
+ * @see #setScrollIndicators(int)
+ * @see #setScrollIndicators(int, int)
+ * @see #getScrollIndicators()
+ */
+ public static final int SCROLL_INDICATOR_BOTTOM = 0x2;
+
+ /**
+ * Scroll indicator direction for the left edge of the view.
+ *
+ * @see #setScrollIndicators(int)
+ * @see #setScrollIndicators(int, int)
+ * @see #getScrollIndicators()
+ */
+ public static final int SCROLL_INDICATOR_LEFT = 0x4;
+
+ /**
+ * Scroll indicator direction for the right edge of the view.
+ *
+ * @see #setScrollIndicators(int)
+ * @see #setScrollIndicators(int, int)
+ * @see #getScrollIndicators()
+ */
+ public static final int SCROLL_INDICATOR_RIGHT = 0x8;
+
+ /**
+ * Scroll indicator direction for the starting edge of the view.
+ *
+ * @see #setScrollIndicators(View, int)
+ * @see #setScrollIndicators(View, int, int)
+ * @see #getScrollIndicators(View)
+ */
+ public static final int SCROLL_INDICATOR_START = 0x10;
+
+ /**
+ * Scroll indicator direction for the ending edge of the view.
+ *
+ * @see #setScrollIndicators(int)
+ * @see #setScrollIndicators(int, int)
+ * @see #getScrollIndicators()
+ */
+ public static final int SCROLL_INDICATOR_END = 0x20;
+
interface ViewCompatImpl {
public boolean canScrollHorizontally(View v, int direction);
public boolean canScrollVertically(View v, int direction);
@@ -384,6 +452,10 @@ public class ViewCompat {
int combineMeasuredStates(int curState, int newState);
public float getZ(View view);
public boolean isAttachedToWindow(View view);
+ public boolean hasOnClickListeners(View view);
+ public void setScrollIndicators(View view, int indicators);
+ public void setScrollIndicators(View view, int indicators, int mask);
+ public int getScrollIndicators(View view);
}
static class BaseViewCompatImpl implements ViewCompatImpl {
@@ -963,6 +1035,26 @@ public class ViewCompat {
public boolean isAttachedToWindow(View view) {
return ViewCompatBase.isAttachedToWindow(view);
}
+
+ @Override
+ public boolean hasOnClickListeners(View view) {
+ return false;
+ }
+
+ @Override
+ public int getScrollIndicators(View view) {
+ return 0;
+ }
+
+ @Override
+ public void setScrollIndicators(View view, int indicators) {
+ // no-op
+ }
+
+ @Override
+ public void setScrollIndicators(View view, int indicators, int mask) {
+ // no-op
+ }
}
static class EclairMr1ViewCompatImpl extends BaseViewCompatImpl {
@@ -1222,7 +1314,14 @@ public class ViewCompat {
}
}
- static class JBViewCompatImpl extends ICSViewCompatImpl {
+ static class ICSMr1ViewCompatImpl extends ICSViewCompatImpl {
+ @Override
+ public boolean hasOnClickListeners(View view) {
+ return ViewCompatICSMr1.hasOnClickListeners(view);
+ }
+ }
+
+ static class JBViewCompatImpl extends ICSMr1ViewCompatImpl {
@Override
public boolean hasTransientState(View view) {
return ViewCompatJB.hasTransientState(view);
@@ -1529,10 +1628,29 @@ public class ViewCompat {
}
}
+ static class MarshmallowViewCompatImpl extends LollipopViewCompatImpl {
+ @Override
+ public void setScrollIndicators(View view, int indicators) {
+ ViewCompatMarshmallow.setScrollIndicators(view, indicators);
+ }
+
+ @Override
+ public void setScrollIndicators(View view, int indicators, int mask) {
+ ViewCompatMarshmallow.setScrollIndicators(view, indicators, mask);
+ }
+
+ @Override
+ public int getScrollIndicators(View view) {
+ return ViewCompatMarshmallow.getScrollIndicators(view);
+ }
+ }
+
static final ViewCompatImpl IMPL;
static {
final int version = android.os.Build.VERSION.SDK_INT;
- if (version >= 21) {
+ if (version >= 23) {
+ IMPL = new MarshmallowViewCompatImpl();
+ } else if (version >= 21) {
IMPL = new LollipopViewCompatImpl();
} else if (version >= 19) {
IMPL = new KitKatViewCompatImpl();
@@ -1540,6 +1658,8 @@ public class ViewCompat {
IMPL = new JbMr1ViewCompatImpl();
} else if (version >= 16) {
IMPL = new JBViewCompatImpl();
+ } else if (version >= 15) {
+ IMPL = new ICSMr1ViewCompatImpl();
} else if (version >= 14) {
IMPL = new ICSViewCompatImpl();
} else if (version >= 11) {
@@ -2513,7 +2633,7 @@ public class ViewCompat {
* @param value The y location of the pivot point.
*/
public static void setPivotY(View view, float value) {
- IMPL.setPivotX(view, value);
+ IMPL.setPivotY(view, value);
}
public static float getRotation(View view) {
@@ -3085,4 +3205,76 @@ public class ViewCompat {
public static boolean isAttachedToWindow(View view) {
return IMPL.isAttachedToWindow(view);
}
+
+ /**
+ * Returns whether the provided view has an attached {@link View.OnClickListener}.
+ *
+ * @return true if there is a listener, false if there is none.
+ */
+ public static boolean hasOnClickListeners(View view) {
+ return IMPL.hasOnClickListeners(view);
+ }
+
+ /**
+ * Sets the state of all scroll indicators.
+ * <p>
+ * See {@link #setScrollIndicators(View, int, int)} for usage information.
+ *
+ * @param indicators a bitmask of indicators that should be enabled, or
+ * {@code 0} to disable all indicators
+ *
+ * @see #setScrollIndicators(View, int, int)
+ * @see #getScrollIndicators(View)
+ */
+ public static void setScrollIndicators(@NonNull View view, @ScrollIndicators int indicators) {
+ IMPL.setScrollIndicators(view, indicators);
+ }
+
+ /**
+ * Sets the state of the scroll indicators specified by the mask. To change
+ * all scroll indicators at once, see {@link #setScrollIndicators(View, int)}.
+ * <p>
+ * When a scroll indicator is enabled, it will be displayed if the view
+ * can scroll in the direction of the indicator.
+ * <p>
+ * Multiple indicator types may be enabled or disabled by passing the
+ * logical OR of the desired types. If multiple types are specified, they
+ * will all be set to the same enabled state.
+ * <p>
+ * For example, to enable the top scroll indicatorExample: {@code setScrollIndicators}
+ *
+ * @param indicators the indicator direction, or the logical OR of multiple
+ * indicator directions. One or more of:
+ * <ul>
+ * <li>{@link #SCROLL_INDICATOR_TOP}</li>
+ * <li>{@link #SCROLL_INDICATOR_BOTTOM}</li>
+ * <li>{@link #SCROLL_INDICATOR_LEFT}</li>
+ * <li>{@link #SCROLL_INDICATOR_RIGHT}</li>
+ * <li>{@link #SCROLL_INDICATOR_START}</li>
+ * <li>{@link #SCROLL_INDICATOR_END}</li>
+ * </ul>
+ *
+ * @see #setScrollIndicators(View, int)
+ * @see #getScrollIndicators(View)
+ */
+ public static void setScrollIndicators(@NonNull View view, @ScrollIndicators int indicators,
+ @ScrollIndicators int mask) {
+ IMPL.setScrollIndicators(view, indicators, mask);
+ }
+
+ /**
+ * Returns a bitmask representing the enabled scroll indicators.
+ * <p>
+ * For example, if the top and left scroll indicators are enabled and all
+ * other indicators are disabled, the return value will be
+ * {@code ViewCompat.SCROLL_INDICATOR_TOP | ViewCompat.SCROLL_INDICATOR_LEFT}.
+ * <p>
+ * To check whether the bottom scroll indicator is enabled, use the value
+ * of {@code (ViewCompat.getScrollIndicators(view) & ViewCompat.SCROLL_INDICATOR_BOTTOM) != 0}.
+ *
+ * @return a bitmask representing the enabled scroll indicators
+ */
+ public static int getScrollIndicators(@NonNull View view) {
+ return IMPL.getScrollIndicators(view);
+ }
}
diff --git a/v4/java/android/support/v4/view/ViewPager.java b/v4/java/android/support/v4/view/ViewPager.java
index f19104a75c..c6f3648e32 100644
--- a/v4/java/android/support/v4/view/ViewPager.java
+++ b/v4/java/android/support/v4/view/ViewPager.java
@@ -144,7 +144,10 @@ public class ViewPager extends ViewGroup {
private int mRestoredCurItem = -1;
private Parcelable mRestoredAdapterState = null;
private ClassLoader mRestoredClassLoader = null;
+
private Scroller mScroller;
+ private boolean mIsScrollStarted;
+
private PagerObserver mObserver;
private int mPageMargin;
@@ -388,6 +391,10 @@ public class ViewPager extends ViewGroup {
@Override
protected void onDetachedFromWindow() {
removeCallbacks(mEndScrollRunnable);
+ // To be on the safe side, abort the scroller
+ if ((mScroller != null) && !mScroller.isFinished()) {
+ mScroller.abortAnimation();
+ }
super.onDetachedFromWindow();
}
@@ -411,7 +418,7 @@ public class ViewPager extends ViewGroup {
*/
public void setAdapter(PagerAdapter adapter) {
if (mAdapter != null) {
- mAdapter.unregisterDataSetObserver(mObserver);
+ mAdapter.setViewPagerObserver(null);
mAdapter.startUpdate(this);
for (int i = 0; i < mItems.size(); i++) {
final ItemInfo ii = mItems.get(i);
@@ -432,7 +439,7 @@ public class ViewPager extends ViewGroup {
if (mObserver == null) {
mObserver = new PagerObserver();
}
- mAdapter.registerDataSetObserver(mObserver);
+ mAdapter.setViewPagerObserver(mObserver);
mPopulatePending = false;
final boolean wasFirstLayout = mFirstLayout;
mFirstLayout = true;
@@ -829,7 +836,21 @@ public class ViewPager extends ViewGroup {
setScrollingCacheEnabled(false);
return;
}
- int sx = getScrollX();
+
+ int sx;
+ boolean wasScrolling = (mScroller != null) && !mScroller.isFinished();
+ if (wasScrolling) {
+ // We're in the middle of a previously initiated scrolling. Check to see
+ // whether that scrolling has actually started (if we always call getStartX
+ // we can get a stale value from the scroller if it hadn't yet had its first
+ // computeScrollOffset call) to decide what is the current scrolling position.
+ sx = mIsScrollStarted ? mScroller.getCurrX() : mScroller.getStartX();
+ // And abort the current scrolling.
+ mScroller.abortAnimation();
+ setScrollingCacheEnabled(false);
+ } else {
+ sx = getScrollX();
+ }
int sy = getScrollY();
int dx = x - sx;
int dy = y - sy;
@@ -849,7 +870,7 @@ public class ViewPager extends ViewGroup {
final float distance = halfWidth + halfWidth *
distanceInfluenceForSnapDuration(distanceRatio);
- int duration = 0;
+ int duration;
velocity = Math.abs(velocity);
if (velocity > 0) {
duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
@@ -860,6 +881,9 @@ public class ViewPager extends ViewGroup {
}
duration = Math.min(duration, MAX_SETTLE_DURATION);
+ // Reset the "scroll started" flag. It will be flipped to true in all places
+ // where we call computeScrollOffset().
+ mIsScrollStarted = false;
mScroller.startScroll(sx, sy, dx, dy, duration);
ViewCompat.postInvalidateOnAnimation(this);
}
@@ -1642,6 +1666,7 @@ public class ViewPager extends ViewGroup {
@Override
public void computeScroll() {
+ mIsScrollStarted = true;
if (!mScroller.isFinished() && mScroller.computeScrollOffset()) {
int oldX = getScrollX();
int oldY = getScrollY();
@@ -1822,15 +1847,18 @@ public class ViewPager extends ViewGroup {
if (needPopulate) {
// Done with scroll, no longer want to cache view drawing.
setScrollingCacheEnabled(false);
- mScroller.abortAnimation();
- int oldX = getScrollX();
- int oldY = getScrollY();
- int x = mScroller.getCurrX();
- int y = mScroller.getCurrY();
- if (oldX != x || oldY != y) {
- scrollTo(x, y);
- if (x != oldX) {
- pageScrolled(x);
+ boolean wasScrolling = !mScroller.isFinished();
+ if (wasScrolling) {
+ mScroller.abortAnimation();
+ int oldX = getScrollX();
+ int oldY = getScrollY();
+ int x = mScroller.getCurrX();
+ int y = mScroller.getCurrY();
+ if (oldX != x || oldY != y) {
+ scrollTo(x, y);
+ if (x != oldX) {
+ pageScrolled(x);
+ }
}
}
}
@@ -1878,13 +1906,7 @@ public class ViewPager extends ViewGroup {
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
// Release the drag.
if (DEBUG) Log.v(TAG, "Intercept done!");
- mIsBeingDragged = false;
- mIsUnableToDrag = false;
- mActivePointerId = INVALID_POINTER;
- if (mVelocityTracker != null) {
- mVelocityTracker.recycle();
- mVelocityTracker = null;
- }
+ resetTouch();
return false;
}
@@ -1970,6 +1992,7 @@ public class ViewPager extends ViewGroup {
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
mIsUnableToDrag = false;
+ mIsScrollStarted = true;
mScroller.computeScrollOffset();
if (mScrollState == SCROLL_STATE_SETTLING &&
Math.abs(mScroller.getFinalX() - mScroller.getCurrX()) > mCloseEnough) {
@@ -2051,6 +2074,11 @@ public class ViewPager extends ViewGroup {
case MotionEvent.ACTION_MOVE:
if (!mIsBeingDragged) {
final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
+ if (pointerIndex == -1) {
+ // A child has consumed some touch events and put us into an inconsistent state.
+ needsInvalidate = resetTouch();
+ break;
+ }
final float x = MotionEventCompat.getX(ev, pointerIndex);
final float xDiff = Math.abs(x - mLastMotionX);
final float y = MotionEventCompat.getY(ev, pointerIndex);
@@ -2102,17 +2130,13 @@ public class ViewPager extends ViewGroup {
totalDelta);
setCurrentItemInternal(nextPage, true, true, initialVelocity);
- mActivePointerId = INVALID_POINTER;
- endDrag();
- needsInvalidate = mLeftEdge.onRelease() | mRightEdge.onRelease();
+ needsInvalidate = resetTouch();
}
break;
case MotionEvent.ACTION_CANCEL:
if (mIsBeingDragged) {
scrollToItem(mCurItem, true, 0, false);
- mActivePointerId = INVALID_POINTER;
- endDrag();
- needsInvalidate = mLeftEdge.onRelease() | mRightEdge.onRelease();
+ needsInvalidate = resetTouch();
}
break;
case MotionEventCompat.ACTION_POINTER_DOWN: {
@@ -2134,6 +2158,14 @@ public class ViewPager extends ViewGroup {
return true;
}
+ private boolean resetTouch() {
+ boolean needsInvalidate;
+ mActivePointerId = INVALID_POINTER;
+ endDrag();
+ needsInvalidate = mLeftEdge.onRelease() | mRightEdge.onRelease();
+ return needsInvalidate;
+ }
+
private void requestParentDisallowInterceptTouchEvent(boolean disallowIntercept) {
final ViewParent parent = getParent();
if (parent != null) {
diff --git a/v4/java/android/support/v4/widget/DrawerLayout.java b/v4/java/android/support/v4/widget/DrawerLayout.java
index a9560ad7b0..549b8eadbc 100644
--- a/v4/java/android/support/v4/widget/DrawerLayout.java
+++ b/v4/java/android/support/v4/widget/DrawerLayout.java
@@ -59,17 +59,20 @@ import java.util.List;
/**
* DrawerLayout acts as a top-level container for window content that allows for
- * interactive "drawer" views to be pulled out from the edge of the window.
+ * interactive "drawer" views to be pulled out from one or both vertical edges of the window.
*
* <p>Drawer positioning and layout is controlled using the <code>android:layout_gravity</code>
* attribute on child views corresponding to which side of the view you want the drawer
- * to emerge from: left or right. (Or start/end on platform versions that support layout direction.)
+ * to emerge from: left or right (or start/end on platform versions that support layout direction.)
+ * Note that you can only have one drawer view for each vertical edge of the window. If your
+ * layout configures more than one drawer view per vertical edge of the window, an exception will
+ * be thrown at runtime.
* </p>
*
* <p>To use a DrawerLayout, position your primary content view as the first child with
- * a width and height of <code>match_parent</code>. Add drawers as child views after the main
- * content view and set the <code>layout_gravity</code> appropriately. Drawers commonly use
- * <code>match_parent</code> for height with a fixed width.</p>
+ * width and height of <code>match_parent</code> and no <code>layout_gravity></code>.
+ * Add drawers as child views after the main content view and set the <code>layout_gravity</code>
+ * appropriately. Drawers commonly use <code>match_parent</code> for height with a fixed width.</p>
*
* <p>{@link DrawerListener} can be used to monitor the state and motion of drawer views.
* Avoid performing expensive operations such as layout during animation as it can cause
@@ -110,7 +113,8 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
public static final int STATE_SETTLING = ViewDragHelper.STATE_SETTLING;
/** @hide */
- @IntDef({LOCK_MODE_UNLOCKED, LOCK_MODE_LOCKED_CLOSED, LOCK_MODE_LOCKED_OPEN})
+ @IntDef({LOCK_MODE_UNLOCKED, LOCK_MODE_LOCKED_CLOSED, LOCK_MODE_LOCKED_OPEN,
+ LOCK_MODE_UNDEFINED})
@Retention(RetentionPolicy.SOURCE)
private @interface LockMode {}
@@ -131,6 +135,11 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
*/
public static final int LOCK_MODE_LOCKED_OPEN = 2;
+ /**
+ * The drawer's lock state is reset to default.
+ */
+ public static final int LOCK_MODE_UNDEFINED = 3;
+
/** @hide */
@IntDef({Gravity.LEFT, Gravity.RIGHT, GravityCompat.START, GravityCompat.END})
@Retention(RetentionPolicy.SOURCE)
@@ -189,8 +198,12 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
private int mDrawerState;
private boolean mInLayout;
private boolean mFirstLayout = true;
- private int mLockModeLeft;
- private int mLockModeRight;
+
+ private @LockMode int mLockModeLeft = LOCK_MODE_UNDEFINED;
+ private @LockMode int mLockModeRight = LOCK_MODE_UNDEFINED;
+ private @LockMode int mLockModeStart = LOCK_MODE_UNDEFINED;
+ private @LockMode int mLockModeEnd = LOCK_MODE_UNDEFINED;
+
private boolean mDisallowInterceptRequested;
private boolean mChildrenCanceledTouch;
@@ -544,11 +557,22 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
public void setDrawerLockMode(@LockMode int lockMode, @EdgeGravity int edgeGravity) {
final int absGravity = GravityCompat.getAbsoluteGravity(edgeGravity,
ViewCompat.getLayoutDirection(this));
- if (absGravity == Gravity.LEFT) {
- mLockModeLeft = lockMode;
- } else if (absGravity == Gravity.RIGHT) {
- mLockModeRight = lockMode;
+
+ switch (edgeGravity) {
+ case Gravity.LEFT:
+ mLockModeLeft = lockMode;
+ break;
+ case Gravity.RIGHT:
+ mLockModeRight = lockMode;
+ break;
+ case GravityCompat.START:
+ mLockModeStart = lockMode;
+ break;
+ case GravityCompat.END:
+ mLockModeEnd = lockMode;
+ break;
}
+
if (lockMode != LOCK_MODE_UNLOCKED) {
// Cancel interaction in progress
final ViewDragHelper helper = absGravity == Gravity.LEFT ? mLeftDragger : mRightDragger;
@@ -566,8 +590,8 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
if (toClose != null) {
closeDrawer(toClose);
}
- break;
- // default: do nothing
+ break;
+ // default: do nothing
}
}
@@ -607,13 +631,51 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
*/
@LockMode
public int getDrawerLockMode(@EdgeGravity int edgeGravity) {
- final int absGravity = GravityCompat.getAbsoluteGravity(
- edgeGravity, ViewCompat.getLayoutDirection(this));
- if (absGravity == Gravity.LEFT) {
- return mLockModeLeft;
- } else if (absGravity == Gravity.RIGHT) {
- return mLockModeRight;
+ int layoutDirection = ViewCompat.getLayoutDirection(this);
+
+ switch (edgeGravity) {
+ case Gravity.LEFT:
+ if (mLockModeLeft != LOCK_MODE_UNDEFINED) {
+ return mLockModeLeft;
+ }
+ int leftLockMode = (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) ?
+ mLockModeStart : mLockModeEnd;
+ if (leftLockMode != LOCK_MODE_UNDEFINED) {
+ return leftLockMode;
+ }
+ break;
+ case Gravity.RIGHT:
+ if (mLockModeRight != LOCK_MODE_UNDEFINED) {
+ return mLockModeRight;
+ }
+ int rightLockMode = (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) ?
+ mLockModeEnd : mLockModeStart;
+ if (rightLockMode != LOCK_MODE_UNDEFINED) {
+ return rightLockMode;
+ }
+ break;
+ case GravityCompat.START:
+ if (mLockModeStart != LOCK_MODE_UNDEFINED) {
+ return mLockModeStart;
+ }
+ int startLockMode = (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) ?
+ mLockModeLeft : mLockModeRight;
+ if (startLockMode != LOCK_MODE_UNDEFINED) {
+ return startLockMode;
+ }
+ break;
+ case GravityCompat.END:
+ if (mLockModeEnd != LOCK_MODE_UNDEFINED) {
+ return mLockModeEnd;
+ }
+ int endLockMode = (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) ?
+ mLockModeRight : mLockModeLeft;
+ if (endLockMode != LOCK_MODE_UNDEFINED) {
+ return endLockMode;
+ }
+ break;
}
+
return LOCK_MODE_UNLOCKED;
}
@@ -626,13 +688,8 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
*/
@LockMode
public int getDrawerLockMode(View drawerView) {
- final int absGravity = getDrawerViewAbsoluteGravity(drawerView);
- if (absGravity == Gravity.LEFT) {
- return mLockModeLeft;
- } else if (absGravity == Gravity.RIGHT) {
- return mLockModeRight;
- }
- return LOCK_MODE_UNLOCKED;
+ final int drawerGravity = ((LayoutParams) drawerView.getLayoutParams()).gravity;
+ return getDrawerLockMode(drawerGravity);
}
/**
@@ -712,8 +769,8 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
void dispatchOnDrawerClosed(View drawerView) {
final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams();
- if (lp.knownOpen) {
- lp.knownOpen = false;
+ if ((lp.openState & LayoutParams.FLAG_IS_OPENED) == 1) {
+ lp.openState = 0;
if (mListener != null) {
mListener.onDrawerClosed(drawerView);
}
@@ -734,8 +791,8 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
void dispatchOnDrawerOpened(View drawerView) {
final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams();
- if (!lp.knownOpen) {
- lp.knownOpen = true;
+ if ((lp.openState & LayoutParams.FLAG_IS_OPENED) == 0) {
+ lp.openState = LayoutParams.FLAG_IS_OPENED;
if (mListener != null) {
mListener.onDrawerOpened(drawerView);
}
@@ -806,7 +863,8 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
- if (((LayoutParams) child.getLayoutParams()).knownOpen) {
+ final LayoutParams childLp = (LayoutParams) child.getLayoutParams();
+ if ((childLp.openState & LayoutParams.FLAG_IS_OPENED) == 1) {
return child;
}
}
@@ -951,6 +1009,7 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
gravityToString(childGravity) + " but this " + TAG + " already has a " +
"drawer view along that edge");
}
+ foundDrawers = foundDrawers | childGravity;
final int drawerWidthSpec = getChildMeasureSpec(widthMeasureSpec,
mMinDrawerMargin + lp.leftMargin + lp.rightMargin,
lp.width);
@@ -1435,13 +1494,15 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
throw new IllegalArgumentException("View " + drawerView + " is not a sliding drawer");
}
+ final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams();
if (mFirstLayout) {
- final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams();
lp.onScreen = 1.f;
- lp.knownOpen = true;
+ lp.openState = LayoutParams.FLAG_IS_OPENED;
updateChildrenImportantForAccessibility(drawerView, true);
} else {
+ lp.openState |= LayoutParams.FLAG_IS_OPENING;
+
if (checkDrawerViewAbsoluteGravity(drawerView, Gravity.LEFT)) {
mLeftDragger.smoothSlideViewTo(drawerView, 0, drawerView.getTop());
} else {
@@ -1477,11 +1538,13 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
throw new IllegalArgumentException("View " + drawerView + " is not a sliding drawer");
}
+ final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams();
if (mFirstLayout) {
- final LayoutParams lp = (LayoutParams) drawerView.getLayoutParams();
lp.onScreen = 0.f;
- lp.knownOpen = false;
+ lp.openState = 0;
} else {
+ lp.openState |= LayoutParams.FLAG_IS_CLOSING;
+
if (checkDrawerViewAbsoluteGravity(drawerView, Gravity.LEFT)) {
mLeftDragger.smoothSlideViewTo(drawerView, -drawerView.getWidth(),
drawerView.getTop());
@@ -1521,7 +1584,8 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
if (!isDrawerView(drawer)) {
throw new IllegalArgumentException("View " + drawer + " is not a drawer");
}
- return ((LayoutParams) drawer.getLayoutParams()).knownOpen;
+ LayoutParams drawerLp = (LayoutParams) drawer.getLayoutParams();
+ return (drawerLp.openState & LayoutParams.FLAG_IS_OPENED) == 1;
}
/**
@@ -1705,8 +1769,18 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
}
}
- setDrawerLockMode(ss.lockModeLeft, Gravity.LEFT);
- setDrawerLockMode(ss.lockModeRight, Gravity.RIGHT);
+ if (ss.lockModeLeft != LOCK_MODE_UNDEFINED) {
+ setDrawerLockMode(ss.lockModeLeft, Gravity.LEFT);
+ }
+ if (ss.lockModeRight != LOCK_MODE_UNDEFINED) {
+ setDrawerLockMode(ss.lockModeRight, Gravity.RIGHT);
+ }
+ if (ss.lockModeStart != LOCK_MODE_UNDEFINED) {
+ setDrawerLockMode(ss.lockModeStart, GravityCompat.START);
+ }
+ if (ss.lockModeEnd != LOCK_MODE_UNDEFINED) {
+ setDrawerLockMode(ss.lockModeEnd, GravityCompat.END);
+ }
}
@Override
@@ -1714,13 +1788,26 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
final Parcelable superState = super.onSaveInstanceState();
final SavedState ss = new SavedState(superState);
- final View openDrawer = findOpenDrawer();
- if (openDrawer != null) {
- ss.openDrawerGravity = ((LayoutParams) openDrawer.getLayoutParams()).gravity;
+ final int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ final View child = getChildAt(i);
+ LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ // Is the current child fully opened (that is, not closing)?
+ boolean isOpenedAndNotClosing = (lp.openState == LayoutParams.FLAG_IS_OPENED);
+ // Is the current child opening?
+ boolean isClosedAndOpening = (lp.openState == LayoutParams.FLAG_IS_OPENING);
+ if (isOpenedAndNotClosing || isClosedAndOpening) {
+ // If one of the conditions above holds, save the child's gravity
+ // so that we open that child during state restore.
+ ss.openDrawerGravity = lp.gravity;
+ break;
+ }
}
ss.lockModeLeft = mLockModeLeft;
ss.lockModeRight = mLockModeRight;
+ ss.lockModeStart = mLockModeStart;
+ ss.lockModeEnd = mLockModeEnd;
return ss;
}
@@ -1766,12 +1853,18 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
*/
protected static class SavedState extends BaseSavedState {
int openDrawerGravity = Gravity.NO_GRAVITY;
- int lockModeLeft = LOCK_MODE_UNLOCKED;
- int lockModeRight = LOCK_MODE_UNLOCKED;
+ @LockMode int lockModeLeft;
+ @LockMode int lockModeRight;
+ @LockMode int lockModeStart;
+ @LockMode int lockModeEnd;
public SavedState(Parcel in) {
super(in);
openDrawerGravity = in.readInt();
+ lockModeLeft = in.readInt();
+ lockModeRight = in.readInt();
+ lockModeStart = in.readInt();
+ lockModeEnd = in.readInt();
}
public SavedState(Parcelable superState) {
@@ -1782,6 +1875,10 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(openDrawerGravity);
+ dest.writeInt(lockModeLeft);
+ dest.writeInt(lockModeRight);
+ dest.writeInt(lockModeStart);
+ dest.writeInt(lockModeEnd);
}
public static final Parcelable.Creator<SavedState> CREATOR =
@@ -1965,11 +2062,14 @@ public class DrawerLayout extends ViewGroup implements DrawerLayoutImpl {
}
public static class LayoutParams extends ViewGroup.MarginLayoutParams {
+ private static final int FLAG_IS_OPENED = 0x1;
+ private static final int FLAG_IS_OPENING = 0x2;
+ private static final int FLAG_IS_CLOSING = 0x4;
public int gravity = Gravity.NO_GRAVITY;
- float onScreen;
- boolean isPeeking;
- boolean knownOpen;
+ private float onScreen;
+ private boolean isPeeking;
+ private int openState;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
diff --git a/v4/java/android/support/v4/widget/NestedScrollView.java b/v4/java/android/support/v4/widget/NestedScrollView.java
index 788761a571..27e43076d9 100644
--- a/v4/java/android/support/v4/widget/NestedScrollView.java
+++ b/v4/java/android/support/v4/widget/NestedScrollView.java
@@ -31,6 +31,7 @@ import android.support.v4.view.NestedScrollingChild;
import android.support.v4.view.NestedScrollingChildHelper;
import android.support.v4.view.NestedScrollingParent;
import android.support.v4.view.NestedScrollingParentHelper;
+import android.support.v4.view.ScrollingView;
import android.support.v4.view.VelocityTrackerCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
@@ -61,13 +62,35 @@ import java.util.List;
* Nested scrolling is enabled by default.
*/
public class NestedScrollView extends FrameLayout implements NestedScrollingParent,
- NestedScrollingChild {
+ NestedScrollingChild, ScrollingView {
static final int ANIMATED_SCROLL_GAP = 250;
static final float MAX_SCROLL_FACTOR = 0.5f;
private static final String TAG = "NestedScrollView";
+ /**
+ * Interface definition for a callback to be invoked when the scroll
+ * X or Y positions of a view change.
+ *
+ * <p>This version of the interface works on all versions of Android, back to API v4.</p>
+ *
+ * @see #setOnScrollChangeListener(OnScrollChangeListener)
+ */
+ public interface OnScrollChangeListener {
+ /**
+ * Called when the scroll position of a view changes.
+ *
+ * @param v The view whose scroll position has changed.
+ * @param scrollX Current horizontal scroll origin.
+ * @param scrollY Current vertical scroll origin.
+ * @param oldScrollX Previous horizontal scroll origin.
+ * @param oldScrollY Previous vertical scroll origin.
+ */
+ void onScrollChange(NestedScrollView v, int scrollX, int scrollY,
+ int oldScrollX, int oldScrollY);
+ }
+
private long mLastScroll;
private final Rect mTempRect = new Rect();
@@ -153,6 +176,8 @@ public class NestedScrollView extends FrameLayout implements NestedScrollingPare
private float mVerticalScrollFactor;
+ private OnScrollChangeListener mOnScrollChangeListener;
+
public NestedScrollView(Context context) {
this(context, null);
}
@@ -245,6 +270,7 @@ public class NestedScrollView extends FrameLayout implements NestedScrollingPare
@Override
public void onStopNestedScroll(View target) {
+ mParentHelper.onStopNestedScroll(target);
stopNestedScroll();
}
@@ -376,6 +402,19 @@ public class NestedScrollView extends FrameLayout implements NestedScrollingPare
}
/**
+ * Register a callback to be invoked when the scroll X or Y positions of
+ * this view change.
+ * <p>This version of the method works on all versions of Android, back to API v4.</p>
+ *
+ * @param l The listener to notify when the scroll X or Y position changes.
+ * @see android.view.View#getScrollX()
+ * @see android.view.View#getScrollY()
+ */
+ public void setOnScrollChangeListener(OnScrollChangeListener l) {
+ mOnScrollChangeListener = l;
+ }
+
+ /**
* @return Returns true this ScrollView can be scrolled
*/
private boolean canScroll() {
@@ -430,6 +469,15 @@ public class NestedScrollView extends FrameLayout implements NestedScrollingPare
}
@Override
+ protected void onScrollChanged(int l, int t, int oldl, int oldt) {
+ super.onScrollChanged(l, t, oldl, oldt);
+
+ if (mOnScrollChangeListener != null) {
+ mOnScrollChangeListener.onScrollChange(this, l, t, oldl, oldt);
+ }
+ }
+
+ @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -576,13 +624,6 @@ public class NestedScrollView extends FrameLayout implements NestedScrollingPare
return true;
}
- /*
- * Don't try to intercept touch if we can't scroll anyway.
- */
- if (getScrollY() == 0 && !ViewCompat.canScrollVertically(this, 1)) {
- return false;
- }
-
switch (action & MotionEventCompat.ACTION_MASK) {
case MotionEvent.ACTION_MOVE: {
/*
@@ -657,6 +698,9 @@ public class NestedScrollView extends FrameLayout implements NestedScrollingPare
mIsBeingDragged = false;
mActivePointerId = INVALID_POINTER;
recycleVelocityTracker();
+ if (mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0, getScrollRange())) {
+ ViewCompat.postInvalidateOnAnimation(this);
+ }
stopNestedScroll();
break;
case MotionEventCompat.ACTION_POINTER_UP:
@@ -795,17 +839,23 @@ public class NestedScrollView extends FrameLayout implements NestedScrollingPare
if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
flingWithNestedDispatch(-initialVelocity);
+ } else if (mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0,
+ getScrollRange())) {
+ ViewCompat.postInvalidateOnAnimation(this);
}
-
- mActivePointerId = INVALID_POINTER;
- endDrag();
}
+ mActivePointerId = INVALID_POINTER;
+ endDrag();
break;
case MotionEvent.ACTION_CANCEL:
if (mIsBeingDragged && getChildCount() > 0) {
- mActivePointerId = INVALID_POINTER;
- endDrag();
+ if (mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0,
+ getScrollRange())) {
+ ViewCompat.postInvalidateOnAnimation(this);
+ }
}
+ mActivePointerId = INVALID_POINTER;
+ endDrag();
break;
case MotionEventCompat.ACTION_POINTER_DOWN: {
final int index = MotionEventCompat.getActionIndex(ev);
@@ -942,6 +992,10 @@ public class NestedScrollView extends FrameLayout implements NestedScrollingPare
clampedY = true;
}
+ if (clampedY) {
+ mScroller.springBack(newScrollX, newScrollY, 0, 0, 0, getScrollRange());
+ }
+
onOverScrolled(newScrollX, newScrollY, clampedX, clampedY);
return clampedX || clampedY;
@@ -1280,9 +1334,10 @@ public class NestedScrollView extends FrameLayout implements NestedScrollingPare
/**
* <p>The scroll range of a scroll view is the overall height of all of its
* children.</p>
+ * @hide
*/
@Override
- protected int computeVerticalScrollRange() {
+ public int computeVerticalScrollRange() {
final int count = getChildCount();
final int contentHeight = getHeight() - getPaddingBottom() - getPaddingTop();
if (count == 0) {
@@ -1301,11 +1356,36 @@ public class NestedScrollView extends FrameLayout implements NestedScrollingPare
return scrollRange;
}
+ /** @hide */
@Override
- protected int computeVerticalScrollOffset() {
+ public int computeVerticalScrollOffset() {
return Math.max(0, super.computeVerticalScrollOffset());
}
+ /** @hide */
+ @Override
+ public int computeVerticalScrollExtent() {
+ return super.computeVerticalScrollExtent();
+ }
+
+ /** @hide */
+ @Override
+ public int computeHorizontalScrollRange() {
+ return super.computeHorizontalScrollRange();
+ }
+
+ /** @hide */
+ @Override
+ public int computeHorizontalScrollOffset() {
+ return super.computeHorizontalScrollOffset();
+ }
+
+ /** @hide */
+ @Override
+ public int computeHorizontalScrollExtent() {
+ return super.computeHorizontalScrollExtent();
+ }
+
@Override
protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) {
ViewGroup.LayoutParams lp = child.getLayoutParams();
diff --git a/v4/java/android/support/v4/widget/ScrollerCompat.java b/v4/java/android/support/v4/widget/ScrollerCompat.java
index afbf89704e..3115a415ec 100644
--- a/v4/java/android/support/v4/widget/ScrollerCompat.java
+++ b/v4/java/android/support/v4/widget/ScrollerCompat.java
@@ -54,6 +54,8 @@ public class ScrollerCompat {
boolean isOverScrolled(Object scroller);
int getFinalX(Object scroller);
int getFinalY(Object scroller);
+ boolean springBack(Object scroller, int startX, int startY, int minX, int maxX,
+ int minY, int maxY);
}
static final int CHASE_FRAME_TIME = 16; // ms per target frame
@@ -145,6 +147,12 @@ public class ScrollerCompat {
public int getFinalY(Object scroller) {
return ((Scroller) scroller).getFinalY();
}
+
+ @Override
+ public boolean springBack(Object scroller, int startX, int startY, int minX, int maxX,
+ int minY, int maxY) {
+ return false;
+ }
}
static class ScrollerCompatImplGingerbread implements ScrollerCompatImpl {
@@ -233,6 +241,13 @@ public class ScrollerCompat {
public int getFinalY(Object scroller) {
return ScrollerCompatGingerbread.getFinalY(scroller);
}
+
+ @Override
+ public boolean springBack(Object scroller, int startX, int startY, int minX, int maxX,
+ int minY, int maxY) {
+ return ScrollerCompatGingerbread.springBack(scroller, startX, startY, minX, maxX,
+ minY, maxY);
+ }
}
static class ScrollerCompatImplIcs extends ScrollerCompatImplGingerbread {
@@ -423,6 +438,22 @@ public class ScrollerCompat {
}
/**
+ * Call this when you want to 'spring back' into a valid coordinate range.
+ *
+ * @param startX Starting X coordinate
+ * @param startY Starting Y coordinate
+ * @param minX Minimum valid X value
+ * @param maxX Maximum valid X value
+ * @param minY Minimum valid Y value
+ * @param maxY Maximum valid Y value
+ * @return true if a springback was initiated, false if startX and startY were
+ * already within the valid range.
+ */
+ public boolean springBack(int startX, int startY, int minX, int maxX, int minY, int maxY) {
+ return mImpl.springBack(mScroller, startX, startY, minX, maxX, minY, maxY);
+ }
+
+ /**
* Stops the animation. Aborting the animation causes the scroller to move to the final x and y
* position.
*/
diff --git a/v4/java/android/support/v4/widget/SwipeRefreshLayout.java b/v4/java/android/support/v4/widget/SwipeRefreshLayout.java
index d6b35ef1be..06db6f2f29 100644
--- a/v4/java/android/support/v4/widget/SwipeRefreshLayout.java
+++ b/v4/java/android/support/v4/widget/SwipeRefreshLayout.java
@@ -102,6 +102,7 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare
private boolean mRefreshing = false;
private int mTouchSlop;
private float mTotalDragDistance = -1;
+
// If nested scrolling is enabled, the total amount that needed to be
// consumed by this as the nested scrolling parent is used in place of the
// overscroll determined by MOVE events in the onTouch handler
@@ -109,6 +110,8 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare
private final NestedScrollingParentHelper mNestedScrollingParentHelper;
private final NestedScrollingChildHelper mNestedScrollingChildHelper;
private final int[] mParentScrollConsumed = new int[2];
+ private final int[] mParentOffsetInWindow = new int[2];
+ private boolean mNestedScrollInProgress;
private int mMediumAnimationDuration;
private int mCurrentTargetOffsetTop;
@@ -182,22 +185,34 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare
mListener.onRefresh();
}
}
+ mCurrentTargetOffsetTop = mCircleView.getTop();
} else {
- mProgress.stop();
- mCircleView.setVisibility(View.GONE);
- setColorViewAlpha(MAX_ALPHA);
- // Return the circle to its start position
- if (mScale) {
- setAnimationProgress(0 /* animation complete and view is hidden */);
- } else {
- setTargetOffsetTopAndBottom(mOriginalOffsetTop - mCurrentTargetOffsetTop,
- true /* requires update */);
- }
+ reset();
}
- mCurrentTargetOffsetTop = mCircleView.getTop();
}
};
+ private void reset() {
+ mCircleView.clearAnimation();
+ mProgress.stop();
+ mCircleView.setVisibility(View.GONE);
+ setColorViewAlpha(MAX_ALPHA);
+ // Return the circle to its start position
+ if (mScale) {
+ setAnimationProgress(0 /* animation complete and view is hidden */);
+ } else {
+ setTargetOffsetTopAndBottom(mOriginalOffsetTop - mCurrentTargetOffsetTop,
+ true /* requires update */);
+ }
+ mCurrentTargetOffsetTop = mCircleView.getTop();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ reset();
+ }
+
private void setColorViewAlpha(int targetAlpha) {
mCircleView.getBackground().setAlpha(targetAlpha);
mProgress.setAlpha(targetAlpha);
@@ -654,7 +669,8 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare
mReturningToStart = false;
}
- if (!isEnabled() || mReturningToStart || canChildScrollUp() || mRefreshing) {
+ if (!isEnabled() || mReturningToStart || canChildScrollUp()
+ || mRefreshing || mNestedScrollInProgress) {
// Fail fast if we're not in a state where a swipe is possible
return false;
}
@@ -728,19 +744,18 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare
@Override
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
- if (isEnabled() && (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0) {
- // Dispatch up to the nested parent
- startNestedScroll(nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL);
- return true;
- }
- return false;
+ return isEnabled() && canChildScrollUp() && !mReturningToStart && !mRefreshing
+ && (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
}
@Override
public void onNestedScrollAccepted(View child, View target, int axes) {
// Reset the counter of how much leftover scroll needs to be consumed.
mNestedScrollingParentHelper.onNestedScrollAccepted(child, target, axes);
+ // Dispatch up to the nested parent
+ startNestedScroll(axes & ViewCompat.SCROLL_AXIS_VERTICAL);
mTotalUnconsumed = 0;
+ mNestedScrollInProgress = true;
}
@Override
@@ -759,6 +774,15 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare
moveSpinner(mTotalUnconsumed);
}
+ // If a client layout is using a custom start position for the circle
+ // view, they mean to hide it again before scrolling the child view
+ // If we get back to mTotalUnconsumed == 0 and there is more to go, hide
+ // the circle so it isn't exposed if its blocking content is moved
+ if (mUsingCustomStart && dy > 0 && mTotalUnconsumed == 0
+ && Math.abs(dy - consumed[1]) > 0) {
+ mCircleView.setVisibility(View.GONE);
+ }
+
// Now let our nested parent consume the leftovers
final int[] parentConsumed = mParentScrollConsumed;
if (dispatchNestedPreScroll(dx - consumed[0], dy - consumed[1], parentConsumed, null)) {
@@ -775,6 +799,7 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare
@Override
public void onStopNestedScroll(View target) {
mNestedScrollingParentHelper.onStopNestedScroll(target);
+ mNestedScrollInProgress = false;
// Finish the spinner for nested scrolling if we ever consumed any
// unconsumed nested scroll
if (mTotalUnconsumed > 0) {
@@ -786,30 +811,27 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare
}
@Override
- public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed,
- int dyUnconsumed) {
- if (dyUnconsumed < 0) {
- dyUnconsumed = Math.abs(dyUnconsumed);
- mTotalUnconsumed += dyUnconsumed;
+ public void onNestedScroll(final View target, final int dxConsumed, final int dyConsumed,
+ final int dxUnconsumed, final int dyUnconsumed) {
+ // Dispatch up to the nested parent first
+ dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed,
+ mParentOffsetInWindow);
+
+ // This is a bit of a hack. Nested scrolling works from the bottom up, and as we are
+ // sometimes between two nested scrolling views, we need a way to be able to know when any
+ // nested scrolling parent has stopped handling events. We do that by using the
+ // 'offset in window 'functionality to see if we have been moved from the event.
+ // This is a decent indication of whether we should take over the event stream or not.
+ final int dy = dyUnconsumed + mParentOffsetInWindow[1];
+ if (dy < 0) {
+ mTotalUnconsumed += Math.abs(dy);
moveSpinner(mTotalUnconsumed);
}
- // Dispatch up to the nested parent
- dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dxConsumed, null);
}
// NestedScrollingChild
@Override
- public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
- return false;
- }
-
- @Override
- public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {
- return false;
- }
-
- @Override
public void setNestedScrollingEnabled(boolean enabled) {
mNestedScrollingChildHelper.setNestedScrollingEnabled(enabled);
}
@@ -847,6 +869,18 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare
}
@Override
+ public boolean onNestedPreFling(View target, float velocityX,
+ float velocityY) {
+ return dispatchNestedPreFling(velocityX, velocityY);
+ }
+
+ @Override
+ public boolean onNestedFling(View target, float velocityX, float velocityY,
+ boolean consumed) {
+ return dispatchNestedFling(velocityX, velocityY, consumed);
+ }
+
+ @Override
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return mNestedScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}
@@ -943,12 +977,13 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare
@Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = MotionEventCompat.getActionMasked(ev);
+ int pointerIndex = -1;
if (mReturningToStart && action == MotionEvent.ACTION_DOWN) {
mReturningToStart = false;
}
- if (!isEnabled() || mReturningToStart || canChildScrollUp()) {
+ if (!isEnabled() || mReturningToStart || canChildScrollUp() || mNestedScrollInProgress) {
// Fail fast if we're not in a state where a swipe is possible
return false;
}
@@ -960,7 +995,7 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare
break;
case MotionEvent.ACTION_MOVE: {
- final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
+ pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
if (pointerIndex < 0) {
Log.e(LOG_TAG, "Got ACTION_MOVE event but have an invalid active pointer id.");
return false;
@@ -978,8 +1013,12 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare
break;
}
case MotionEventCompat.ACTION_POINTER_DOWN: {
- final int index = MotionEventCompat.getActionIndex(ev);
- mActivePointerId = MotionEventCompat.getPointerId(ev, index);
+ pointerIndex = MotionEventCompat.getActionIndex(ev);
+ if (pointerIndex < 0) {
+ Log.e(LOG_TAG, "Got ACTION_POINTER_DOWN event but have an invalid action index.");
+ return false;
+ }
+ mActivePointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
break;
}
@@ -987,15 +1026,13 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare
onSecondaryPointerUp(ev);
break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL: {
- if (mActivePointerId == INVALID_POINTER) {
- if (action == MotionEvent.ACTION_UP) {
- Log.e(LOG_TAG, "Got ACTION_UP event but don't have an active pointer id.");
- }
+ case MotionEvent.ACTION_UP: {
+ pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
+ if (pointerIndex < 0) {
+ Log.e(LOG_TAG, "Got ACTION_UP event but don't have an active pointer id.");
return false;
}
- final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
+
final float y = MotionEventCompat.getY(ev, pointerIndex);
final float overscrollTop = (y - mInitialMotionY) * DRAG_RATE;
mIsBeingDragged = false;
@@ -1003,6 +1040,8 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare
mActivePointerId = INVALID_POINTER;
return false;
}
+ case MotionEvent.ACTION_CANCEL:
+ return false;
}
return true;
@@ -1020,18 +1059,6 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare
mCircleView.startAnimation(mAnimateToCorrectPosition);
}
- private void peek(int from, AnimationListener listener) {
- mFrom = from;
- mPeek.reset();
- mPeek.setDuration(500);
- mPeek.setInterpolator(mDecelerateInterpolator);
- if (listener != null) {
- mCircleView.setAnimationListener(listener);
- }
- mCircleView.clearAnimation();
- mCircleView.startAnimation(mPeek);
- }
-
private void animateOffsetToStartPosition(int from, AnimationListener listener) {
if (mScale) {
// Scale the item back down
@@ -1066,23 +1093,6 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare
}
};
- private final Animation mPeek = new Animation() {
- @Override
- public void applyTransformation(float interpolatedTime, Transformation t) {
- int targetTop = 0;
- int endTarget = 0;
- if (!mUsingCustomStart) {
- endTarget = (int) (mSpinnerFinalOffset - Math.abs(mOriginalOffsetTop));
- } else {
- endTarget = (int) mSpinnerFinalOffset; //mSpinnerFinalOffset;
- }
- targetTop = (mFrom + (int) ((endTarget - mFrom) * interpolatedTime));
- int offset = targetTop - mCircleView.getTop();
- setTargetOffsetTopAndBottom(offset, false /* requires update */);
- mProgress.setArrowScale(1 - interpolatedTime);
- }
- };
-
private void moveToStart(float interpolatedTime) {
int targetTop = 0;
targetTop = (mFrom + (int) ((mOriginalOffsetTop - mFrom) * interpolatedTime));
diff --git a/v4/java/android/support/v4/widget/TextViewCompat.java b/v4/java/android/support/v4/widget/TextViewCompat.java
index c31196aeac..621ee66eab 100644
--- a/v4/java/android/support/v4/widget/TextViewCompat.java
+++ b/v4/java/android/support/v4/widget/TextViewCompat.java
@@ -18,6 +18,7 @@ package android.support.v4.widget;
import android.graphics.drawable.Drawable;
import android.os.Build;
+import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.widget.TextView;
@@ -29,26 +30,23 @@ import android.widget.TextView;
public class TextViewCompat {
// Hide constructor
- private TextViewCompat() {
- }
+ private TextViewCompat() {}
interface TextViewCompatImpl {
-
- public void setCompoundDrawablesRelative(@NonNull TextView textView,
+ void setCompoundDrawablesRelative(@NonNull TextView textView,
@Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end,
@Nullable Drawable bottom);
-
- public void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView,
+ void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView,
@Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end,
@Nullable Drawable bottom);
-
- public void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView,
+ void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView,
int start, int top, int end, int bottom);
-
+ int getMaxLines(TextView textView);
+ int getMinLines(TextView textView);
+ void setTextAppearance(@NonNull TextView textView, @IdRes int resId);
}
static class BaseTextViewCompatImpl implements TextViewCompatImpl {
-
@Override
public void setCompoundDrawablesRelative(@NonNull TextView textView,
@Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end,
@@ -69,10 +67,35 @@ public class TextViewCompat {
textView.setCompoundDrawablesWithIntrinsicBounds(start, top, end, bottom);
}
+ @Override
+ public int getMaxLines(TextView textView) {
+ return TextViewCompatDonut.getMaxLines(textView);
+ }
+
+ @Override
+ public int getMinLines(TextView textView) {
+ return TextViewCompatDonut.getMinLines(textView);
+ }
+
+ @Override
+ public void setTextAppearance(TextView textView, int resId) {
+ TextViewCompatDonut.setTextAppearance(textView, resId);
+ }
}
- static class JbMr1TextViewCompatImpl extends BaseTextViewCompatImpl {
+ static class JbTextViewCompatImpl extends BaseTextViewCompatImpl {
+ @Override
+ public int getMaxLines(TextView textView) {
+ return TextViewCompatJb.getMaxLines(textView);
+ }
+
+ @Override
+ public int getMinLines(TextView textView) {
+ return TextViewCompatJb.getMinLines(textView);
+ }
+ }
+ static class JbMr1TextViewCompatImpl extends JbTextViewCompatImpl {
@Override
public void setCompoundDrawablesRelative(@NonNull TextView textView,
@Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end,
@@ -94,11 +117,9 @@ public class TextViewCompat {
TextViewCompatJbMr1.setCompoundDrawablesRelativeWithIntrinsicBounds(textView,
start, top, end, bottom);
}
-
}
static class JbMr2TextViewCompatImpl extends JbMr1TextViewCompatImpl {
-
@Override
public void setCompoundDrawablesRelative(@NonNull TextView textView,
@Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end,
@@ -123,14 +144,25 @@ public class TextViewCompat {
}
}
+ static class Api23TextViewCompatImpl extends JbMr2TextViewCompatImpl {
+ @Override
+ public void setTextAppearance(@NonNull TextView textView, @IdRes int resId) {
+ TextViewCompatApi23.setTextAppearance(textView, resId);
+ }
+ }
+
static final TextViewCompatImpl IMPL;
static {
final int version = Build.VERSION.SDK_INT;
- if (version >= 18) {
+ if (version >= 23) {
+ IMPL = new Api23TextViewCompatImpl();
+ } else if (version >= 18) {
IMPL = new JbMr2TextViewCompatImpl();
} else if (version >= 17) {
IMPL = new JbMr1TextViewCompatImpl();
+ } else if (version >= 16) {
+ IMPL = new JbTextViewCompatImpl();
} else {
IMPL = new BaseTextViewCompatImpl();
}
@@ -200,4 +232,34 @@ public class TextViewCompat {
IMPL.setCompoundDrawablesRelativeWithIntrinsicBounds(textView, start, top, end, bottom);
}
+ /**
+ * Returns the maximum number of lines displayed in the given TextView, or -1 if the maximum
+ * height was set in pixels instead.
+ */
+ public static int getMaxLines(@NonNull TextView textView) {
+ return IMPL.getMaxLines(textView);
+ }
+
+ /**
+ * Returns the minimum number of lines displayed in the given TextView, or -1 if the minimum
+ * height was set in pixels instead.
+ */
+ public static int getMinLines(@NonNull TextView textView) {
+ return IMPL.getMinLines(textView);
+ }
+
+ /**
+ * Sets the text appearance from the specified style resource.
+ * <p>
+ * Use a framework-defined {@code TextAppearance} style like
+ * {@link android.R.style#TextAppearance_Material_Body1 @android:style/TextAppearance.Material.Body1}
+ * or see {@link android.R.styleable#TextAppearance TextAppearance} for the
+ * set of attributes that can be used in a custom style.
+ *
+ * @param textView The TextView against which to invoke the method.
+ * @param resId The resource identifier of the style to apply.
+ */
+ public static void setTextAppearance(@NonNull TextView textView, @IdRes int resId) {
+ IMPL.setTextAppearance(textView, resId);
+ }
}
diff --git a/v4/java/android/support/v4/widget/TextViewCompatDonut.java b/v4/java/android/support/v4/widget/TextViewCompatDonut.java
new file mode 100644
index 0000000000..ba155fe342
--- /dev/null
+++ b/v4/java/android/support/v4/widget/TextViewCompatDonut.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2015 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.support.v4.widget;
+
+import android.util.Log;
+import android.widget.TextView;
+
+import java.lang.reflect.Field;
+
+class TextViewCompatDonut {
+
+ private static final String LOG_TAG = "TextViewCompatDonut";
+ private static final int LINES = 1;
+
+ private static Field sMaximumField;
+ private static boolean sMaximumFieldFetched;
+ private static Field sMaxModeField;
+ private static boolean sMaxModeFieldFetched;
+
+ private static Field sMinimumField;
+ private static boolean sMinimumFieldFetched;
+ private static Field sMinModeField;
+ private static boolean sMinModeFieldFetched;
+
+ static int getMaxLines(TextView textView) {
+ if (!sMaxModeFieldFetched) {
+ sMaxModeField = retrieveField("mMaxMode");
+ sMaxModeFieldFetched = true;
+ }
+ if (sMaxModeField != null && retrieveIntFromField(sMaxModeField, textView) == LINES) {
+ // If the max mode is using lines, we can grab the maximum value
+ if (!sMaximumFieldFetched) {
+ sMaximumField = retrieveField("mMaximum");
+ sMaximumFieldFetched = true;
+ }
+ if (sMaximumField != null) {
+ return retrieveIntFromField(sMaximumField, textView);
+ }
+ }
+ return -1;
+ }
+
+ static int getMinLines(TextView textView) {
+ if (!sMinModeFieldFetched) {
+ sMinModeField = retrieveField("mMinMode");
+ sMinModeFieldFetched = true;
+ }
+ if (sMinModeField != null && retrieveIntFromField(sMinModeField, textView) == LINES) {
+ // If the min mode is using lines, we can grab the maximum value
+ if (!sMinimumFieldFetched) {
+ sMinimumField = retrieveField("mMinimum");
+ sMinimumFieldFetched = true;
+ }
+ if (sMinimumField != null) {
+ return retrieveIntFromField(sMinimumField, textView);
+ }
+ }
+ return -1;
+ }
+
+ private static Field retrieveField(String fieldName) {
+ Field field = null;
+ try {
+ field = TextView.class.getDeclaredField(fieldName);
+ field.setAccessible(true);
+ } catch (NoSuchFieldException e) {
+ Log.e(LOG_TAG, "Could not retrieve " + fieldName + " field.");
+ }
+ return field;
+ }
+
+ private static int retrieveIntFromField(Field field, TextView textView) {
+ try {
+ return field.getInt(textView);
+ } catch (IllegalAccessException e) {
+ Log.d(LOG_TAG, "Could not retrieve value of " + field.getName() + " field.");
+ }
+ return -1;
+ }
+
+ static void setTextAppearance(TextView textView, int resId) {
+ textView.setTextAppearance(textView.getContext(), resId);
+ }
+}
diff --git a/v4/jellybean-mr1/android/support/v4/text/TextUtilsCompatJellybeanMr1.java b/v4/jellybean-mr1/android/support/v4/text/TextUtilsCompatJellybeanMr1.java
index fcdf8b5675..d5b675b4d6 100644
--- a/v4/jellybean-mr1/android/support/v4/text/TextUtilsCompatJellybeanMr1.java
+++ b/v4/jellybean-mr1/android/support/v4/text/TextUtilsCompatJellybeanMr1.java
@@ -25,7 +25,7 @@ import java.util.Locale;
/**
* Jellybean MR1 - specific TextUtils API access.
*/
-public class TextUtilsCompatJellybeanMr1 {
+class TextUtilsCompatJellybeanMr1 {
@NonNull
public static String htmlEncode(@NonNull String s) {
return TextUtils.htmlEncode(s);
diff --git a/v4/jellybean-mr2/android/support/v4/media/TransportMediatorJellybeanMR2.java b/v4/jellybean-mr2/android/support/v4/media/TransportMediatorJellybeanMR2.java
index 38b6778f23..be3555e428 100644
--- a/v4/jellybean-mr2/android/support/v4/media/TransportMediatorJellybeanMR2.java
+++ b/v4/jellybean-mr2/android/support/v4/media/TransportMediatorJellybeanMR2.java
@@ -28,9 +28,7 @@ import android.view.KeyEvent;
import android.view.View;
import android.view.ViewTreeObserver;
-class TransportMediatorJellybeanMR2
- implements RemoteControlClient.OnGetPlaybackPositionListener,
- RemoteControlClient.OnPlaybackPositionUpdateListener {
+class TransportMediatorJellybeanMR2 {
final Context mContext;
final AudioManager mAudioManager;
final View mTargetView;
@@ -75,7 +73,20 @@ class TransportMediatorJellybeanMR2
mTransportCallback.handleAudioFocusChange(focusChange);
}
};
-
+ final RemoteControlClient.OnGetPlaybackPositionListener mGetPlaybackPositionListener
+ = new RemoteControlClient.OnGetPlaybackPositionListener() {
+ @Override
+ public long onGetPlaybackPosition() {
+ return mTransportCallback.getPlaybackPosition();
+ }
+ };
+ final RemoteControlClient.OnPlaybackPositionUpdateListener mPlaybackPositionUpdateListener
+ = new RemoteControlClient.OnPlaybackPositionUpdateListener() {
+ public void onPlaybackPositionUpdate(long newPositionMs) {
+ mTransportCallback.playbackPositionUpdate(newPositionMs);
+ }
+ };
+
PendingIntent mPendingIntent;
RemoteControlClient mRemoteControl;
boolean mFocused;
@@ -112,8 +123,8 @@ class TransportMediatorJellybeanMR2
mPendingIntent = PendingIntent.getBroadcast(mContext, 0, mIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
mRemoteControl = new RemoteControlClient(mPendingIntent);
- mRemoteControl.setOnGetPlaybackPositionListener(this);
- mRemoteControl.setPlaybackPositionUpdateListener(this);
+ mRemoteControl.setOnGetPlaybackPositionListener(mGetPlaybackPositionListener);
+ mRemoteControl.setPlaybackPositionUpdateListener(mPlaybackPositionUpdateListener);
}
void gainFocus() {
@@ -145,16 +156,6 @@ class TransportMediatorJellybeanMR2
}
}
- @Override
- public long onGetPlaybackPosition() {
- return mTransportCallback.getPlaybackPosition();
- }
-
- @Override
- public void onPlaybackPositionUpdate(long newPositionMs) {
- mTransportCallback.playbackPositionUpdate(newPositionMs);
- }
-
public void refreshState(boolean playing, long position, int transportControls) {
if (mRemoteControl != null) {
mRemoteControl.setPlaybackState(playing ? RemoteControlClient.PLAYSTATE_PLAYING
diff --git a/v4/jellybean-mr2/android/support/v4/media/session/MediaSessionCompatApi18.java b/v4/jellybean-mr2/android/support/v4/media/session/MediaSessionCompatApi18.java
index 1c5dca78ed..8ceb38c226 100644
--- a/v4/jellybean-mr2/android/support/v4/media/session/MediaSessionCompatApi18.java
+++ b/v4/jellybean-mr2/android/support/v4/media/session/MediaSessionCompatApi18.java
@@ -16,28 +16,56 @@
package android.support.v4.media.session;
import android.app.PendingIntent;
+import android.content.ComponentName;
import android.content.Context;
import android.media.AudioManager;
import android.media.RemoteControlClient;
+import android.util.Log;
import android.os.SystemClock;
-public class MediaSessionCompatApi18 {
+class MediaSessionCompatApi18 {
+ private static final String TAG = "MediaSessionCompatApi18";
+
/***** PlaybackState actions *****/
private static final long ACTION_SEEK_TO = 1 << 8;
+ private static boolean sIsMbrPendingIntentSupported = true;
+
public static Object createPlaybackPositionUpdateListener(
MediaSessionCompatApi14.Callback callback) {
return new OnPlaybackPositionUpdateListener<MediaSessionCompatApi14.Callback>(callback);
}
- public static void registerMediaButtonEventReceiver(Context context, PendingIntent pi) {
+ public static void registerMediaButtonEventReceiver(Context context, PendingIntent pi,
+ ComponentName cn) {
AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
- am.registerMediaButtonEventReceiver(pi);
+
+ // Some Android implementations are not able to register a media button event receiver
+ // using a PendingIntent but need a ComponentName instead. These will raise a
+ // NullPointerException.
+ if (sIsMbrPendingIntentSupported) {
+ try {
+ am.registerMediaButtonEventReceiver(pi);
+ } catch (NullPointerException e) {
+ Log.w(TAG, "Unable to register media button event receiver with "
+ + "PendingIntent, falling back to ComponentName.");
+ sIsMbrPendingIntentSupported = false;
+ }
+ }
+
+ if (!sIsMbrPendingIntentSupported) {
+ am.registerMediaButtonEventReceiver(cn);
+ }
}
- public static void unregisterMediaButtonEventReceiver(Context context, PendingIntent pi) {
+ public static void unregisterMediaButtonEventReceiver(Context context, PendingIntent pi,
+ ComponentName cn) {
AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
- am.unregisterMediaButtonEventReceiver(pi);
+ if (sIsMbrPendingIntentSupported) {
+ am.unregisterMediaButtonEventReceiver(pi);
+ } else {
+ am.unregisterMediaButtonEventReceiver(cn);
+ }
}
public static void setState(Object rccObj, int state, long position, float speed,
diff --git a/v4/jellybean/android/support/v4/widget/TextViewCompatJb.java b/v4/jellybean/android/support/v4/widget/TextViewCompatJb.java
new file mode 100644
index 0000000000..1658874c68
--- /dev/null
+++ b/v4/jellybean/android/support/v4/widget/TextViewCompatJb.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 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.support.v4.widget;
+
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.widget.TextView;
+
+class TextViewCompatJb {
+ static int getMaxLines(TextView textView) {
+ return textView.getMaxLines();
+ }
+
+ static int getMinLines(TextView textView) {
+ return textView.getMinLines();
+ }
+}
diff --git a/v4/kitkat/android/support/v4/media/session/MediaSessionCompatApi19.java b/v4/kitkat/android/support/v4/media/session/MediaSessionCompatApi19.java
index 61039d37fc..f3c19e292e 100644
--- a/v4/kitkat/android/support/v4/media/session/MediaSessionCompatApi19.java
+++ b/v4/kitkat/android/support/v4/media/session/MediaSessionCompatApi19.java
@@ -15,14 +15,13 @@
*/
package android.support.v4.media.session;
-import android.graphics.Bitmap;
import android.media.MediaMetadataEditor;
import android.media.MediaMetadataRetriever;
import android.media.Rating;
import android.media.RemoteControlClient;
import android.os.Bundle;
-public class MediaSessionCompatApi19 {
+class MediaSessionCompatApi19 {
/***** PlaybackState actions *****/
private static final long ACTION_SET_RATING = 1 << 7;
diff --git a/v4/kitkat/android/support/v4/view/ViewPropertyAnimatorCompatKK.java b/v4/kitkat/android/support/v4/view/ViewPropertyAnimatorCompatKK.java
index 5439972d65..64f1969dad 100644
--- a/v4/kitkat/android/support/v4/view/ViewPropertyAnimatorCompatKK.java
+++ b/v4/kitkat/android/support/v4/view/ViewPropertyAnimatorCompatKK.java
@@ -22,12 +22,16 @@ class ViewPropertyAnimatorCompatKK {
public static void setUpdateListener(final View view,
final ViewPropertyAnimatorUpdateListener listener) {
- view.animate().setUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator valueAnimator) {
- listener.onAnimationUpdate(view);
- }
- });
+ ValueAnimator.AnimatorUpdateListener wrapped = null;
+ if (listener != null) {
+ wrapped = new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ listener.onAnimationUpdate(view);
+ }
+ };
+ }
+ view.animate().setUpdateListener(wrapped);
}
}
diff --git a/v4/tests/AndroidManifest.xml b/v4/tests/AndroidManifest.xml
new file mode 100644
index 0000000000..556c885344
--- /dev/null
+++ b/v4/tests/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="android.support.v4.test">
+ <uses-sdk android:minSdkVersion="4" tools:overrideLibrary="android.support.test,
+ android.support.test.espresso, android.support.test.espresso.idling"/>
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ <activity android:name="android.support.v4.widget.test.TextViewTestActivity"/>
+ <activity android:name="android.support.v4.widget.TestActivity"/>
+ </application>
+
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="android.support.v4.test"
+ />
+</manifest>
diff --git a/v4/tests/java/android/support/v4/graphics/ColorUtilsTest.java b/v4/tests/java/android/support/v4/graphics/ColorUtilsTest.java
index 855cdba3a5..56cb6fbf43 100644
--- a/v4/tests/java/android/support/v4/graphics/ColorUtilsTest.java
+++ b/v4/tests/java/android/support/v4/graphics/ColorUtilsTest.java
@@ -17,9 +17,9 @@
package android.support.v4.graphics;
import android.graphics.Color;
-import android.support.v4.graphics.ColorUtils;
import android.test.AndroidTestCase;
+import java.lang.Integer;
import java.util.ArrayList;
/**
@@ -31,21 +31,31 @@ public class ColorUtilsTest extends AndroidTestCase {
private static final float ALLOWED_OFFSET_HUE = 360 * 0.005f;
private static final float ALLOWED_OFFSET_SATURATION = 0.005f;
private static final float ALLOWED_OFFSET_LIGHTNESS = 0.005f;
+ private static final float ALLOWED_OFFSET_MIN_ALPHA = 0.01f;
private static final int ALLOWED_OFFSET_RGB_COMPONENT = 2;
private static final ArrayList<TestEntry> sEntryList = new ArrayList<>();
static {
- sEntryList.add(new TestEntry(Color.BLACK).setHsl(0f, 0f, 0f));
- sEntryList.add(new TestEntry(Color.WHITE).setHsl(0f, 0f, 1f));
- sEntryList.add(new TestEntry(Color.BLUE).setHsl(240f, 1f, 0.5f));
- sEntryList.add(new TestEntry(Color.GREEN).setHsl(120f, 1f, 0.5f));
- sEntryList.add(new TestEntry(Color.RED).setHsl(0f, 1f, 0.5f));
- sEntryList.add(new TestEntry(Color.CYAN).setHsl(180f, 1f, 0.5f));
- sEntryList.add(new TestEntry(0x2196F3).setHsl(207f, 0.9f, 0.54f));
- sEntryList.add(new TestEntry(0xD1C4E9).setHsl(261f, 0.46f, 0.84f));
- sEntryList.add(new TestEntry(0x311B92).setHsl(251.09f, 0.687f, 0.339f));
+ sEntryList.add(new TestEntry(Color.BLACK).setHsl(0f, 0f, 0f)
+ .setWhiteMinAlpha30(0.35f).setWhiteMinAlpha45(0.46f));
+ sEntryList.add(new TestEntry(Color.WHITE).setHsl(0f, 0f, 1f)
+ .setBlackMinAlpha30(0.42f).setBlackMinAlpha45(0.54f));
+ sEntryList.add(new TestEntry(Color.BLUE).setHsl(240f, 1f, 0.5f)
+ .setWhiteMinAlpha30(0.55f).setWhiteMinAlpha45(0.71f));
+ sEntryList.add(new TestEntry(Color.GREEN).setHsl(120f, 1f, 0.5f)
+ .setBlackMinAlpha30(0.43f).setBlackMinAlpha45(0.55f));
+ sEntryList.add(new TestEntry(Color.RED).setHsl(0f, 1f, 0.5f)
+ .setWhiteMinAlpha30(0.84f).setBlackMinAlpha30(0.55f).setBlackMinAlpha45(0.78f));
+ sEntryList.add(new TestEntry(Color.CYAN).setHsl(180f, 1f, 0.5f)
+ .setBlackMinAlpha30(0.43f).setBlackMinAlpha45(0.55f));
+ sEntryList.add(new TestEntry(0xFF2196F3).setHsl(207f, 0.9f, 0.54f)
+ .setBlackMinAlpha30(0.52f).setWhiteMinAlpha30(0.97f).setBlackMinAlpha45(0.7f));
+ sEntryList.add(new TestEntry(0xFFD1C4E9).setHsl(261f, 0.46f, 0.84f)
+ .setBlackMinAlpha30(0.45f).setBlackMinAlpha45(0.58f));
+ sEntryList.add(new TestEntry(0xFF311B92).setHsl(251.09f, 0.687f, 0.339f)
+ .setWhiteMinAlpha30(0.39f).setWhiteMinAlpha45(0.54f));
}
public void testToHSL() {
@@ -72,6 +82,28 @@ public class ColorUtilsTest extends AndroidTestCase {
}
}
+ public void testMinAlphas() {
+ for (TestEntry entry : sEntryList) {
+ testMinAlpha("Black title", entry.rgb, entry.blackMinAlpha30,
+ ColorUtils.calculateMinimumAlpha(Color.BLACK, entry.rgb, 3.0f));
+ testMinAlpha("Black body", entry.rgb, entry.blackMinAlpha45,
+ ColorUtils.calculateMinimumAlpha(Color.BLACK, entry.rgb, 4.5f));
+ testMinAlpha("White title", entry.rgb, entry.whiteMinAlpha30,
+ ColorUtils.calculateMinimumAlpha(Color.WHITE, entry.rgb, 3.0f));
+ testMinAlpha("White body", entry.rgb, entry.whiteMinAlpha45,
+ ColorUtils.calculateMinimumAlpha(Color.WHITE, entry.rgb, 4.5f));
+ }
+ }
+
+ private static void testMinAlpha(String title, int color, float expected, int actual) {
+ final String message = title + " text within error for #" + Integer.toHexString(color);
+ if (expected < 0) {
+ assertEquals(message, actual, -1);
+ } else {
+ assertClose(message, expected, actual / 255f, ALLOWED_OFFSET_MIN_ALPHA);
+ }
+ }
+
private static void assertClose(String message, float expected, float actual,
float allowedOffset) {
StringBuilder sb = new StringBuilder(message);
@@ -114,6 +146,10 @@ public class ColorUtilsTest extends AndroidTestCase {
private static class TestEntry {
final int rgb;
final float[] hsl = new float[3];
+ float blackMinAlpha45 = -1;
+ float blackMinAlpha30 = -1;
+ float whiteMinAlpha45 = -1;
+ float whiteMinAlpha30 = -1;
TestEntry(int rgb) {
this.rgb = rgb;
@@ -125,5 +161,25 @@ public class ColorUtilsTest extends AndroidTestCase {
hsl[2] = l;
return this;
}
+
+ TestEntry setBlackMinAlpha30(float minAlpha) {
+ blackMinAlpha30 = minAlpha;
+ return this;
+ }
+
+ TestEntry setBlackMinAlpha45(float minAlpha) {
+ blackMinAlpha45 = minAlpha;
+ return this;
+ }
+
+ TestEntry setWhiteMinAlpha30(float minAlpha) {
+ whiteMinAlpha30 = minAlpha;
+ return this;
+ }
+
+ TestEntry setWhiteMinAlpha45(float minAlpha) {
+ whiteMinAlpha45 = minAlpha;
+ return this;
+ }
}
} \ No newline at end of file
diff --git a/v4/tests/java/android/support/v4/widget/TestActivity.java b/v4/tests/java/android/support/v4/widget/TestActivity.java
new file mode 100644
index 0000000000..9ab5188db1
--- /dev/null
+++ b/v4/tests/java/android/support/v4/widget/TestActivity.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 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.support.v4.widget;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+
+public class TestActivity extends Activity {
+ FrameLayout mContainer;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContainer = new FrameLayout(this);
+
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ setContentView(mContainer);
+ }
+}
diff --git a/v4/tests/java/android/support/v4/widget/TextViewCompatTest.java b/v4/tests/java/android/support/v4/widget/TextViewCompatTest.java
new file mode 100644
index 0000000000..a7d233909c
--- /dev/null
+++ b/v4/tests/java/android/support/v4/widget/TextViewCompatTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015 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.support.v4.widget;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase2;
+import android.support.test.InstrumentationRegistry;
+import android.support.v4.widget.TextViewCompat;
+import android.util.Log;
+import android.widget.TextView;
+
+import android.support.test.runner.AndroidJUnit4;
+
+@RunWith(AndroidJUnit4.class)
+public class TextViewCompatTest extends ActivityInstrumentationTestCase2<TestActivity> {
+ private boolean mDebug;
+
+ Throwable mainThreadException;
+
+ Thread mInstrumentationThread;
+
+ public TextViewCompatTest() {
+ super("android.support.v4.widget", TestActivity.class);
+ mDebug = false;
+ }
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mInstrumentationThread = Thread.currentThread();
+
+ // Note that injectInstrumentation was added in v5. Since this is v4 we have to use
+ // the misspelled (and deprecated) inject API.
+ injectInsrumentation(InstrumentationRegistry.getInstrumentation());
+ }
+
+ @After
+ @Override
+ public void tearDown() throws Exception {
+ getInstrumentation().waitForIdleSync();
+ super.tearDown();
+ }
+
+ @Test
+ public void testMaxLines() throws Throwable {
+ final TextView textView = new TextView(getActivity());
+ textView.setMaxLines(4);
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ getActivity().mContainer.addView(textView);
+ }
+ });
+
+ assertEquals("Max lines must match", TextViewCompat.getMaxLines(textView), 4);
+ }
+}
diff --git a/v4/tests/java/android/support/v4/widget/test/TextViewTestActivity.java b/v4/tests/java/android/support/v4/widget/test/TextViewTestActivity.java
new file mode 100644
index 0000000000..7366127815
--- /dev/null
+++ b/v4/tests/java/android/support/v4/widget/test/TextViewTestActivity.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 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.support.v4.widget.test;
+
+
+import android.app.Activity;
+
+public class TextViewTestActivity extends Activity {
+
+}