Merge "Annotate with @NonNull DefaultLifecycleObserver" into oc-mr1-support-27.0-dev
diff --git a/annotations/api/current.txt b/annotations/api/current.txt
index c52f7e1..901e8f7 100644
--- a/annotations/api/current.txt
+++ b/annotations/api/current.txt
@@ -93,6 +93,9 @@
public abstract class MenuRes implements java.lang.annotation.Annotation {
}
+ public abstract class NavigationRes implements java.lang.annotation.Annotation {
+ }
+
public abstract class NonNull implements java.lang.annotation.Annotation {
}
diff --git a/annotations/src/android/support/annotation/NavigationRes.java b/annotations/src/android/support/annotation/NavigationRes.java
new file mode 100644
index 0000000..a051026
--- /dev/null
+++ b/annotations/src/android/support/annotation/NavigationRes.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 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.annotation;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Denotes that an integer parameter, field or method return value is expected
+ * to be a navigation resource reference (e.g. {@code R.navigation.flow}).
+ */
+@Documented
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
+public @interface NavigationRes {
+}
diff --git a/buildSrc/src/main/java/android/support/LibraryVersions.java b/buildSrc/src/main/java/android/support/LibraryVersions.java
index dbc9da6..710a7d3 100644
--- a/buildSrc/src/main/java/android/support/LibraryVersions.java
+++ b/buildSrc/src/main/java/android/support/LibraryVersions.java
@@ -48,7 +48,7 @@
/**
* Version code for Lifecycle libs that are required by the support library
*/
- public static final Version LIFECYCLES_CORE = new Version("1.0.1");
+ public static final Version LIFECYCLES_CORE = new Version("1.0.2");
/**
* Version code for Lifecycle runtime libs that are required by the support library
diff --git a/compat/Android.mk b/compat/Android.mk
index cd62336..e16bba6 100644
--- a/compat/Android.mk
+++ b/compat/Android.mk
@@ -25,10 +25,10 @@
LOCAL_USE_AAPT2 := true
LOCAL_MODULE := android-support-compat
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/java
+LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/src/main/java
LOCAL_SRC_FILES := \
- $(call all-java-files-under,java) \
- $(call all-Iaidl-files-under,java)
+ $(call all-java-files-under,src/main/java) \
+ $(call all-Iaidl-files-under,src/main/java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-annotations
diff --git a/compat/api/current.txt b/compat/api/current.txt
index c603a03..8f48f36 100644
--- a/compat/api/current.txt
+++ b/compat/api/current.txt
@@ -700,6 +700,13 @@
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;
method public static android.graphics.Typeface getFont(android.content.Context, int) throws android.content.res.Resources.NotFoundException;
+ method public static void getFont(android.content.Context, int, android.support.v4.content.res.ResourcesCompat.FontCallback, android.os.Handler) throws android.content.res.Resources.NotFoundException;
+ }
+
+ public static abstract class ResourcesCompat.FontCallback {
+ ctor public ResourcesCompat.FontCallback();
+ method public abstract void onFontRetrievalFailed(int);
+ method public abstract void onFontRetrieved(android.graphics.Typeface);
}
}
@@ -962,6 +969,7 @@
field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2
field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3
field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff
+ field public static final int FAIL_REASON_SECURITY_VIOLATION = -4; // 0xfffffffc
field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe
}
diff --git a/compat/build.gradle b/compat/build.gradle
index 66ae6f3..4d869b8 100644
--- a/compat/build.gradle
+++ b/compat/build.gradle
@@ -19,8 +19,7 @@
}
sourceSets {
- main.java.srcDirs = ['java']
- main.aidl.srcDirs = ['java']
+ main.aidl.srcDirs = ['src/main/java']
main.res.srcDirs 'res', 'res-public'
}
diff --git a/compat/java/android/support/v4/content/res/ResourcesCompat.java b/compat/java/android/support/v4/content/res/ResourcesCompat.java
deleted file mode 100644
index 43d78d0..0000000
--- a/compat/java/android/support/v4/content/res/ResourcesCompat.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.content.res;
-
-import static android.os.Build.VERSION.SDK_INT;
-import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.content.res.Resources.Theme;
-import android.content.res.XmlResourceParser;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.support.annotation.ColorInt;
-import android.support.annotation.ColorRes;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.FontRes;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.annotation.RestrictTo;
-import android.support.v4.content.res.FontResourcesParserCompat.FamilyResourceEntry;
-import android.support.v4.graphics.TypefaceCompat;
-import android.util.Log;
-import android.util.TypedValue;
-import android.widget.TextView;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-
-/**
- * Helper for accessing features in {@link android.content.res.Resources}.
- */
-public final class ResourcesCompat {
- private static final String TAG = "ResourcesCompat";
-
- /**
- * Return a drawable object associated with a particular resource ID and
- * styled for the specified theme. Various types of objects will be
- * returned depending on the underlying resource -- for example, a solid
- * color, PNG image, scalable image, etc.
- * <p>
- * Prior to API level 21, the theme will not be applied and this method
- * simply calls through to {@link Resources#getDrawable(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 drawable attributes, may be
- * {@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.
- */
- @Nullable
- @SuppressWarnings("deprecation")
- public static Drawable getDrawable(@NonNull Resources res, @DrawableRes int id,
- @Nullable Theme theme) throws NotFoundException {
- if (SDK_INT >= 21) {
- return res.getDrawable(id, theme);
- } else {
- return res.getDrawable(id);
- }
- }
-
-
- /**
- * Return a drawable object associated with a particular resource ID for
- * the given screen density in DPI and styled for the specified theme.
- * <p>
- * Prior to API level 15, the theme and density will not be applied and
- * 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).
- *
- * @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 density The desired screen density indicated by the resource as
- * found in {@link android.util.DisplayMetrics}.
- * @param theme The theme used to style the drawable attributes, may be
- * {@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.
- */
- @Nullable
- @SuppressWarnings("deprecation")
- public static Drawable getDrawableForDensity(@NonNull Resources res, @DrawableRes int id,
- int density, @Nullable Theme theme) throws NotFoundException {
- if (SDK_INT >= 21) {
- return res.getDrawableForDensity(id, density, theme);
- } else if (SDK_INT >= 15) {
- return res.getDrawableForDensity(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 res.getColor(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 res.getColorStateList(id, theme);
- } else {
- return res.getColorStateList(id);
- }
- }
-
- /**
- * Returns a font Typeface associated with a particular resource ID.
- * <p>
- * Prior to API level 23, font resources with more than one font in a family will only load the
- * first font in that family.
- *
- * @param context A context to retrieve the Resources from.
- * @param id The desired resource identifier of a {@link Typeface},
- * as generated by the aapt tool. This integer encodes the
- * package, type, and resource entry. The value 0 is an invalid
- * identifier.
- * @return A font Typeface object.
- * @throws NotFoundException Throws NotFoundException if the given ID does
- * not exist.
- */
- @Nullable
- public static Typeface getFont(@NonNull Context context, @FontRes int id)
- throws NotFoundException {
- if (context.isRestricted()) {
- return null;
- }
- return loadFont(context, id, new TypedValue(), Typeface.NORMAL, null);
- }
-
- /** @hide */
- @RestrictTo(LIBRARY_GROUP)
- public static Typeface getFont(@NonNull Context context, @FontRes int id, TypedValue value,
- int style, @Nullable TextView targetView) throws NotFoundException {
- if (context.isRestricted()) {
- return null;
- }
- return loadFont(context, id, value, style, targetView);
- }
-
- private static Typeface loadFont(@NonNull Context context, int id, TypedValue value,
- int style, @Nullable TextView targetView) {
- final Resources resources = context.getResources();
- resources.getValue(id, value, true);
- Typeface typeface = loadFont(context, resources, value, id, style, targetView);
- if (typeface != null) {
- return typeface;
- }
- throw new NotFoundException("Font resource ID #0x"
- + Integer.toHexString(id));
- }
-
- private static Typeface loadFont(
- @NonNull Context context, Resources wrapper, TypedValue value, int id, int style,
- @Nullable TextView targetView) {
- if (value.string == null) {
- throw new NotFoundException("Resource \"" + wrapper.getResourceName(id) + "\" ("
- + Integer.toHexString(id) + ") is not a Font: " + value);
- }
-
- final String file = value.string.toString();
- if (!file.startsWith("res/")) {
- // Early exit if the specified string is unlikely to the resource path.
- return null;
- }
-
- Typeface cached = TypefaceCompat.findFromCache(wrapper, id, style);
- if (cached != null) {
- return cached;
- }
-
- try {
- if (file.toLowerCase().endsWith(".xml")) {
- final XmlResourceParser rp = wrapper.getXml(id);
- final FamilyResourceEntry familyEntry =
- FontResourcesParserCompat.parse(rp, wrapper);
- if (familyEntry == null) {
- Log.e(TAG, "Failed to find font-family tag");
- return null;
- }
- return TypefaceCompat.createFromResourcesFamilyXml(
- context, familyEntry, wrapper, id, style, targetView);
- }
- return TypefaceCompat.createFromResourcesFontFile(context, wrapper, id, file, style);
- } catch (XmlPullParserException e) {
- Log.e(TAG, "Failed to parse xml resource " + file, e);
- } catch (IOException e) {
- Log.e(TAG, "Failed to read xml resource " + file, e);
- }
- return null;
- }
-
- private ResourcesCompat() {}
-}
diff --git a/compat/res/values/attrs.xml b/compat/res/values/attrs.xml
index 1833794..fd4049b 100644
--- a/compat/res/values/attrs.xml
+++ b/compat/res/values/attrs.xml
@@ -32,7 +32,12 @@
documentation for these values. -->
<attr name="fontProviderCerts" format="reference" />
<!-- The strategy to be used when fetching font data from a font provider in XML layouts.
- -->
+ This attribute is ignored when the resource is loaded from code, as it is equivalent to the
+ choice of API between {@link
+ android.support.v4.content.res.ResourcesCompat#getFont(Context, int)} (blocking) and
+ {@link
+ android.support.v4.content.res.ResourcesCompat#getFont(Context, int, FontCallback, Handler)}
+ (async). -->
<attr name="fontProviderFetchStrategy">
<!-- The blocking font fetch works as follows.
First, check the local cache, then if the requested font is not cached, request the
diff --git a/compat/java/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompat.java b/compat/src/main/java/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompat.java
similarity index 100%
rename from compat/java/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompat.java
rename to compat/src/main/java/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompat.java
diff --git a/compat/java/android/support/v4/accessibilityservice/package.html b/compat/src/main/java/android/support/v4/accessibilityservice/package.html
similarity index 100%
rename from compat/java/android/support/v4/accessibilityservice/package.html
rename to compat/src/main/java/android/support/v4/accessibilityservice/package.html
diff --git a/compat/java/android/support/v4/app/ActivityCompat.java b/compat/src/main/java/android/support/v4/app/ActivityCompat.java
similarity index 100%
rename from compat/java/android/support/v4/app/ActivityCompat.java
rename to compat/src/main/java/android/support/v4/app/ActivityCompat.java
diff --git a/compat/java/android/support/v4/app/ActivityManagerCompat.java b/compat/src/main/java/android/support/v4/app/ActivityManagerCompat.java
similarity index 100%
rename from compat/java/android/support/v4/app/ActivityManagerCompat.java
rename to compat/src/main/java/android/support/v4/app/ActivityManagerCompat.java
diff --git a/compat/java/android/support/v4/app/ActivityOptionsCompat.java b/compat/src/main/java/android/support/v4/app/ActivityOptionsCompat.java
similarity index 100%
rename from compat/java/android/support/v4/app/ActivityOptionsCompat.java
rename to compat/src/main/java/android/support/v4/app/ActivityOptionsCompat.java
diff --git a/compat/java/android/support/v4/app/AlarmManagerCompat.java b/compat/src/main/java/android/support/v4/app/AlarmManagerCompat.java
similarity index 100%
rename from compat/java/android/support/v4/app/AlarmManagerCompat.java
rename to compat/src/main/java/android/support/v4/app/AlarmManagerCompat.java
diff --git a/compat/java/android/support/v4/app/AppOpsManagerCompat.java b/compat/src/main/java/android/support/v4/app/AppOpsManagerCompat.java
similarity index 100%
rename from compat/java/android/support/v4/app/AppOpsManagerCompat.java
rename to compat/src/main/java/android/support/v4/app/AppOpsManagerCompat.java
diff --git a/compat/java/android/support/v4/app/BundleCompat.java b/compat/src/main/java/android/support/v4/app/BundleCompat.java
similarity index 100%
rename from compat/java/android/support/v4/app/BundleCompat.java
rename to compat/src/main/java/android/support/v4/app/BundleCompat.java
diff --git a/compat/java/android/support/v4/app/INotificationSideChannel.aidl b/compat/src/main/java/android/support/v4/app/INotificationSideChannel.aidl
similarity index 100%
rename from compat/java/android/support/v4/app/INotificationSideChannel.aidl
rename to compat/src/main/java/android/support/v4/app/INotificationSideChannel.aidl
diff --git a/compat/java/android/support/v4/app/JobIntentService.java b/compat/src/main/java/android/support/v4/app/JobIntentService.java
similarity index 100%
rename from compat/java/android/support/v4/app/JobIntentService.java
rename to compat/src/main/java/android/support/v4/app/JobIntentService.java
diff --git a/compat/java/android/support/v4/app/NotificationBuilderWithBuilderAccessor.java b/compat/src/main/java/android/support/v4/app/NotificationBuilderWithBuilderAccessor.java
similarity index 100%
rename from compat/java/android/support/v4/app/NotificationBuilderWithBuilderAccessor.java
rename to compat/src/main/java/android/support/v4/app/NotificationBuilderWithBuilderAccessor.java
diff --git a/compat/java/android/support/v4/app/NotificationCompat.java b/compat/src/main/java/android/support/v4/app/NotificationCompat.java
similarity index 100%
rename from compat/java/android/support/v4/app/NotificationCompat.java
rename to compat/src/main/java/android/support/v4/app/NotificationCompat.java
diff --git a/compat/java/android/support/v4/app/NotificationCompatBuilder.java b/compat/src/main/java/android/support/v4/app/NotificationCompatBuilder.java
similarity index 100%
rename from compat/java/android/support/v4/app/NotificationCompatBuilder.java
rename to compat/src/main/java/android/support/v4/app/NotificationCompatBuilder.java
diff --git a/compat/java/android/support/v4/app/NotificationCompatExtras.java b/compat/src/main/java/android/support/v4/app/NotificationCompatExtras.java
similarity index 100%
rename from compat/java/android/support/v4/app/NotificationCompatExtras.java
rename to compat/src/main/java/android/support/v4/app/NotificationCompatExtras.java
diff --git a/compat/java/android/support/v4/app/NotificationCompatJellybean.java b/compat/src/main/java/android/support/v4/app/NotificationCompatJellybean.java
similarity index 100%
rename from compat/java/android/support/v4/app/NotificationCompatJellybean.java
rename to compat/src/main/java/android/support/v4/app/NotificationCompatJellybean.java
diff --git a/compat/java/android/support/v4/app/NotificationCompatSideChannelService.java b/compat/src/main/java/android/support/v4/app/NotificationCompatSideChannelService.java
similarity index 100%
rename from compat/java/android/support/v4/app/NotificationCompatSideChannelService.java
rename to compat/src/main/java/android/support/v4/app/NotificationCompatSideChannelService.java
diff --git a/compat/java/android/support/v4/app/NotificationManagerCompat.java b/compat/src/main/java/android/support/v4/app/NotificationManagerCompat.java
similarity index 100%
rename from compat/java/android/support/v4/app/NotificationManagerCompat.java
rename to compat/src/main/java/android/support/v4/app/NotificationManagerCompat.java
diff --git a/compat/java/android/support/v4/app/RemoteInput.java b/compat/src/main/java/android/support/v4/app/RemoteInput.java
similarity index 100%
rename from compat/java/android/support/v4/app/RemoteInput.java
rename to compat/src/main/java/android/support/v4/app/RemoteInput.java
diff --git a/compat/java/android/support/v4/app/RemoteInputCompatBase.java b/compat/src/main/java/android/support/v4/app/RemoteInputCompatBase.java
similarity index 100%
rename from compat/java/android/support/v4/app/RemoteInputCompatBase.java
rename to compat/src/main/java/android/support/v4/app/RemoteInputCompatBase.java
diff --git a/compat/java/android/support/v4/app/ServiceCompat.java b/compat/src/main/java/android/support/v4/app/ServiceCompat.java
similarity index 100%
rename from compat/java/android/support/v4/app/ServiceCompat.java
rename to compat/src/main/java/android/support/v4/app/ServiceCompat.java
diff --git a/compat/java/android/support/v4/app/ShareCompat.java b/compat/src/main/java/android/support/v4/app/ShareCompat.java
similarity index 100%
rename from compat/java/android/support/v4/app/ShareCompat.java
rename to compat/src/main/java/android/support/v4/app/ShareCompat.java
diff --git a/compat/java/android/support/v4/app/SharedElementCallback.java b/compat/src/main/java/android/support/v4/app/SharedElementCallback.java
similarity index 100%
rename from compat/java/android/support/v4/app/SharedElementCallback.java
rename to compat/src/main/java/android/support/v4/app/SharedElementCallback.java
diff --git a/compat/java/android/support/v4/app/SupportActivity.java b/compat/src/main/java/android/support/v4/app/SupportActivity.java
similarity index 100%
rename from compat/java/android/support/v4/app/SupportActivity.java
rename to compat/src/main/java/android/support/v4/app/SupportActivity.java
diff --git a/compat/java/android/support/v4/app/package.html b/compat/src/main/java/android/support/v4/app/package.html
similarity index 100%
rename from compat/java/android/support/v4/app/package.html
rename to compat/src/main/java/android/support/v4/app/package.html
diff --git a/compat/java/android/support/v4/content/ContentResolverCompat.java b/compat/src/main/java/android/support/v4/content/ContentResolverCompat.java
similarity index 100%
rename from compat/java/android/support/v4/content/ContentResolverCompat.java
rename to compat/src/main/java/android/support/v4/content/ContentResolverCompat.java
diff --git a/compat/java/android/support/v4/content/ContextCompat.java b/compat/src/main/java/android/support/v4/content/ContextCompat.java
similarity index 100%
rename from compat/java/android/support/v4/content/ContextCompat.java
rename to compat/src/main/java/android/support/v4/content/ContextCompat.java
diff --git a/compat/java/android/support/v4/content/IntentCompat.java b/compat/src/main/java/android/support/v4/content/IntentCompat.java
similarity index 100%
rename from compat/java/android/support/v4/content/IntentCompat.java
rename to compat/src/main/java/android/support/v4/content/IntentCompat.java
diff --git a/compat/java/android/support/v4/content/SharedPreferencesCompat.java b/compat/src/main/java/android/support/v4/content/SharedPreferencesCompat.java
similarity index 100%
rename from compat/java/android/support/v4/content/SharedPreferencesCompat.java
rename to compat/src/main/java/android/support/v4/content/SharedPreferencesCompat.java
diff --git a/compat/java/android/support/v4/content/package.html b/compat/src/main/java/android/support/v4/content/package.html
similarity index 100%
rename from compat/java/android/support/v4/content/package.html
rename to compat/src/main/java/android/support/v4/content/package.html
diff --git a/compat/java/android/support/v4/content/pm/ActivityInfoCompat.java b/compat/src/main/java/android/support/v4/content/pm/ActivityInfoCompat.java
similarity index 100%
rename from compat/java/android/support/v4/content/pm/ActivityInfoCompat.java
rename to compat/src/main/java/android/support/v4/content/pm/ActivityInfoCompat.java
diff --git a/compat/java/android/support/v4/content/pm/ShortcutInfoCompat.java b/compat/src/main/java/android/support/v4/content/pm/ShortcutInfoCompat.java
similarity index 100%
rename from compat/java/android/support/v4/content/pm/ShortcutInfoCompat.java
rename to compat/src/main/java/android/support/v4/content/pm/ShortcutInfoCompat.java
diff --git a/compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java b/compat/src/main/java/android/support/v4/content/pm/ShortcutManagerCompat.java
similarity index 100%
rename from compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java
rename to compat/src/main/java/android/support/v4/content/pm/ShortcutManagerCompat.java
diff --git a/compat/java/android/support/v4/content/pm/package.html b/compat/src/main/java/android/support/v4/content/pm/package.html
similarity index 100%
rename from compat/java/android/support/v4/content/pm/package.html
rename to compat/src/main/java/android/support/v4/content/pm/package.html
diff --git a/compat/java/android/support/v4/content/res/ConfigurationHelper.java b/compat/src/main/java/android/support/v4/content/res/ConfigurationHelper.java
similarity index 100%
rename from compat/java/android/support/v4/content/res/ConfigurationHelper.java
rename to compat/src/main/java/android/support/v4/content/res/ConfigurationHelper.java
diff --git a/compat/java/android/support/v4/content/res/FontResourcesParserCompat.java b/compat/src/main/java/android/support/v4/content/res/FontResourcesParserCompat.java
similarity index 100%
rename from compat/java/android/support/v4/content/res/FontResourcesParserCompat.java
rename to compat/src/main/java/android/support/v4/content/res/FontResourcesParserCompat.java
diff --git a/compat/src/main/java/android/support/v4/content/res/ResourcesCompat.java b/compat/src/main/java/android/support/v4/content/res/ResourcesCompat.java
new file mode 100644
index 0000000..4c70ce9
--- /dev/null
+++ b/compat/src/main/java/android/support/v4/content/res/ResourcesCompat.java
@@ -0,0 +1,417 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v4.content.res;
+
+import static android.os.Build.VERSION.SDK_INT;
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.content.res.Resources.Theme;
+import android.content.res.XmlResourceParser;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.ColorInt;
+import android.support.annotation.ColorRes;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.FontRes;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
+import android.support.v4.content.res.FontResourcesParserCompat.FamilyResourceEntry;
+import android.support.v4.graphics.TypefaceCompat;
+import android.support.v4.provider.FontsContractCompat.FontRequestCallback;
+import android.support.v4.provider.FontsContractCompat.FontRequestCallback.FontRequestFailReason;
+import android.support.v4.util.Preconditions;
+import android.util.Log;
+import android.util.TypedValue;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/**
+ * Helper for accessing features in {@link android.content.res.Resources}.
+ */
+public final class ResourcesCompat {
+ private static final String TAG = "ResourcesCompat";
+
+ /**
+ * Return a drawable object associated with a particular resource ID and
+ * styled for the specified theme. Various types of objects will be
+ * returned depending on the underlying resource -- for example, a solid
+ * color, PNG image, scalable image, etc.
+ * <p>
+ * Prior to API level 21, the theme will not be applied and this method
+ * simply calls through to {@link Resources#getDrawable(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 drawable attributes, may be
+ * {@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.
+ */
+ @Nullable
+ @SuppressWarnings("deprecation")
+ public static Drawable getDrawable(@NonNull Resources res, @DrawableRes int id,
+ @Nullable Theme theme) throws NotFoundException {
+ if (SDK_INT >= 21) {
+ return res.getDrawable(id, theme);
+ } else {
+ return res.getDrawable(id);
+ }
+ }
+
+
+ /**
+ * Return a drawable object associated with a particular resource ID for
+ * the given screen density in DPI and styled for the specified theme.
+ * <p>
+ * Prior to API level 15, the theme and density will not be applied and
+ * 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).
+ *
+ * @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 density The desired screen density indicated by the resource as
+ * found in {@link android.util.DisplayMetrics}.
+ * @param theme The theme used to style the drawable attributes, may be
+ * {@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.
+ */
+ @Nullable
+ @SuppressWarnings("deprecation")
+ public static Drawable getDrawableForDensity(@NonNull Resources res, @DrawableRes int id,
+ int density, @Nullable Theme theme) throws NotFoundException {
+ if (SDK_INT >= 21) {
+ return res.getDrawableForDensity(id, density, theme);
+ } else if (SDK_INT >= 15) {
+ return res.getDrawableForDensity(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 res.getColor(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 res.getColorStateList(id, theme);
+ } else {
+ return res.getColorStateList(id);
+ }
+ }
+
+ /**
+ * Returns a font Typeface associated with a particular resource ID.
+ * <p>
+ * This method will block the calling thread to retrieve the requested font, including if it
+ * is from a font provider. If you wish to not have this behavior, use
+ * {@link #getFont(Context, int, FontCallback, Handler)} instead.
+ * <p>
+ * Prior to API level 23, font resources with more than one font in a family will only load the
+ * font closest to a regular weight typeface.
+ *
+ * @param context A context to retrieve the Resources from.
+ * @param id The desired resource identifier of a {@link Typeface},
+ * as generated by the aapt tool. This integer encodes the
+ * package, type, and resource entry. The value 0 is an invalid
+ * identifier.
+ * @return A font Typeface object.
+ * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
+ *
+ * @see #getFont(Context, int, FontCallback, Handler)
+ */
+ @Nullable
+ public static Typeface getFont(@NonNull Context context, @FontRes int id)
+ throws NotFoundException {
+ if (context.isRestricted()) {
+ return null;
+ }
+ return loadFont(context, id, new TypedValue(), Typeface.NORMAL, null /* callback */,
+ null /* handler */, false /* isXmlRequest */);
+ }
+
+ /**
+ * Interface used to receive asynchronous font fetching events.
+ */
+ public abstract static class FontCallback {
+
+ /**
+ * Called when an asynchronous font was finished loading.
+ *
+ * @param typeface The font that was loaded.
+ */
+ public abstract void onFontRetrieved(@NonNull Typeface typeface);
+
+ /**
+ * Called when an asynchronous font failed to load.
+ *
+ * @param reason The reason the font failed to load. One of
+ * {@link FontRequestFailReason#FAIL_REASON_PROVIDER_NOT_FOUND},
+ * {@link FontRequestFailReason#FAIL_REASON_WRONG_CERTIFICATES},
+ * {@link FontRequestFailReason#FAIL_REASON_FONT_LOAD_ERROR},
+ * {@link FontRequestFailReason#FAIL_REASON_SECURITY_VIOLATION},
+ * {@link FontRequestFailReason#FAIL_REASON_FONT_NOT_FOUND},
+ * {@link FontRequestFailReason#FAIL_REASON_FONT_UNAVAILABLE} or
+ * {@link FontRequestFailReason#FAIL_REASON_MALFORMED_QUERY}.
+ */
+ public abstract void onFontRetrievalFailed(@FontRequestFailReason int reason);
+
+ /**
+ * Call {@link #onFontRetrieved(Typeface)} on the handler given, or the Ui Thread if it is
+ * null.
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ public final void callbackSuccessAsync(final Typeface typeface, @Nullable Handler handler) {
+ if (handler == null) {
+ handler = new Handler(Looper.getMainLooper());
+ }
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ onFontRetrieved(typeface);
+ }
+ });
+ }
+
+ /**
+ * Call {@link #onFontRetrievalFailed(int)} on the handler given, or the Ui Thread if it is
+ * null.
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ public final void callbackFailAsync(
+ @FontRequestFailReason final int reason, @Nullable Handler handler) {
+ if (handler == null) {
+ handler = new Handler(Looper.getMainLooper());
+ }
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ onFontRetrievalFailed(reason);
+ }
+ });
+ }
+ }
+
+ /**
+ * Returns a font Typeface associated with a particular resource ID asynchronously.
+ * <p>
+ * Prior to API level 23, font resources with more than one font in a family will only load the
+ * font closest to a regular weight typeface.
+ * </p>
+ *
+ * @param context A context to retrieve the Resources from.
+ * @param id The desired resource identifier of a {@link Typeface}, as generated by the aapt
+ * tool. This integer encodes the package, type, and resource entry. The value 0 is an
+ * invalid identifier.
+ * @param fontCallback A callback to receive async fetching of this font. The callback will be
+ * triggered on the UI thread.
+ * @param handler A handler for the thread the callback should be called on. If null, the
+ * callback will be called on the UI thread.
+ * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
+ */
+ public static void getFont(@NonNull Context context, @FontRes int id,
+ @NonNull FontCallback fontCallback, @Nullable Handler handler)
+ throws NotFoundException {
+ Preconditions.checkNotNull(fontCallback);
+ if (context.isRestricted()) {
+ fontCallback.callbackFailAsync(
+ FontRequestCallback.FAIL_REASON_SECURITY_VIOLATION, handler);
+ return;
+ }
+ loadFont(context, id, new TypedValue(), Typeface.NORMAL, fontCallback, handler,
+ false /* isXmlRequest */);
+ }
+
+ /**
+ * Used by TintTypedArray.
+ *
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ public static Typeface getFont(@NonNull Context context, @FontRes int id, TypedValue value,
+ int style) throws NotFoundException {
+ if (context.isRestricted()) {
+ return null;
+ }
+ return loadFont(context, id, value, style, null /* callback */, null /* handler */,
+ true /* isXmlRequest */);
+ }
+
+ /**
+ *
+ * @param context The Context to get Resources from
+ * @param id The Resource id to load
+ * @param value A TypedValue to use in the fetching
+ * @param style The font style to load
+ * @param fontCallback A callback to trigger when the font is fetched or an error occurs
+ * @param handler A handler to the thread the callback should be called on
+ * @param isRequestFromLayoutInflator Whether this request originated from XML. This is used to
+ * determine if we use or ignore the fontProviderFetchStrategy attribute in
+ * font provider XML fonts.
+ * @return
+ */
+ private static Typeface loadFont(@NonNull Context context, int id, TypedValue value,
+ int style, @Nullable FontCallback fontCallback, @Nullable Handler handler,
+ boolean isRequestFromLayoutInflator) {
+ final Resources resources = context.getResources();
+ resources.getValue(id, value, true);
+ Typeface typeface = loadFont(context, resources, value, id, style, fontCallback, handler,
+ isRequestFromLayoutInflator);
+ if (typeface == null && fontCallback == null) {
+ throw new NotFoundException("Font resource ID #0x"
+ + Integer.toHexString(id) + " could not be retrieved.");
+ }
+ return typeface;
+ }
+
+ /**
+ * Load the given font. This method will always return null for asynchronous requests, which
+ * provide a fontCallback, as there is no immediate result. When the callback is not provided,
+ * the request is treated as synchronous and fails if async loading is required.
+ */
+ private static Typeface loadFont(
+ @NonNull Context context, Resources wrapper, TypedValue value, int id, int style,
+ @Nullable FontCallback fontCallback, @Nullable Handler handler,
+ boolean isRequestFromLayoutInflator) {
+ if (value.string == null) {
+ throw new NotFoundException("Resource \"" + wrapper.getResourceName(id) + "\" ("
+ + Integer.toHexString(id) + ") is not a Font: " + value);
+ }
+
+ final String file = value.string.toString();
+ if (!file.startsWith("res/")) {
+ // Early exit if the specified string is unlikely to be a resource path.
+ if (fontCallback != null) {
+ fontCallback.callbackFailAsync(
+ FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR, handler);
+ }
+ return null;
+ }
+ Typeface typeface = TypefaceCompat.findFromCache(wrapper, id, style);
+
+ if (typeface != null) {
+ if (fontCallback != null) {
+ fontCallback.callbackSuccessAsync(typeface, handler);
+ }
+ return typeface;
+ }
+
+ try {
+ if (file.toLowerCase().endsWith(".xml")) {
+ final XmlResourceParser rp = wrapper.getXml(id);
+ final FamilyResourceEntry familyEntry =
+ FontResourcesParserCompat.parse(rp, wrapper);
+ if (familyEntry == null) {
+ Log.e(TAG, "Failed to find font-family tag");
+ if (fontCallback != null) {
+ fontCallback.callbackFailAsync(
+ FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR, handler);
+ }
+ return null;
+ }
+ return TypefaceCompat.createFromResourcesFamilyXml(context, familyEntry, wrapper,
+ id, style, fontCallback, handler, isRequestFromLayoutInflator);
+ }
+ typeface = TypefaceCompat.createFromResourcesFontFile(
+ context, wrapper, id, file, style);
+ if (fontCallback != null) {
+ if (typeface != null) {
+ fontCallback.callbackSuccessAsync(typeface, handler);
+ } else {
+ fontCallback.callbackFailAsync(
+ FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR, handler);
+ }
+ }
+ return typeface;
+ } catch (XmlPullParserException e) {
+ Log.e(TAG, "Failed to parse xml resource " + file, e);
+ } catch (IOException e) {
+ Log.e(TAG, "Failed to read xml resource " + file, e);
+ }
+ if (fontCallback != null) {
+ fontCallback.callbackFailAsync(
+ FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR, handler);
+ }
+ return null;
+ }
+
+ private ResourcesCompat() {}
+}
diff --git a/compat/java/android/support/v4/content/res/TypedArrayUtils.java b/compat/src/main/java/android/support/v4/content/res/TypedArrayUtils.java
similarity index 100%
rename from compat/java/android/support/v4/content/res/TypedArrayUtils.java
rename to compat/src/main/java/android/support/v4/content/res/TypedArrayUtils.java
diff --git a/compat/java/android/support/v4/database/DatabaseUtilsCompat.java b/compat/src/main/java/android/support/v4/database/DatabaseUtilsCompat.java
similarity index 100%
rename from compat/java/android/support/v4/database/DatabaseUtilsCompat.java
rename to compat/src/main/java/android/support/v4/database/DatabaseUtilsCompat.java
diff --git a/compat/java/android/support/v4/database/package.html b/compat/src/main/java/android/support/v4/database/package.html
similarity index 100%
rename from compat/java/android/support/v4/database/package.html
rename to compat/src/main/java/android/support/v4/database/package.html
diff --git a/compat/java/android/support/v4/graphics/BitmapCompat.java b/compat/src/main/java/android/support/v4/graphics/BitmapCompat.java
similarity index 100%
rename from compat/java/android/support/v4/graphics/BitmapCompat.java
rename to compat/src/main/java/android/support/v4/graphics/BitmapCompat.java
diff --git a/compat/java/android/support/v4/graphics/PaintCompat.java b/compat/src/main/java/android/support/v4/graphics/PaintCompat.java
similarity index 100%
rename from compat/java/android/support/v4/graphics/PaintCompat.java
rename to compat/src/main/java/android/support/v4/graphics/PaintCompat.java
diff --git a/compat/java/android/support/v4/graphics/PathParser.java b/compat/src/main/java/android/support/v4/graphics/PathParser.java
similarity index 100%
rename from compat/java/android/support/v4/graphics/PathParser.java
rename to compat/src/main/java/android/support/v4/graphics/PathParser.java
diff --git a/compat/java/android/support/v4/graphics/TypefaceCompat.java b/compat/src/main/java/android/support/v4/graphics/TypefaceCompat.java
similarity index 79%
rename from compat/java/android/support/v4/graphics/TypefaceCompat.java
rename to compat/src/main/java/android/support/v4/graphics/TypefaceCompat.java
index b142a5f..3c55df6 100644
--- a/compat/java/android/support/v4/graphics/TypefaceCompat.java
+++ b/compat/src/main/java/android/support/v4/graphics/TypefaceCompat.java
@@ -23,16 +23,18 @@
import android.graphics.Typeface;
import android.os.Build;
import android.os.CancellationSignal;
+import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RestrictTo;
+import android.support.v4.content.res.FontResourcesParserCompat;
import android.support.v4.content.res.FontResourcesParserCompat.FamilyResourceEntry;
import android.support.v4.content.res.FontResourcesParserCompat.FontFamilyFilesResourceEntry;
import android.support.v4.content.res.FontResourcesParserCompat.ProviderResourceEntry;
+import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.provider.FontsContractCompat;
import android.support.v4.provider.FontsContractCompat.FontInfo;
import android.support.v4.util.LruCache;
-import android.widget.TextView;
/**
* Helper for accessing features in {@link Typeface}.
@@ -108,16 +110,31 @@
public static Typeface createFromResourcesFamilyXml(
@NonNull Context context, @NonNull FamilyResourceEntry entry,
@NonNull Resources resources, int id, int style,
- @Nullable TextView targetView) {
+ @Nullable ResourcesCompat.FontCallback fontCallback, @Nullable Handler handler,
+ boolean isRequestFromLayoutInflator) {
Typeface typeface;
if (entry instanceof ProviderResourceEntry) {
ProviderResourceEntry providerEntry = (ProviderResourceEntry) entry;
- typeface = FontsContractCompat.getFontSync(context,
- providerEntry.getRequest(), targetView, providerEntry.getFetchStrategy(),
- providerEntry.getTimeout(), style);
+ final boolean isBlocking = isRequestFromLayoutInflator
+ ? providerEntry.getFetchStrategy()
+ == FontResourcesParserCompat.FETCH_STRATEGY_BLOCKING
+ : fontCallback == null;
+ final int timeout = isRequestFromLayoutInflator ? providerEntry.getTimeout()
+ : FontResourcesParserCompat.INFINITE_TIMEOUT_VALUE;
+ typeface = FontsContractCompat.getFontSync(context, providerEntry.getRequest(),
+ fontCallback, handler, isBlocking, timeout, style);
} else {
typeface = sTypefaceCompatImpl.createFromFontFamilyFilesResourceEntry(
context, (FontFamilyFilesResourceEntry) entry, resources, style);
+ if (fontCallback != null) {
+ if (typeface != null) {
+ fontCallback.callbackSuccessAsync(typeface, handler);
+ } else {
+ fontCallback.callbackFailAsync(
+ FontsContractCompat.FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR,
+ handler);
+ }
+ }
}
if (typeface != null) {
sTypefaceCache.put(createResourceUid(resources, id, style), typeface);
@@ -135,7 +152,8 @@
Typeface typeface = sTypefaceCompatImpl.createFromResourcesFontFile(
context, resources, id, path, style);
if (typeface != null) {
- sTypefaceCache.put(createResourceUid(resources, id, style), typeface);
+ final String resourceUid = createResourceUid(resources, id, style);
+ sTypefaceCache.put(resourceUid, typeface);
}
return typeface;
}
diff --git a/compat/java/android/support/v4/graphics/TypefaceCompatApi21Impl.java b/compat/src/main/java/android/support/v4/graphics/TypefaceCompatApi21Impl.java
similarity index 100%
rename from compat/java/android/support/v4/graphics/TypefaceCompatApi21Impl.java
rename to compat/src/main/java/android/support/v4/graphics/TypefaceCompatApi21Impl.java
diff --git a/compat/java/android/support/v4/graphics/TypefaceCompatApi24Impl.java b/compat/src/main/java/android/support/v4/graphics/TypefaceCompatApi24Impl.java
similarity index 97%
rename from compat/java/android/support/v4/graphics/TypefaceCompatApi24Impl.java
rename to compat/src/main/java/android/support/v4/graphics/TypefaceCompatApi24Impl.java
index a107859..89a6ec4 100644
--- a/compat/java/android/support/v4/graphics/TypefaceCompatApi24Impl.java
+++ b/compat/src/main/java/android/support/v4/graphics/TypefaceCompatApi24Impl.java
@@ -145,7 +145,8 @@
return null;
}
}
- return createFromFamiliesWithDefault(family);
+ final Typeface typeface = createFromFamiliesWithDefault(family);
+ return Typeface.create(typeface, style);
}
@Override
diff --git a/compat/java/android/support/v4/graphics/TypefaceCompatApi26Impl.java b/compat/src/main/java/android/support/v4/graphics/TypefaceCompatApi26Impl.java
similarity index 98%
rename from compat/java/android/support/v4/graphics/TypefaceCompatApi26Impl.java
rename to compat/src/main/java/android/support/v4/graphics/TypefaceCompatApi26Impl.java
index c7066c8..972aa5d 100644
--- a/compat/java/android/support/v4/graphics/TypefaceCompatApi26Impl.java
+++ b/compat/src/main/java/android/support/v4/graphics/TypefaceCompatApi26Impl.java
@@ -273,7 +273,8 @@
if (!freeze(fontFamily)) {
return null;
}
- return createFromFamiliesWithDefault(fontFamily);
+ final Typeface typeface = createFromFamiliesWithDefault(fontFamily);
+ return Typeface.create(typeface, style);
}
/**
diff --git a/compat/java/android/support/v4/graphics/TypefaceCompatBaseImpl.java b/compat/src/main/java/android/support/v4/graphics/TypefaceCompatBaseImpl.java
similarity index 100%
rename from compat/java/android/support/v4/graphics/TypefaceCompatBaseImpl.java
rename to compat/src/main/java/android/support/v4/graphics/TypefaceCompatBaseImpl.java
diff --git a/compat/java/android/support/v4/graphics/TypefaceCompatUtil.java b/compat/src/main/java/android/support/v4/graphics/TypefaceCompatUtil.java
similarity index 100%
rename from compat/java/android/support/v4/graphics/TypefaceCompatUtil.java
rename to compat/src/main/java/android/support/v4/graphics/TypefaceCompatUtil.java
diff --git a/compat/java/android/support/v4/graphics/drawable/DrawableCompat.java b/compat/src/main/java/android/support/v4/graphics/drawable/DrawableCompat.java
similarity index 100%
rename from compat/java/android/support/v4/graphics/drawable/DrawableCompat.java
rename to compat/src/main/java/android/support/v4/graphics/drawable/DrawableCompat.java
diff --git a/compat/java/android/support/v4/graphics/drawable/DrawableWrapper.java b/compat/src/main/java/android/support/v4/graphics/drawable/DrawableWrapper.java
similarity index 100%
rename from compat/java/android/support/v4/graphics/drawable/DrawableWrapper.java
rename to compat/src/main/java/android/support/v4/graphics/drawable/DrawableWrapper.java
diff --git a/compat/java/android/support/v4/graphics/drawable/DrawableWrapperApi14.java b/compat/src/main/java/android/support/v4/graphics/drawable/DrawableWrapperApi14.java
similarity index 100%
rename from compat/java/android/support/v4/graphics/drawable/DrawableWrapperApi14.java
rename to compat/src/main/java/android/support/v4/graphics/drawable/DrawableWrapperApi14.java
diff --git a/compat/java/android/support/v4/graphics/drawable/DrawableWrapperApi19.java b/compat/src/main/java/android/support/v4/graphics/drawable/DrawableWrapperApi19.java
similarity index 100%
rename from compat/java/android/support/v4/graphics/drawable/DrawableWrapperApi19.java
rename to compat/src/main/java/android/support/v4/graphics/drawable/DrawableWrapperApi19.java
diff --git a/compat/java/android/support/v4/graphics/drawable/DrawableWrapperApi21.java b/compat/src/main/java/android/support/v4/graphics/drawable/DrawableWrapperApi21.java
similarity index 100%
rename from compat/java/android/support/v4/graphics/drawable/DrawableWrapperApi21.java
rename to compat/src/main/java/android/support/v4/graphics/drawable/DrawableWrapperApi21.java
diff --git a/compat/java/android/support/v4/graphics/drawable/IconCompat.java b/compat/src/main/java/android/support/v4/graphics/drawable/IconCompat.java
similarity index 100%
rename from compat/java/android/support/v4/graphics/drawable/IconCompat.java
rename to compat/src/main/java/android/support/v4/graphics/drawable/IconCompat.java
diff --git a/compat/java/android/support/v4/graphics/drawable/TintAwareDrawable.java b/compat/src/main/java/android/support/v4/graphics/drawable/TintAwareDrawable.java
similarity index 100%
rename from compat/java/android/support/v4/graphics/drawable/TintAwareDrawable.java
rename to compat/src/main/java/android/support/v4/graphics/drawable/TintAwareDrawable.java
diff --git a/compat/java/android/support/v4/hardware/display/DisplayManagerCompat.java b/compat/src/main/java/android/support/v4/hardware/display/DisplayManagerCompat.java
similarity index 100%
rename from compat/java/android/support/v4/hardware/display/DisplayManagerCompat.java
rename to compat/src/main/java/android/support/v4/hardware/display/DisplayManagerCompat.java
diff --git a/compat/java/android/support/v4/hardware/fingerprint/FingerprintManagerCompat.java b/compat/src/main/java/android/support/v4/hardware/fingerprint/FingerprintManagerCompat.java
similarity index 100%
rename from compat/java/android/support/v4/hardware/fingerprint/FingerprintManagerCompat.java
rename to compat/src/main/java/android/support/v4/hardware/fingerprint/FingerprintManagerCompat.java
diff --git a/compat/java/android/support/v4/internal/package-info.java b/compat/src/main/java/android/support/v4/internal/package-info.java
similarity index 100%
rename from compat/java/android/support/v4/internal/package-info.java
rename to compat/src/main/java/android/support/v4/internal/package-info.java
diff --git a/compat/java/android/support/v4/internal/view/SupportMenu.java b/compat/src/main/java/android/support/v4/internal/view/SupportMenu.java
similarity index 100%
rename from compat/java/android/support/v4/internal/view/SupportMenu.java
rename to compat/src/main/java/android/support/v4/internal/view/SupportMenu.java
diff --git a/compat/java/android/support/v4/internal/view/SupportMenuItem.java b/compat/src/main/java/android/support/v4/internal/view/SupportMenuItem.java
similarity index 100%
rename from compat/java/android/support/v4/internal/view/SupportMenuItem.java
rename to compat/src/main/java/android/support/v4/internal/view/SupportMenuItem.java
diff --git a/compat/java/android/support/v4/internal/view/SupportSubMenu.java b/compat/src/main/java/android/support/v4/internal/view/SupportSubMenu.java
similarity index 100%
rename from compat/java/android/support/v4/internal/view/SupportSubMenu.java
rename to compat/src/main/java/android/support/v4/internal/view/SupportSubMenu.java
diff --git a/compat/java/android/support/v4/net/ConnectivityManagerCompat.java b/compat/src/main/java/android/support/v4/net/ConnectivityManagerCompat.java
similarity index 100%
rename from compat/java/android/support/v4/net/ConnectivityManagerCompat.java
rename to compat/src/main/java/android/support/v4/net/ConnectivityManagerCompat.java
diff --git a/compat/java/android/support/v4/net/DatagramSocketWrapper.java b/compat/src/main/java/android/support/v4/net/DatagramSocketWrapper.java
similarity index 100%
rename from compat/java/android/support/v4/net/DatagramSocketWrapper.java
rename to compat/src/main/java/android/support/v4/net/DatagramSocketWrapper.java
diff --git a/compat/java/android/support/v4/net/TrafficStatsCompat.java b/compat/src/main/java/android/support/v4/net/TrafficStatsCompat.java
similarity index 100%
rename from compat/java/android/support/v4/net/TrafficStatsCompat.java
rename to compat/src/main/java/android/support/v4/net/TrafficStatsCompat.java
diff --git a/compat/java/android/support/v4/os/BuildCompat.java b/compat/src/main/java/android/support/v4/os/BuildCompat.java
similarity index 100%
rename from compat/java/android/support/v4/os/BuildCompat.java
rename to compat/src/main/java/android/support/v4/os/BuildCompat.java
diff --git a/compat/java/android/support/v4/os/CancellationSignal.java b/compat/src/main/java/android/support/v4/os/CancellationSignal.java
similarity index 100%
rename from compat/java/android/support/v4/os/CancellationSignal.java
rename to compat/src/main/java/android/support/v4/os/CancellationSignal.java
diff --git a/compat/java/android/support/v4/os/ConfigurationCompat.java b/compat/src/main/java/android/support/v4/os/ConfigurationCompat.java
similarity index 100%
rename from compat/java/android/support/v4/os/ConfigurationCompat.java
rename to compat/src/main/java/android/support/v4/os/ConfigurationCompat.java
diff --git a/compat/java/android/support/v4/os/EnvironmentCompat.java b/compat/src/main/java/android/support/v4/os/EnvironmentCompat.java
similarity index 100%
rename from compat/java/android/support/v4/os/EnvironmentCompat.java
rename to compat/src/main/java/android/support/v4/os/EnvironmentCompat.java
diff --git a/compat/java/android/support/v4/os/IResultReceiver.aidl b/compat/src/main/java/android/support/v4/os/IResultReceiver.aidl
similarity index 100%
rename from compat/java/android/support/v4/os/IResultReceiver.aidl
rename to compat/src/main/java/android/support/v4/os/IResultReceiver.aidl
diff --git a/compat/java/android/support/v4/os/LocaleHelper.java b/compat/src/main/java/android/support/v4/os/LocaleHelper.java
similarity index 100%
rename from compat/java/android/support/v4/os/LocaleHelper.java
rename to compat/src/main/java/android/support/v4/os/LocaleHelper.java
diff --git a/compat/java/android/support/v4/os/LocaleListCompat.java b/compat/src/main/java/android/support/v4/os/LocaleListCompat.java
similarity index 100%
rename from compat/java/android/support/v4/os/LocaleListCompat.java
rename to compat/src/main/java/android/support/v4/os/LocaleListCompat.java
diff --git a/compat/java/android/support/v4/os/LocaleListHelper.java b/compat/src/main/java/android/support/v4/os/LocaleListHelper.java
similarity index 100%
rename from compat/java/android/support/v4/os/LocaleListHelper.java
rename to compat/src/main/java/android/support/v4/os/LocaleListHelper.java
diff --git a/compat/java/android/support/v4/os/LocaleListInterface.java b/compat/src/main/java/android/support/v4/os/LocaleListInterface.java
similarity index 100%
rename from compat/java/android/support/v4/os/LocaleListInterface.java
rename to compat/src/main/java/android/support/v4/os/LocaleListInterface.java
diff --git a/compat/java/android/support/v4/os/OperationCanceledException.java b/compat/src/main/java/android/support/v4/os/OperationCanceledException.java
similarity index 100%
rename from compat/java/android/support/v4/os/OperationCanceledException.java
rename to compat/src/main/java/android/support/v4/os/OperationCanceledException.java
diff --git a/compat/java/android/support/v4/os/ParcelableCompat.java b/compat/src/main/java/android/support/v4/os/ParcelableCompat.java
similarity index 100%
rename from compat/java/android/support/v4/os/ParcelableCompat.java
rename to compat/src/main/java/android/support/v4/os/ParcelableCompat.java
diff --git a/compat/java/android/support/v4/os/ParcelableCompatCreatorCallbacks.java b/compat/src/main/java/android/support/v4/os/ParcelableCompatCreatorCallbacks.java
similarity index 100%
rename from compat/java/android/support/v4/os/ParcelableCompatCreatorCallbacks.java
rename to compat/src/main/java/android/support/v4/os/ParcelableCompatCreatorCallbacks.java
diff --git a/compat/java/android/support/v4/os/ResultReceiver.aidl b/compat/src/main/java/android/support/v4/os/ResultReceiver.aidl
similarity index 100%
rename from compat/java/android/support/v4/os/ResultReceiver.aidl
rename to compat/src/main/java/android/support/v4/os/ResultReceiver.aidl
diff --git a/compat/java/android/support/v4/os/ResultReceiver.java b/compat/src/main/java/android/support/v4/os/ResultReceiver.java
similarity index 100%
rename from compat/java/android/support/v4/os/ResultReceiver.java
rename to compat/src/main/java/android/support/v4/os/ResultReceiver.java
diff --git a/compat/java/android/support/v4/os/TraceCompat.java b/compat/src/main/java/android/support/v4/os/TraceCompat.java
similarity index 100%
rename from compat/java/android/support/v4/os/TraceCompat.java
rename to compat/src/main/java/android/support/v4/os/TraceCompat.java
diff --git a/compat/java/android/support/v4/os/UserManagerCompat.java b/compat/src/main/java/android/support/v4/os/UserManagerCompat.java
similarity index 100%
rename from compat/java/android/support/v4/os/UserManagerCompat.java
rename to compat/src/main/java/android/support/v4/os/UserManagerCompat.java
diff --git a/compat/java/android/support/v4/os/package.html b/compat/src/main/java/android/support/v4/os/package.html
similarity index 100%
rename from compat/java/android/support/v4/os/package.html
rename to compat/src/main/java/android/support/v4/os/package.html
diff --git a/compat/java/android/support/v4/provider/FontRequest.java b/compat/src/main/java/android/support/v4/provider/FontRequest.java
similarity index 100%
rename from compat/java/android/support/v4/provider/FontRequest.java
rename to compat/src/main/java/android/support/v4/provider/FontRequest.java
diff --git a/compat/java/android/support/v4/provider/FontsContractCompat.java b/compat/src/main/java/android/support/v4/provider/FontsContractCompat.java
similarity index 88%
rename from compat/java/android/support/v4/provider/FontsContractCompat.java
rename to compat/src/main/java/android/support/v4/provider/FontsContractCompat.java
index 3511f3a..9ef1b0b 100644
--- a/compat/java/android/support/v4/provider/FontsContractCompat.java
+++ b/compat/src/main/java/android/support/v4/provider/FontsContractCompat.java
@@ -17,7 +17,6 @@
package android.support.v4.provider;
import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-import static android.support.v4.content.res.FontResourcesParserCompat.FetchStrategy;
import android.annotation.SuppressLint;
import android.content.ContentResolver;
@@ -46,17 +45,16 @@
import android.support.annotation.RestrictTo;
import android.support.annotation.VisibleForTesting;
import android.support.v4.content.res.FontResourcesParserCompat;
+import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.graphics.TypefaceCompat;
import android.support.v4.graphics.TypefaceCompatUtil;
import android.support.v4.provider.SelfDestructiveThread.ReplyCallback;
import android.support.v4.util.LruCache;
import android.support.v4.util.Preconditions;
import android.support.v4.util.SimpleArrayMap;
-import android.widget.TextView;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
@@ -166,11 +164,11 @@
// space open for new provider codes, these should all be negative numbers.
/** @hide */
@RestrictTo(LIBRARY_GROUP)
- public static final int RESULT_CODE_PROVIDER_NOT_FOUND = -1;
+ /* package */ static final int RESULT_CODE_PROVIDER_NOT_FOUND = -1;
/** @hide */
@RestrictTo(LIBRARY_GROUP)
- public static final int RESULT_CODE_WRONG_CERTIFICATES = -2;
- // Note -3 is used by Typeface to indicate the font failed to load.
+ /* package */ static final int RESULT_CODE_WRONG_CERTIFICATES = -2;
+ // Note -3 is used by FontRequestCallback to indicate the font failed to load.
private static final LruCache<String, Typeface> sTypefaceCache = new LruCache<>(16);
@@ -179,51 +177,87 @@
new SelfDestructiveThread("fonts", Process.THREAD_PRIORITY_BACKGROUND,
BACKGROUND_THREAD_KEEP_ALIVE_DURATION_MS);
- private static Typeface getFontInternal(final Context context, final FontRequest request,
+ @NonNull
+ private static TypefaceResult getFontInternal(final Context context, final FontRequest request,
int style) {
FontFamilyResult result;
try {
result = fetchFonts(context, null /* CancellationSignal */, request);
} catch (PackageManager.NameNotFoundException e) {
- return null;
+ return new TypefaceResult(null, FontRequestCallback.FAIL_REASON_PROVIDER_NOT_FOUND);
}
if (result.getStatusCode() == FontFamilyResult.STATUS_OK) {
- return TypefaceCompat.createFromFontInfo(context, null /* CancellationSignal */,
- result.getFonts(), style);
+ final Typeface typeface = TypefaceCompat.createFromFontInfo(
+ context, null /* CancellationSignal */, result.getFonts(), style);
+ return new TypefaceResult(typeface, typeface != null
+ ? FontRequestCallback.RESULT_OK
+ : FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR);
}
- return null;
+ int resultCode = result.getStatusCode() == FontFamilyResult.STATUS_WRONG_CERTIFICATES
+ ? FontRequestCallback.FAIL_REASON_WRONG_CERTIFICATES
+ : FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR;
+ return new TypefaceResult(null, resultCode);
}
private static final Object sLock = new Object();
@GuardedBy("sLock")
- private static final SimpleArrayMap<String, ArrayList<ReplyCallback<Typeface>>>
+ private static final SimpleArrayMap<String, ArrayList<ReplyCallback<TypefaceResult>>>
sPendingReplies = new SimpleArrayMap<>();
+ private static final class TypefaceResult {
+ final Typeface mTypeface;
+ @FontRequestCallback.FontRequestFailReason final int mResult;
+
+ TypefaceResult(@Nullable Typeface typeface,
+ @FontRequestCallback.FontRequestFailReason int result) {
+ mTypeface = typeface;
+ mResult = result;
+ }
+ }
+
+ /**
+ * Used for tests, should not be used otherwise.
+ * @hide
+ **/
+ @RestrictTo(LIBRARY_GROUP)
+ public static final void resetCache() {
+ sTypefaceCache.evictAll();
+ }
+
/** @hide */
@RestrictTo(LIBRARY_GROUP)
public static Typeface getFontSync(final Context context, final FontRequest request,
- final @Nullable TextView targetView, @FetchStrategy int strategy, int timeout,
+ final @Nullable ResourcesCompat.FontCallback fontCallback,
+ final @Nullable Handler handler, boolean isBlockingFetch, int timeout,
final int style) {
final String id = request.getIdentifier() + "-" + style;
Typeface cached = sTypefaceCache.get(id);
if (cached != null) {
+ if (fontCallback != null) {
+ fontCallback.onFontRetrieved(cached);
+ }
return cached;
}
- final boolean isBlockingFetch =
- strategy == FontResourcesParserCompat.FETCH_STRATEGY_BLOCKING;
-
if (isBlockingFetch && timeout == FontResourcesParserCompat.INFINITE_TIMEOUT_VALUE) {
// Wait forever. No need to post to the thread.
- return getFontInternal(context, request, style);
+ TypefaceResult typefaceResult = getFontInternal(context, request, style);
+ if (fontCallback != null) {
+ if (typefaceResult.mResult == FontFamilyResult.STATUS_OK) {
+ fontCallback.callbackSuccessAsync(typefaceResult.mTypeface, handler);
+ } else {
+ fontCallback.callbackFailAsync(typefaceResult.mResult, handler);
+ }
+ }
+ return typefaceResult.mTypeface;
}
- final Callable<Typeface> fetcher = new Callable<Typeface>() {
+ final Callable<TypefaceResult> fetcher = new Callable<TypefaceResult>() {
@Override
- public Typeface call() throws Exception {
- Typeface typeface = getFontInternal(context, request, style);
- if (typeface != null) {
- sTypefaceCache.put(id, typeface);
+ public TypefaceResult call() throws Exception {
+ TypefaceResult typeface = getFontInternal(context, request, style);
+ if (typeface.mTypeface != null) {
+ sTypefaceCache.put(id, typeface.mTypeface);
}
return typeface;
}
@@ -231,37 +265,42 @@
if (isBlockingFetch) {
try {
- return sBackgroundThread.postAndWait(fetcher, timeout);
+ return sBackgroundThread.postAndWait(fetcher, timeout).mTypeface;
} catch (InterruptedException e) {
return null;
}
} else {
- final WeakReference<TextView> textViewWeak = new WeakReference<TextView>(targetView);
- final ReplyCallback<Typeface> reply = new ReplyCallback<Typeface>() {
- @Override
- public void onReply(final Typeface typeface) {
- final TextView textView = textViewWeak.get();
- if (textView != null) {
- targetView.setTypeface(typeface, style);
- }
- }
- };
+ final ReplyCallback<TypefaceResult> reply = fontCallback == null ? null
+ : new ReplyCallback<TypefaceResult>() {
+ @Override
+ public void onReply(final TypefaceResult typeface) {
+ if (typeface.mResult == FontFamilyResult.STATUS_OK) {
+ fontCallback.callbackSuccessAsync(typeface.mTypeface, handler);
+ } else {
+ fontCallback.callbackFailAsync(typeface.mResult, handler);
+ }
+ }
+ };
synchronized (sLock) {
if (sPendingReplies.containsKey(id)) {
// Already requested. Do not request the same provider again and insert the
// reply to the queue instead.
- sPendingReplies.get(id).add(reply);
+ if (reply != null) {
+ sPendingReplies.get(id).add(reply);
+ }
return null;
}
- ArrayList<ReplyCallback<Typeface>> pendingReplies = new ArrayList<>();
- pendingReplies.add(reply);
- sPendingReplies.put(id, pendingReplies);
+ if (reply != null) {
+ ArrayList<ReplyCallback<TypefaceResult>> pendingReplies = new ArrayList<>();
+ pendingReplies.add(reply);
+ sPendingReplies.put(id, pendingReplies);
+ }
}
- sBackgroundThread.postAndReply(fetcher, new ReplyCallback<Typeface>() {
+ sBackgroundThread.postAndReply(fetcher, new ReplyCallback<TypefaceResult>() {
@Override
- public void onReply(final Typeface typeface) {
- final ArrayList<ReplyCallback<Typeface>> replies;
+ public void onReply(final TypefaceResult typeface) {
+ final ArrayList<ReplyCallback<TypefaceResult>> replies;
synchronized (sLock) {
replies = sPendingReplies.get(id);
sPendingReplies.remove(id);
@@ -269,7 +308,7 @@
for (int i = 0; i < replies.size(); ++i) {
replies.get(i).onReply(typeface);
}
- };
+ }
});
return null;
}
@@ -292,8 +331,9 @@
* @param weight An integer that indicates the font weight.
* @param italic A boolean that indicates the font is italic style or not.
* @param resultCode A boolean that indicates the font contents is ready.
+ *
+ * @hide
*/
- /** @hide */
@RestrictTo(LIBRARY_GROUP)
public FontInfo(@NonNull Uri uri, @IntRange(from = 0) int ttcIndex,
@IntRange(from = 1, to = 1000) int weight,
@@ -396,6 +436,9 @@
* Interface used to receive asynchronously fetched typefaces.
*/
public static class FontRequestCallback {
+ /** @hide */
+ @RestrictTo(LIBRARY_GROUP)
+ public static final int RESULT_OK = Columns.RESULT_CODE_OK;
/**
* Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given
* provider was not found on the device.
@@ -412,6 +455,11 @@
*/
public static final int FAIL_REASON_FONT_LOAD_ERROR = -3;
/**
+ * Constant that signals that the font was not loaded due to security issues. This usually
+ * means the font was attempted to load on a restricted context.
+ */
+ public static final int FAIL_REASON_SECURITY_VIOLATION = -4;
+ /**
* Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font
* provider did not return any results for the given query.
*/
@@ -431,9 +479,10 @@
@RestrictTo(LIBRARY_GROUP)
@IntDef({ FAIL_REASON_PROVIDER_NOT_FOUND, FAIL_REASON_FONT_LOAD_ERROR,
FAIL_REASON_FONT_NOT_FOUND, FAIL_REASON_FONT_UNAVAILABLE,
- FAIL_REASON_MALFORMED_QUERY, FAIL_REASON_WRONG_CERTIFICATES })
+ FAIL_REASON_MALFORMED_QUERY, FAIL_REASON_WRONG_CERTIFICATES,
+ FAIL_REASON_SECURITY_VIOLATION, RESULT_OK })
@Retention(RetentionPolicy.SOURCE)
- @interface FontRequestFailReason {}
+ public @interface FontRequestFailReason {}
public FontRequestCallback() {}
diff --git a/compat/java/android/support/v4/provider/SelfDestructiveThread.java b/compat/src/main/java/android/support/v4/provider/SelfDestructiveThread.java
similarity index 99%
rename from compat/java/android/support/v4/provider/SelfDestructiveThread.java
rename to compat/src/main/java/android/support/v4/provider/SelfDestructiveThread.java
index 885799b..7cfe1f8 100644
--- a/compat/java/android/support/v4/provider/SelfDestructiveThread.java
+++ b/compat/src/main/java/android/support/v4/provider/SelfDestructiveThread.java
@@ -129,7 +129,7 @@
/**
* Execute the specific callable object on this thread and call the reply callback on the
- * calling thread once it finishs.
+ * calling thread once it finishes.
*/
public <T> void postAndReply(final Callable<T> callable, final ReplyCallback<T> reply) {
final Handler callingHandler = new Handler();
diff --git a/compat/java/android/support/v4/text/BidiFormatter.java b/compat/src/main/java/android/support/v4/text/BidiFormatter.java
similarity index 100%
rename from compat/java/android/support/v4/text/BidiFormatter.java
rename to compat/src/main/java/android/support/v4/text/BidiFormatter.java
diff --git a/compat/java/android/support/v4/text/ICUCompat.java b/compat/src/main/java/android/support/v4/text/ICUCompat.java
similarity index 100%
rename from compat/java/android/support/v4/text/ICUCompat.java
rename to compat/src/main/java/android/support/v4/text/ICUCompat.java
diff --git a/compat/java/android/support/v4/text/TextDirectionHeuristicCompat.java b/compat/src/main/java/android/support/v4/text/TextDirectionHeuristicCompat.java
similarity index 100%
rename from compat/java/android/support/v4/text/TextDirectionHeuristicCompat.java
rename to compat/src/main/java/android/support/v4/text/TextDirectionHeuristicCompat.java
diff --git a/compat/java/android/support/v4/text/TextDirectionHeuristicsCompat.java b/compat/src/main/java/android/support/v4/text/TextDirectionHeuristicsCompat.java
similarity index 100%
rename from compat/java/android/support/v4/text/TextDirectionHeuristicsCompat.java
rename to compat/src/main/java/android/support/v4/text/TextDirectionHeuristicsCompat.java
diff --git a/compat/java/android/support/v4/text/TextUtilsCompat.java b/compat/src/main/java/android/support/v4/text/TextUtilsCompat.java
similarity index 100%
rename from compat/java/android/support/v4/text/TextUtilsCompat.java
rename to compat/src/main/java/android/support/v4/text/TextUtilsCompat.java
diff --git a/compat/java/android/support/v4/text/util/LinkifyCompat.java b/compat/src/main/java/android/support/v4/text/util/LinkifyCompat.java
similarity index 100%
rename from compat/java/android/support/v4/text/util/LinkifyCompat.java
rename to compat/src/main/java/android/support/v4/text/util/LinkifyCompat.java
diff --git a/compat/java/android/support/v4/util/ArrayMap.java b/compat/src/main/java/android/support/v4/util/ArrayMap.java
similarity index 100%
rename from compat/java/android/support/v4/util/ArrayMap.java
rename to compat/src/main/java/android/support/v4/util/ArrayMap.java
diff --git a/compat/java/android/support/v4/util/ArraySet.java b/compat/src/main/java/android/support/v4/util/ArraySet.java
similarity index 100%
rename from compat/java/android/support/v4/util/ArraySet.java
rename to compat/src/main/java/android/support/v4/util/ArraySet.java
diff --git a/compat/java/android/support/v4/util/AtomicFile.java b/compat/src/main/java/android/support/v4/util/AtomicFile.java
similarity index 100%
rename from compat/java/android/support/v4/util/AtomicFile.java
rename to compat/src/main/java/android/support/v4/util/AtomicFile.java
diff --git a/compat/java/android/support/v4/util/CircularArray.java b/compat/src/main/java/android/support/v4/util/CircularArray.java
similarity index 100%
rename from compat/java/android/support/v4/util/CircularArray.java
rename to compat/src/main/java/android/support/v4/util/CircularArray.java
diff --git a/compat/java/android/support/v4/util/CircularIntArray.java b/compat/src/main/java/android/support/v4/util/CircularIntArray.java
similarity index 100%
rename from compat/java/android/support/v4/util/CircularIntArray.java
rename to compat/src/main/java/android/support/v4/util/CircularIntArray.java
diff --git a/compat/java/android/support/v4/util/ContainerHelpers.java b/compat/src/main/java/android/support/v4/util/ContainerHelpers.java
similarity index 100%
rename from compat/java/android/support/v4/util/ContainerHelpers.java
rename to compat/src/main/java/android/support/v4/util/ContainerHelpers.java
diff --git a/compat/java/android/support/v4/util/DebugUtils.java b/compat/src/main/java/android/support/v4/util/DebugUtils.java
similarity index 100%
rename from compat/java/android/support/v4/util/DebugUtils.java
rename to compat/src/main/java/android/support/v4/util/DebugUtils.java
diff --git a/compat/java/android/support/v4/util/LogWriter.java b/compat/src/main/java/android/support/v4/util/LogWriter.java
similarity index 100%
rename from compat/java/android/support/v4/util/LogWriter.java
rename to compat/src/main/java/android/support/v4/util/LogWriter.java
diff --git a/compat/java/android/support/v4/util/LongSparseArray.java b/compat/src/main/java/android/support/v4/util/LongSparseArray.java
similarity index 100%
rename from compat/java/android/support/v4/util/LongSparseArray.java
rename to compat/src/main/java/android/support/v4/util/LongSparseArray.java
diff --git a/compat/java/android/support/v4/util/LruCache.java b/compat/src/main/java/android/support/v4/util/LruCache.java
similarity index 100%
rename from compat/java/android/support/v4/util/LruCache.java
rename to compat/src/main/java/android/support/v4/util/LruCache.java
diff --git a/compat/java/android/support/v4/util/MapCollections.java b/compat/src/main/java/android/support/v4/util/MapCollections.java
similarity index 100%
rename from compat/java/android/support/v4/util/MapCollections.java
rename to compat/src/main/java/android/support/v4/util/MapCollections.java
diff --git a/compat/java/android/support/v4/util/ObjectsCompat.java b/compat/src/main/java/android/support/v4/util/ObjectsCompat.java
similarity index 100%
rename from compat/java/android/support/v4/util/ObjectsCompat.java
rename to compat/src/main/java/android/support/v4/util/ObjectsCompat.java
diff --git a/compat/java/android/support/v4/util/Pair.java b/compat/src/main/java/android/support/v4/util/Pair.java
similarity index 100%
rename from compat/java/android/support/v4/util/Pair.java
rename to compat/src/main/java/android/support/v4/util/Pair.java
diff --git a/compat/java/android/support/v4/util/PatternsCompat.java b/compat/src/main/java/android/support/v4/util/PatternsCompat.java
similarity index 100%
rename from compat/java/android/support/v4/util/PatternsCompat.java
rename to compat/src/main/java/android/support/v4/util/PatternsCompat.java
diff --git a/compat/java/android/support/v4/util/Pools.java b/compat/src/main/java/android/support/v4/util/Pools.java
similarity index 100%
rename from compat/java/android/support/v4/util/Pools.java
rename to compat/src/main/java/android/support/v4/util/Pools.java
diff --git a/compat/java/android/support/v4/util/Preconditions.java b/compat/src/main/java/android/support/v4/util/Preconditions.java
similarity index 100%
rename from compat/java/android/support/v4/util/Preconditions.java
rename to compat/src/main/java/android/support/v4/util/Preconditions.java
diff --git a/compat/java/android/support/v4/util/SimpleArrayMap.java b/compat/src/main/java/android/support/v4/util/SimpleArrayMap.java
similarity index 100%
rename from compat/java/android/support/v4/util/SimpleArrayMap.java
rename to compat/src/main/java/android/support/v4/util/SimpleArrayMap.java
diff --git a/compat/java/android/support/v4/util/SparseArrayCompat.java b/compat/src/main/java/android/support/v4/util/SparseArrayCompat.java
similarity index 100%
rename from compat/java/android/support/v4/util/SparseArrayCompat.java
rename to compat/src/main/java/android/support/v4/util/SparseArrayCompat.java
diff --git a/compat/java/android/support/v4/util/TimeUtils.java b/compat/src/main/java/android/support/v4/util/TimeUtils.java
similarity index 100%
rename from compat/java/android/support/v4/util/TimeUtils.java
rename to compat/src/main/java/android/support/v4/util/TimeUtils.java
diff --git a/compat/java/android/support/v4/util/package.html b/compat/src/main/java/android/support/v4/util/package.html
similarity index 100%
rename from compat/java/android/support/v4/util/package.html
rename to compat/src/main/java/android/support/v4/util/package.html
diff --git a/compat/java/android/support/v4/view/AccessibilityDelegateCompat.java b/compat/src/main/java/android/support/v4/view/AccessibilityDelegateCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/AccessibilityDelegateCompat.java
rename to compat/src/main/java/android/support/v4/view/AccessibilityDelegateCompat.java
diff --git a/compat/java/android/support/v4/view/ActionProvider.java b/compat/src/main/java/android/support/v4/view/ActionProvider.java
similarity index 100%
rename from compat/java/android/support/v4/view/ActionProvider.java
rename to compat/src/main/java/android/support/v4/view/ActionProvider.java
diff --git a/compat/java/android/support/v4/view/GestureDetectorCompat.java b/compat/src/main/java/android/support/v4/view/GestureDetectorCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/GestureDetectorCompat.java
rename to compat/src/main/java/android/support/v4/view/GestureDetectorCompat.java
diff --git a/compat/java/android/support/v4/view/GravityCompat.java b/compat/src/main/java/android/support/v4/view/GravityCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/GravityCompat.java
rename to compat/src/main/java/android/support/v4/view/GravityCompat.java
diff --git a/compat/java/android/support/v4/view/InputDeviceCompat.java b/compat/src/main/java/android/support/v4/view/InputDeviceCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/InputDeviceCompat.java
rename to compat/src/main/java/android/support/v4/view/InputDeviceCompat.java
diff --git a/compat/java/android/support/v4/view/LayoutInflaterCompat.java b/compat/src/main/java/android/support/v4/view/LayoutInflaterCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/LayoutInflaterCompat.java
rename to compat/src/main/java/android/support/v4/view/LayoutInflaterCompat.java
diff --git a/compat/java/android/support/v4/view/LayoutInflaterFactory.java b/compat/src/main/java/android/support/v4/view/LayoutInflaterFactory.java
similarity index 100%
rename from compat/java/android/support/v4/view/LayoutInflaterFactory.java
rename to compat/src/main/java/android/support/v4/view/LayoutInflaterFactory.java
diff --git a/compat/java/android/support/v4/view/MarginLayoutParamsCompat.java b/compat/src/main/java/android/support/v4/view/MarginLayoutParamsCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/MarginLayoutParamsCompat.java
rename to compat/src/main/java/android/support/v4/view/MarginLayoutParamsCompat.java
diff --git a/compat/java/android/support/v4/view/MenuCompat.java b/compat/src/main/java/android/support/v4/view/MenuCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/MenuCompat.java
rename to compat/src/main/java/android/support/v4/view/MenuCompat.java
diff --git a/compat/java/android/support/v4/view/MenuItemCompat.java b/compat/src/main/java/android/support/v4/view/MenuItemCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/MenuItemCompat.java
rename to compat/src/main/java/android/support/v4/view/MenuItemCompat.java
diff --git a/compat/java/android/support/v4/view/MotionEventCompat.java b/compat/src/main/java/android/support/v4/view/MotionEventCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/MotionEventCompat.java
rename to compat/src/main/java/android/support/v4/view/MotionEventCompat.java
diff --git a/compat/java/android/support/v4/view/NestedScrollingChild.java b/compat/src/main/java/android/support/v4/view/NestedScrollingChild.java
similarity index 100%
rename from compat/java/android/support/v4/view/NestedScrollingChild.java
rename to compat/src/main/java/android/support/v4/view/NestedScrollingChild.java
diff --git a/compat/java/android/support/v4/view/NestedScrollingChild2.java b/compat/src/main/java/android/support/v4/view/NestedScrollingChild2.java
similarity index 100%
rename from compat/java/android/support/v4/view/NestedScrollingChild2.java
rename to compat/src/main/java/android/support/v4/view/NestedScrollingChild2.java
diff --git a/compat/java/android/support/v4/view/NestedScrollingParent.java b/compat/src/main/java/android/support/v4/view/NestedScrollingParent.java
similarity index 100%
rename from compat/java/android/support/v4/view/NestedScrollingParent.java
rename to compat/src/main/java/android/support/v4/view/NestedScrollingParent.java
diff --git a/compat/java/android/support/v4/view/NestedScrollingParent2.java b/compat/src/main/java/android/support/v4/view/NestedScrollingParent2.java
similarity index 100%
rename from compat/java/android/support/v4/view/NestedScrollingParent2.java
rename to compat/src/main/java/android/support/v4/view/NestedScrollingParent2.java
diff --git a/compat/java/android/support/v4/view/OnApplyWindowInsetsListener.java b/compat/src/main/java/android/support/v4/view/OnApplyWindowInsetsListener.java
similarity index 100%
rename from compat/java/android/support/v4/view/OnApplyWindowInsetsListener.java
rename to compat/src/main/java/android/support/v4/view/OnApplyWindowInsetsListener.java
diff --git a/compat/java/android/support/v4/view/PointerIconCompat.java b/compat/src/main/java/android/support/v4/view/PointerIconCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/PointerIconCompat.java
rename to compat/src/main/java/android/support/v4/view/PointerIconCompat.java
diff --git a/compat/java/android/support/v4/view/ScaleGestureDetectorCompat.java b/compat/src/main/java/android/support/v4/view/ScaleGestureDetectorCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/ScaleGestureDetectorCompat.java
rename to compat/src/main/java/android/support/v4/view/ScaleGestureDetectorCompat.java
diff --git a/compat/java/android/support/v4/view/ScrollingView.java b/compat/src/main/java/android/support/v4/view/ScrollingView.java
similarity index 100%
rename from compat/java/android/support/v4/view/ScrollingView.java
rename to compat/src/main/java/android/support/v4/view/ScrollingView.java
diff --git a/compat/java/android/support/v4/view/TintableBackgroundView.java b/compat/src/main/java/android/support/v4/view/TintableBackgroundView.java
similarity index 100%
rename from compat/java/android/support/v4/view/TintableBackgroundView.java
rename to compat/src/main/java/android/support/v4/view/TintableBackgroundView.java
diff --git a/compat/java/android/support/v4/view/VelocityTrackerCompat.java b/compat/src/main/java/android/support/v4/view/VelocityTrackerCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/VelocityTrackerCompat.java
rename to compat/src/main/java/android/support/v4/view/VelocityTrackerCompat.java
diff --git a/compat/java/android/support/v4/view/ViewCompat.java b/compat/src/main/java/android/support/v4/view/ViewCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/ViewCompat.java
rename to compat/src/main/java/android/support/v4/view/ViewCompat.java
diff --git a/compat/java/android/support/v4/view/ViewConfigurationCompat.java b/compat/src/main/java/android/support/v4/view/ViewConfigurationCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/ViewConfigurationCompat.java
rename to compat/src/main/java/android/support/v4/view/ViewConfigurationCompat.java
diff --git a/compat/java/android/support/v4/view/ViewGroupCompat.java b/compat/src/main/java/android/support/v4/view/ViewGroupCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/ViewGroupCompat.java
rename to compat/src/main/java/android/support/v4/view/ViewGroupCompat.java
diff --git a/compat/java/android/support/v4/view/ViewParentCompat.java b/compat/src/main/java/android/support/v4/view/ViewParentCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/ViewParentCompat.java
rename to compat/src/main/java/android/support/v4/view/ViewParentCompat.java
diff --git a/compat/java/android/support/v4/view/ViewPropertyAnimatorCompat.java b/compat/src/main/java/android/support/v4/view/ViewPropertyAnimatorCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/ViewPropertyAnimatorCompat.java
rename to compat/src/main/java/android/support/v4/view/ViewPropertyAnimatorCompat.java
diff --git a/compat/java/android/support/v4/view/ViewPropertyAnimatorListener.java b/compat/src/main/java/android/support/v4/view/ViewPropertyAnimatorListener.java
similarity index 100%
rename from compat/java/android/support/v4/view/ViewPropertyAnimatorListener.java
rename to compat/src/main/java/android/support/v4/view/ViewPropertyAnimatorListener.java
diff --git a/compat/java/android/support/v4/view/ViewPropertyAnimatorListenerAdapter.java b/compat/src/main/java/android/support/v4/view/ViewPropertyAnimatorListenerAdapter.java
similarity index 100%
rename from compat/java/android/support/v4/view/ViewPropertyAnimatorListenerAdapter.java
rename to compat/src/main/java/android/support/v4/view/ViewPropertyAnimatorListenerAdapter.java
diff --git a/compat/java/android/support/v4/view/ViewPropertyAnimatorUpdateListener.java b/compat/src/main/java/android/support/v4/view/ViewPropertyAnimatorUpdateListener.java
similarity index 100%
rename from compat/java/android/support/v4/view/ViewPropertyAnimatorUpdateListener.java
rename to compat/src/main/java/android/support/v4/view/ViewPropertyAnimatorUpdateListener.java
diff --git a/compat/java/android/support/v4/view/WindowCompat.java b/compat/src/main/java/android/support/v4/view/WindowCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/WindowCompat.java
rename to compat/src/main/java/android/support/v4/view/WindowCompat.java
diff --git a/compat/java/android/support/v4/view/WindowInsetsCompat.java b/compat/src/main/java/android/support/v4/view/WindowInsetsCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/WindowInsetsCompat.java
rename to compat/src/main/java/android/support/v4/view/WindowInsetsCompat.java
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityEventCompat.java b/compat/src/main/java/android/support/v4/view/accessibility/AccessibilityEventCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/accessibility/AccessibilityEventCompat.java
rename to compat/src/main/java/android/support/v4/view/accessibility/AccessibilityEventCompat.java
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityManagerCompat.java b/compat/src/main/java/android/support/v4/view/accessibility/AccessibilityManagerCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/accessibility/AccessibilityManagerCompat.java
rename to compat/src/main/java/android/support/v4/view/accessibility/AccessibilityManagerCompat.java
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java b/compat/src/main/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
rename to compat/src/main/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityNodeProviderCompat.java b/compat/src/main/java/android/support/v4/view/accessibility/AccessibilityNodeProviderCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/accessibility/AccessibilityNodeProviderCompat.java
rename to compat/src/main/java/android/support/v4/view/accessibility/AccessibilityNodeProviderCompat.java
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityRecordCompat.java b/compat/src/main/java/android/support/v4/view/accessibility/AccessibilityRecordCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/accessibility/AccessibilityRecordCompat.java
rename to compat/src/main/java/android/support/v4/view/accessibility/AccessibilityRecordCompat.java
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityWindowInfoCompat.java b/compat/src/main/java/android/support/v4/view/accessibility/AccessibilityWindowInfoCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/accessibility/AccessibilityWindowInfoCompat.java
rename to compat/src/main/java/android/support/v4/view/accessibility/AccessibilityWindowInfoCompat.java
diff --git a/compat/java/android/support/v4/view/accessibility/package.html b/compat/src/main/java/android/support/v4/view/accessibility/package.html
similarity index 100%
rename from compat/java/android/support/v4/view/accessibility/package.html
rename to compat/src/main/java/android/support/v4/view/accessibility/package.html
diff --git a/compat/java/android/support/v4/view/animation/PathInterpolatorApi14.java b/compat/src/main/java/android/support/v4/view/animation/PathInterpolatorApi14.java
similarity index 100%
rename from compat/java/android/support/v4/view/animation/PathInterpolatorApi14.java
rename to compat/src/main/java/android/support/v4/view/animation/PathInterpolatorApi14.java
diff --git a/compat/java/android/support/v4/view/animation/PathInterpolatorCompat.java b/compat/src/main/java/android/support/v4/view/animation/PathInterpolatorCompat.java
similarity index 100%
rename from compat/java/android/support/v4/view/animation/PathInterpolatorCompat.java
rename to compat/src/main/java/android/support/v4/view/animation/PathInterpolatorCompat.java
diff --git a/compat/java/android/support/v4/view/package.html b/compat/src/main/java/android/support/v4/view/package.html
similarity index 100%
rename from compat/java/android/support/v4/view/package.html
rename to compat/src/main/java/android/support/v4/view/package.html
diff --git a/compat/java/android/support/v4/widget/AutoSizeableTextView.java b/compat/src/main/java/android/support/v4/widget/AutoSizeableTextView.java
similarity index 100%
rename from compat/java/android/support/v4/widget/AutoSizeableTextView.java
rename to compat/src/main/java/android/support/v4/widget/AutoSizeableTextView.java
diff --git a/compat/java/android/support/v4/widget/CompoundButtonCompat.java b/compat/src/main/java/android/support/v4/widget/CompoundButtonCompat.java
similarity index 100%
rename from compat/java/android/support/v4/widget/CompoundButtonCompat.java
rename to compat/src/main/java/android/support/v4/widget/CompoundButtonCompat.java
diff --git a/compat/java/android/support/v4/widget/EdgeEffectCompat.java b/compat/src/main/java/android/support/v4/widget/EdgeEffectCompat.java
similarity index 100%
rename from compat/java/android/support/v4/widget/EdgeEffectCompat.java
rename to compat/src/main/java/android/support/v4/widget/EdgeEffectCompat.java
diff --git a/compat/java/android/support/v4/widget/ImageViewCompat.java b/compat/src/main/java/android/support/v4/widget/ImageViewCompat.java
similarity index 100%
rename from compat/java/android/support/v4/widget/ImageViewCompat.java
rename to compat/src/main/java/android/support/v4/widget/ImageViewCompat.java
diff --git a/compat/java/android/support/v4/widget/ListPopupWindowCompat.java b/compat/src/main/java/android/support/v4/widget/ListPopupWindowCompat.java
similarity index 100%
rename from compat/java/android/support/v4/widget/ListPopupWindowCompat.java
rename to compat/src/main/java/android/support/v4/widget/ListPopupWindowCompat.java
diff --git a/compat/java/android/support/v4/widget/ListViewCompat.java b/compat/src/main/java/android/support/v4/widget/ListViewCompat.java
similarity index 100%
rename from compat/java/android/support/v4/widget/ListViewCompat.java
rename to compat/src/main/java/android/support/v4/widget/ListViewCompat.java
diff --git a/compat/java/android/support/v4/widget/PopupMenuCompat.java b/compat/src/main/java/android/support/v4/widget/PopupMenuCompat.java
similarity index 100%
rename from compat/java/android/support/v4/widget/PopupMenuCompat.java
rename to compat/src/main/java/android/support/v4/widget/PopupMenuCompat.java
diff --git a/compat/java/android/support/v4/widget/PopupWindowCompat.java b/compat/src/main/java/android/support/v4/widget/PopupWindowCompat.java
similarity index 100%
rename from compat/java/android/support/v4/widget/PopupWindowCompat.java
rename to compat/src/main/java/android/support/v4/widget/PopupWindowCompat.java
diff --git a/compat/java/android/support/v4/widget/ScrollerCompat.java b/compat/src/main/java/android/support/v4/widget/ScrollerCompat.java
similarity index 100%
rename from compat/java/android/support/v4/widget/ScrollerCompat.java
rename to compat/src/main/java/android/support/v4/widget/ScrollerCompat.java
diff --git a/compat/java/android/support/v4/widget/TextViewCompat.java b/compat/src/main/java/android/support/v4/widget/TextViewCompat.java
similarity index 100%
rename from compat/java/android/support/v4/widget/TextViewCompat.java
rename to compat/src/main/java/android/support/v4/widget/TextViewCompat.java
diff --git a/compat/java/android/support/v4/widget/TintableCompoundButton.java b/compat/src/main/java/android/support/v4/widget/TintableCompoundButton.java
similarity index 100%
rename from compat/java/android/support/v4/widget/TintableCompoundButton.java
rename to compat/src/main/java/android/support/v4/widget/TintableCompoundButton.java
diff --git a/compat/java/android/support/v4/widget/TintableImageSourceView.java b/compat/src/main/java/android/support/v4/widget/TintableImageSourceView.java
similarity index 100%
rename from compat/java/android/support/v4/widget/TintableImageSourceView.java
rename to compat/src/main/java/android/support/v4/widget/TintableImageSourceView.java
diff --git a/compat/java/android/support/v4/widget/package.html b/compat/src/main/java/android/support/v4/widget/package.html
similarity index 100%
rename from compat/java/android/support/v4/widget/package.html
rename to compat/src/main/java/android/support/v4/widget/package.html
diff --git a/compat/tests/java/android/support/v4/content/res/FontResourcesParserCompatTest.java b/compat/tests/java/android/support/v4/content/res/FontResourcesParserCompatTest.java
index e7f40cf..fb41792 100644
--- a/compat/tests/java/android/support/v4/content/res/FontResourcesParserCompatTest.java
+++ b/compat/tests/java/android/support/v4/content/res/FontResourcesParserCompatTest.java
@@ -98,10 +98,10 @@
assertNotNull(result);
ProviderResourceEntry providerEntry = (ProviderResourceEntry) result;
FontRequest request = providerEntry.getRequest();
- assertEquals("com.example.test.fontprovider.authority",
+ assertEquals("android.support.provider.fonts.font",
request.getProviderAuthority());
- assertEquals("com.example.test.fontprovider.package", request.getProviderPackage());
- assertEquals("MyRequestedFont", request.getQuery());
+ assertEquals("android.support.compat.test", request.getProviderPackage());
+ assertEquals("singleFontFamily", request.getQuery());
}
@Test
diff --git a/compat/tests/java/android/support/v4/content/res/ResourcesCompatTest.java b/compat/tests/java/android/support/v4/content/res/ResourcesCompatTest.java
index 56f5ab4..b326dd6 100644
--- a/compat/tests/java/android/support/v4/content/res/ResourcesCompatTest.java
+++ b/compat/tests/java/android/support/v4/content/res/ResourcesCompatTest.java
@@ -20,6 +20,7 @@
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
import android.content.Context;
import android.content.res.ColorStateList;
@@ -27,15 +28,21 @@
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
+import android.support.annotation.NonNull;
import android.support.compat.test.R;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
+import android.support.v4.provider.FontsContractCompat;
+import android.support.v4.provider.MockFontProvider;
import android.support.v4.testutils.TestUtils;
import android.util.DisplayMetrics;
import org.junit.Before;
import org.junit.Test;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
@SmallTest
public class ResourcesCompatTest {
private Context mContext;
@@ -45,6 +52,7 @@
public void setup() {
mContext = InstrumentationRegistry.getContext();
mResources = mContext.getResources();
+ MockFontProvider.prepareFontFiles(mContext);
}
@Test
@@ -293,15 +301,49 @@
}
@Test
- public void testGetFont_fontFile() {
+ public void testGetFont_fontFile_sync() {
Typeface font = ResourcesCompat.getFont(mContext, R.font.samplefont);
assertNotNull(font);
assertNotSame(Typeface.DEFAULT, font);
}
+ private static final class FontCallback extends ResourcesCompat.FontCallback {
+ private final CountDownLatch mLatch;
+ Typeface mTypeface;
+
+ FontCallback(CountDownLatch latch) {
+ mLatch = latch;
+ }
+
+ @Override
+ public void onFontRetrieved(@NonNull Typeface typeface) {
+ mTypeface = typeface;
+ mLatch.countDown();
+ }
+
+ @Override
+ public void onFontRetrievalFailed(int reason) {
+ mLatch.countDown();
+ }
+ }
+
@Test
- public void testGetFont_xmlFile() {
+ public void testGetFont_fontFile_async() throws InterruptedException {
+ final CountDownLatch latch = new CountDownLatch(1);
+ final FontCallback callback = new FontCallback(latch);
+ FontsContractCompat.resetCache();
+
+ ResourcesCompat.getFont(mContext, R.font.samplefont, callback, null);
+
+ assertTrue(latch.await(5L, TimeUnit.SECONDS));
+
+ assertNotNull(callback.mTypeface);
+ assertNotSame(Typeface.DEFAULT, callback.mTypeface);
+ }
+
+ @Test
+ public void testGetFont_xmlFile_sync() {
Typeface font = ResourcesCompat.getFont(mContext, R.font.samplexmlfont);
assertNotNull(font);
@@ -309,6 +351,47 @@
}
@Test
+ public void testGetFont_xmlFile_async() throws InterruptedException {
+ final CountDownLatch latch = new CountDownLatch(1);
+ final FontCallback callback = new FontCallback(latch);
+
+ ResourcesCompat.getFont(mContext, R.font.samplexmlfont, callback, null);
+
+ assertTrue(latch.await(5L, TimeUnit.SECONDS));
+
+ assertNotNull(callback.mTypeface);
+ assertNotSame(Typeface.DEFAULT, callback.mTypeface);
+ }
+
+ @Test
+ public void testGetFont_xmlProviderFile_sync() {
+ Typeface font = ResourcesCompat.getFont(mContext, R.font.samplexmldownloadedfont);
+
+ assertNotNull(font);
+ assertNotSame(Typeface.DEFAULT, font);
+ }
+
+ @Test
+ public void testGetFont_xmlProviderFile_async() throws InterruptedException {
+ final CountDownLatch latch = new CountDownLatch(1);
+ final FontCallback callback = new FontCallback(latch);
+
+ // Font provider non-blocking requests post on the calling thread so can't run on
+ // the test thread as it doesn't have a Looper.
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ ResourcesCompat.getFont(mContext, R.font.samplexmldownloadedfont, callback, null);
+ }
+ });
+
+ assertTrue(latch.await(5L, TimeUnit.SECONDS));
+
+ assertNotNull(callback.mTypeface);
+ assertNotSame(Typeface.DEFAULT, callback.mTypeface);
+ }
+
+ @Test
public void testGetFont_invalidXmlFile() {
try {
assertNull(
diff --git a/compat/tests/java/android/support/v4/graphics/TypefaceCompatTest.java b/compat/tests/java/android/support/v4/graphics/TypefaceCompatTest.java
index dab7f0f..dff4c33 100644
--- a/compat/tests/java/android/support/v4/graphics/TypefaceCompatTest.java
+++ b/compat/tests/java/android/support/v4/graphics/TypefaceCompatTest.java
@@ -17,7 +17,10 @@
package android.support.v4.graphics;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import android.annotation.SuppressLint;
import android.app.Instrumentation;
@@ -28,16 +31,17 @@
import android.content.res.Resources;
import android.graphics.Paint;
import android.graphics.Typeface;
+import android.support.annotation.NonNull;
import android.support.compat.test.R;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
-import android.support.testutils.PollingCheck;
import android.support.v4.content.res.FontResourcesParserCompat;
import android.support.v4.content.res.FontResourcesParserCompat.FamilyResourceEntry;
import android.support.v4.content.res.FontResourcesParserCompat.ProviderResourceEntry;
+import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.provider.FontRequest;
+import android.support.v4.provider.FontsContractCompat;
import android.support.v4.provider.MockFontProvider;
-import android.widget.TextView;
import org.junit.After;
import org.junit.Before;
@@ -47,6 +51,8 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
@SmallTest
public class TypefaceCompatTest {
@@ -134,91 +140,169 @@
return new ProviderResourceEntry(request, entry.getFetchStrategy(), entry.getTimeout());
}
- @Test
- public void testCreateFromResourcesFamilyXml_resourceFont_syncloading() throws Exception {
- Typeface typeface = TypefaceCompat.createFromResourcesFamilyXml(mContext,
- getProviderResourceEntry(R.font.styletest_sync_providerfont), mResources,
- R.font.styletest_sync_providerfont, Typeface.NORMAL, null /* TextView */);
- typeface = Typeface.create(typeface, Typeface.NORMAL);
- assertEquals(R.font.large_a, getSelectedFontResourceId(typeface));
+ public static class FontCallback extends ResourcesCompat.FontCallback {
+ private final CountDownLatch mLatch;
+ Typeface mTypeface;
- typeface = TypefaceCompat.createFromResourcesFamilyXml(mContext,
- getProviderResourceEntry(R.font.styletest_sync_providerfont), mResources,
- R.font.styletest_sync_providerfont, Typeface.ITALIC, null /* TextView */);
- typeface = Typeface.create(typeface, Typeface.ITALIC);
- assertEquals(R.font.large_b, getSelectedFontResourceId(typeface));
+ FontCallback(CountDownLatch latch) {
+ mLatch = latch;
+ }
- typeface = TypefaceCompat.createFromResourcesFamilyXml(mContext,
- getProviderResourceEntry(R.font.styletest_sync_providerfont), mResources,
- R.font.styletest_sync_providerfont, Typeface.BOLD, null /* TextView */);
- typeface = Typeface.create(typeface, Typeface.BOLD);
- assertEquals(R.font.large_c, getSelectedFontResourceId(typeface));
+ @Override
+ public void onFontRetrieved(@NonNull Typeface typeface) {
+ mTypeface = typeface;
+ mLatch.countDown();
+ }
- typeface = TypefaceCompat.createFromResourcesFamilyXml(mContext,
- getProviderResourceEntry(R.font.styletest_sync_providerfont), mResources,
- R.font.styletest_sync_providerfont, Typeface.BOLD_ITALIC, null /* TextView */);
- typeface = Typeface.create(typeface, Typeface.BOLD_ITALIC);
- assertEquals(R.font.large_d, getSelectedFontResourceId(typeface));
+ @Override
+ public void onFontRetrievalFailed(int reason) {
+ mLatch.countDown();
+ }
}
@Test
public void testCreateFromResourcesFamilyXml_resourceFont_asyncloading() throws Exception {
+ final Instrumentation inst = InstrumentationRegistry.getInstrumentation();
+ CountDownLatch latch = new CountDownLatch(1);
+ final FontCallback callback = new FontCallback(latch);
+
+ inst.runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ TypefaceCompat.createFromResourcesFamilyXml(mContext,
+ getProviderResourceEntry(R.font.styletest_async_providerfont), mResources,
+ R.font.styletest_async_providerfont, Typeface.NORMAL, callback,
+ null /* handler */, false /* isXmlRequest */);
+ }
+ });
+ assertTrue(latch.await(5L, TimeUnit.SECONDS));
+
+ assertEquals(R.font.large_a, getSelectedFontResourceId(callback.mTypeface));
+
+ latch = new CountDownLatch(1);
+ final FontCallback callback2 = new FontCallback(latch);
+ inst.runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ TypefaceCompat.createFromResourcesFamilyXml(mContext,
+ getProviderResourceEntry(R.font.styletest_async_providerfont), mResources,
+ R.font.styletest_async_providerfont, Typeface.ITALIC, callback2,
+ null /* handler */, false /* isXmlRequest */);
+ }
+ });
+ assertTrue(latch.await(5L, TimeUnit.SECONDS));
+ assertEquals(R.font.large_b, getSelectedFontResourceId(callback2.mTypeface));
+
+ latch = new CountDownLatch(1);
+ final FontCallback callback3 = new FontCallback(latch);
+ inst.runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ TypefaceCompat.createFromResourcesFamilyXml(mContext,
+ getProviderResourceEntry(R.font.styletest_async_providerfont), mResources,
+ R.font.styletest_async_providerfont, Typeface.BOLD, callback3,
+ null /* handler */, false /* isXmlRequest */);
+ }
+ });
+ assertTrue(latch.await(5L, TimeUnit.SECONDS));
+ assertEquals(R.font.large_c, getSelectedFontResourceId(callback3.mTypeface));
+
+ latch = new CountDownLatch(1);
+ final FontCallback callback4 = new FontCallback(latch);
+ inst.runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ TypefaceCompat.createFromResourcesFamilyXml(mContext,
+ getProviderResourceEntry(R.font.styletest_async_providerfont), mResources,
+ R.font.styletest_async_providerfont, Typeface.BOLD_ITALIC, callback4,
+ null /* handler */, false /* isXmlRequest */);
+ }
+ });
+ assertTrue(latch.await(5L, TimeUnit.SECONDS));
+ assertEquals(R.font.large_d, getSelectedFontResourceId(callback4.mTypeface));
+ }
+
+ @Test
+ public void testProviderFont_xmlRequest() {
+ Typeface typeface = TypefaceCompat.createFromResourcesFamilyXml(mContext,
+ getProviderResourceEntry(R.font.samplexmldownloadedfontblocking), mResources,
+ R.font.samplexmldownloadedfontblocking, Typeface.NORMAL, null,
+ null /* handler */, true /* isXmlRequest */);
+
+ assertNotNull(typeface);
+ assertNotEquals(Typeface.DEFAULT, typeface);
+ }
+
+ @Test
+ public void testProviderFont_nonXmlRequest_noCallback() {
+ // If we don't give a callback, the request should be blocking.
+ Typeface typeface = TypefaceCompat.createFromResourcesFamilyXml(mContext,
+ getProviderResourceEntry(R.font.samplexmldownloadedfontblocking), mResources,
+ R.font.samplexmldownloadedfontblocking, Typeface.NORMAL, null,
+ null /* handler */, false /* isXmlRequest */);
+
+ assertNotNull(typeface);
+ assertNotEquals(Typeface.DEFAULT, typeface);
+ }
+
+ @Test
+ public void testProviderFont_nonXmlRequest_withCallback() throws InterruptedException {
Instrumentation inst = InstrumentationRegistry.getInstrumentation();
- final TextView textView = new TextView(mContext);
- PollingCheck.PollingCheckCondition condition = new PollingCheck.PollingCheckCondition() {
- @Override
- public boolean canProceed() {
- return textView.getTypeface() != null;
- }
- };
+ CountDownLatch latch = new CountDownLatch(1);
+ final FontCallback callback = new FontCallback(latch);
+ FontsContractCompat.resetCache();
- textView.setTypeface(null);
+ final Typeface[] result = new Typeface[1];
inst.runOnMainSync(new Runnable() {
@Override
public void run() {
- TypefaceCompat.createFromResourcesFamilyXml(mContext,
- getProviderResourceEntry(R.font.styletest_async_providerfont), mResources,
- R.font.styletest_async_providerfont, Typeface.NORMAL, textView);
+ result[0] = TypefaceCompat.createFromResourcesFamilyXml(mContext,
+ getProviderResourceEntry(R.font.samplexmldownloadedfontblocking),
+ mResources, R.font.samplexmldownloadedfontblocking, Typeface.NORMAL,
+ callback, null /* handler */, false /* isXmlRequest */);
}
});
- PollingCheck.waitFor(condition);
- assertEquals(R.font.large_a, getSelectedFontResourceId(textView.getTypeface()));
+ assertTrue(latch.await(5L, TimeUnit.SECONDS));
+ assertNotNull(callback.mTypeface);
+ assertNull(result[0]);
+ }
- textView.setTypeface(null);
+ @Test
+ public void testProviderFont_nonXmlRequest_withCallback_cached() throws InterruptedException {
+ Instrumentation inst = InstrumentationRegistry.getInstrumentation();
+ CountDownLatch latch = new CountDownLatch(1);
+ final FontCallback callback = new FontCallback(latch);
+ FontsContractCompat.resetCache();
+
+ final Typeface[] result = new Typeface[2];
inst.runOnMainSync(new Runnable() {
@Override
public void run() {
- TypefaceCompat.createFromResourcesFamilyXml(mContext,
- getProviderResourceEntry(R.font.styletest_async_providerfont), mResources,
- R.font.styletest_async_providerfont, Typeface.ITALIC, textView);
+ result[0] = TypefaceCompat.createFromResourcesFamilyXml(mContext,
+ getProviderResourceEntry(R.font.samplexmldownloadedfontblocking),
+ mResources, R.font.samplexmldownloadedfontblocking, Typeface.NORMAL,
+ callback, null /* handler */, false /* isXmlRequest */);
}
});
- PollingCheck.waitFor(condition);
- assertEquals(R.font.large_b, getSelectedFontResourceId(textView.getTypeface()));
+ assertTrue(latch.await(5L, TimeUnit.SECONDS));
+ assertNotNull(callback.mTypeface);
+ assertNull(result[0]);
- textView.setTypeface(null);
+ latch = new CountDownLatch(1);
+ final FontCallback callback2 = new FontCallback(latch);
+
inst.runOnMainSync(new Runnable() {
@Override
public void run() {
- TypefaceCompat.createFromResourcesFamilyXml(mContext,
- getProviderResourceEntry(R.font.styletest_async_providerfont), mResources,
- R.font.styletest_async_providerfont, Typeface.BOLD, textView);
+ result[1] = TypefaceCompat.createFromResourcesFamilyXml(mContext,
+ getProviderResourceEntry(R.font.samplexmldownloadedfontblocking),
+ mResources, R.font.samplexmldownloadedfontblocking, Typeface.NORMAL,
+ callback2, null /* handler */, false /* isXmlRequest */);
}
});
- PollingCheck.waitFor(condition);
- assertEquals(R.font.large_c, getSelectedFontResourceId(textView.getTypeface()));
-
- textView.setTypeface(null);
- inst.runOnMainSync(new Runnable() {
- @Override
- public void run() {
- TypefaceCompat.createFromResourcesFamilyXml(mContext,
- getProviderResourceEntry(R.font.styletest_async_providerfont), mResources,
- R.font.styletest_async_providerfont, Typeface.BOLD_ITALIC, textView);
- }
- });
- PollingCheck.waitFor(condition);
- assertEquals(R.font.large_d, getSelectedFontResourceId(textView.getTypeface()));
+ assertTrue(latch.await(5L, TimeUnit.SECONDS));
+ assertNotNull(callback2.mTypeface);
+ assertNotNull(result[1]);
}
@Test
@@ -228,33 +312,45 @@
final FamilyResourceEntry entry = FontResourcesParserCompat.parse(
mResources.getXml(R.font.styletestfont), mResources);
Typeface typeface = TypefaceCompat.createFromResourcesFamilyXml(mContext, entry, mResources,
- R.font.styletestfont, Typeface.NORMAL, null /* text view */);
- assertEquals(typeface, TypefaceCompat.findFromCache(
- mResources, R.font.styletestfont, Typeface.NORMAL));
+ R.font.styletestfont, Typeface.NORMAL, null /* callback */, null /* handler */,
+ false /* isXmlRequest */);
+ Typeface cachedTypeface = TypefaceCompat.findFromCache(
+ mResources, R.font.styletestfont, Typeface.NORMAL);
+ assertNotNull(cachedTypeface);
+ assertEquals(typeface, cachedTypeface);
typeface = Typeface.create(typeface, Typeface.NORMAL);
// styletestfont has a node of fontStyle="normal" fontWeight="400" font="@font/large_a".
assertEquals(R.font.large_a, getSelectedFontResourceId(typeface));
typeface = TypefaceCompat.createFromResourcesFamilyXml(mContext, entry, mResources,
- R.font.styletestfont, Typeface.ITALIC, null);
- assertEquals(typeface, TypefaceCompat.findFromCache(
- mResources, R.font.styletestfont, Typeface.ITALIC));
+ R.font.styletestfont, Typeface.ITALIC, null /* callback */, null /* handler */,
+ false /* isXmlRequest */);
+ cachedTypeface = TypefaceCompat.findFromCache(
+ mResources, R.font.styletestfont, Typeface.ITALIC);
+ assertNotNull(cachedTypeface);
+ assertEquals(typeface, cachedTypeface);
typeface = Typeface.create(typeface, Typeface.ITALIC);
// styletestfont has a node of fontStyle="italic" fontWeight="400" font="@font/large_b".
assertEquals(R.font.large_b, getSelectedFontResourceId(typeface));
typeface = TypefaceCompat.createFromResourcesFamilyXml(mContext, entry, mResources,
- R.font.styletestfont, Typeface.BOLD, null);
- assertEquals(typeface, TypefaceCompat.findFromCache(
- mResources, R.font.styletestfont, Typeface.BOLD));
+ R.font.styletestfont, Typeface.BOLD, null /* callback */, null /* handler */,
+ false /* isXmlRequest */);
+ cachedTypeface = TypefaceCompat.findFromCache(
+ mResources, R.font.styletestfont, Typeface.BOLD);
+ assertNotNull(cachedTypeface);
+ assertEquals(typeface, cachedTypeface);
typeface = Typeface.create(typeface, Typeface.BOLD);
// styletestfont has a node of fontStyle="normal" fontWeight="700" font="@font/large_c".
assertEquals(R.font.large_c, getSelectedFontResourceId(typeface));
typeface = TypefaceCompat.createFromResourcesFamilyXml(mContext, entry, mResources,
- R.font.styletestfont, Typeface.BOLD_ITALIC, null);
- assertEquals(typeface, TypefaceCompat.findFromCache(
- mResources, R.font.styletestfont, Typeface.BOLD_ITALIC));
+ R.font.styletestfont, Typeface.BOLD_ITALIC, null /* callback */,
+ null /* handler */, false /* isXmlRequest */);
+ cachedTypeface = TypefaceCompat.findFromCache(
+ mResources, R.font.styletestfont, Typeface.BOLD_ITALIC);
+ assertNotNull(cachedTypeface);
+ assertEquals(typeface, cachedTypeface);
typeface = Typeface.create(typeface, Typeface.BOLD_ITALIC);
// styletestfont has a node of fontStyle="italic" fontWeight="700" font="@font/large_d".
assertEquals(R.font.large_d, getSelectedFontResourceId(typeface));
@@ -265,15 +361,19 @@
Typeface typeface = TypefaceCompat.createFromResourcesFontFile(mContext, mResources,
R.font.large_a, "res/font/large_a.ttf", Typeface.NORMAL);
assertNotNull(typeface);
- assertEquals(typeface, TypefaceCompat.findFromCache(
- mResources, R.font.large_a, Typeface.NORMAL));
+ Typeface cachedTypeface = TypefaceCompat.findFromCache(
+ mResources, R.font.large_a, Typeface.NORMAL);
+ assertNotNull(cachedTypeface);
+ assertEquals(typeface, cachedTypeface);
assertEquals(R.font.large_a, getSelectedFontResourceId(typeface));
typeface = TypefaceCompat.createFromResourcesFontFile(mContext, mResources, R.font.large_b,
"res/font/large_b.ttf", Typeface.NORMAL);
assertNotNull(typeface);
- assertEquals(typeface, TypefaceCompat.findFromCache(
- mResources, R.font.large_b, Typeface.NORMAL));
+ cachedTypeface = TypefaceCompat.findFromCache(
+ mResources, R.font.large_b, Typeface.NORMAL);
+ assertNotNull(cachedTypeface);
+ assertEquals(typeface, cachedTypeface);
assertEquals(R.font.large_b, getSelectedFontResourceId(typeface));
}
}
diff --git a/compat/tests/res/font/samplexmldownloadedfont.xml b/compat/tests/res/font/samplexmldownloadedfont.xml
index 659d196..824ad33 100644
--- a/compat/tests/res/font/samplexmldownloadedfont.xml
+++ b/compat/tests/res/font/samplexmldownloadedfont.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
- app:fontProviderAuthority="com.example.test.fontprovider.authority"
- app:fontProviderPackage="com.example.test.fontprovider.package"
- app:fontProviderQuery="MyRequestedFont">
+ app:fontProviderAuthority="android.support.provider.fonts.font"
+ app:fontProviderPackage="android.support.compat.test"
+ app:fontProviderQuery="singleFontFamily"
+ app:fontProviderCerts="@array/mock_provider_certs">
</font-family>
diff --git a/compat/tests/res/font/samplexmldownloadedfontblocking.xml b/compat/tests/res/font/samplexmldownloadedfontblocking.xml
new file mode 100644
index 0000000..3da2382
--- /dev/null
+++ b/compat/tests/res/font/samplexmldownloadedfontblocking.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
+ app:fontProviderAuthority="android.support.provider.fonts.font"
+ app:fontProviderPackage="android.support.compat.test"
+ app:fontProviderQuery="singleFontFamily"
+ app:fontProviderFetchStrategy="blocking"
+ app:fontProviderCerts="@array/mock_provider_certs"
+ app:fontProviderFetchTimeout="-1">
+</font-family>
diff --git a/compat/tests/res/values/arrays.xml b/compat/tests/res/values/arrays.xml
index 1aa87fd..5c127ca 100644
--- a/compat/tests/res/values/arrays.xml
+++ b/compat/tests/res/values/arrays.xml
@@ -30,4 +30,9 @@
<item>@array/certs1</item>
<item>@array/certs2</item>
</array>
+
+ <!-- These are the actual certs for the test running app. -->
+ <array name="mock_provider_certs">
+ <item>MIIB3TCCAUYCAQEwDQYJKoZIhvcNAQEFBQAwNzEWMBQGA1UEAwwNQW5kcm9pZCBEZWJ1ZzEQMA4GA1UECgwHQW5kcm9pZDELMAkGA1UEBhMCVVMwHhcNMTcwMzEwMjE0NzIxWhcNNDcwMzAzMjE0NzIxWjA3MRYwFAYDVQQDDA1BbmRyb2lkIERlYnVnMRAwDgYDVQQKDAdBbmRyb2lkMQswCQYDVQQGEwJVUzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAg9zgUpOAhXrfE17OYlLWkTGCvnSXWi94SpnyVBVZqq33OCbNKaIi5s314f4rhTFp4LDLFozIUihTOH1pJGLvRFqFu78vIpWBNOlj5mDJThBme6Z+eElnIttK/ivcfyaFM1dc55apQIlf9aDCLX6lEp7p1/O0rJKuXWalte+nYwcCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBE6FFD5jx725gyV9Nevmlv7ndQ8/CKj1NC4C2g7sh/wLtegEU8k6VCUyLRl8EEEnXQUtRg7KVquDWwMTKtXZP8EghQ1AGIklH2u1z4w9DgdD0CrJZ9TGPN3jpbOj5RujkHoRr+g6mwMluq0vH1GnOUMEtshkybq15SbDOmXjEUJA==</item>
+ </array>
</resources>
\ No newline at end of file
diff --git a/content/Android.mk b/content/Android.mk
index eff8215..32caf53 100644
--- a/content/Android.mk
+++ b/content/Android.mk
@@ -18,7 +18,7 @@
LOCAL_USE_AAPT2 := true
LOCAL_MODULE := android-support-content
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES := $(call all-java-files-under, src/main/java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
diff --git a/content/build.gradle b/content/build.gradle
index 1b2d182..af33423 100644
--- a/content/build.gradle
+++ b/content/build.gradle
@@ -29,11 +29,6 @@
defaultConfig {
minSdkVersion 14
}
-
- sourceSets {
- main.java.srcDirs = ['src']
- main.res.srcDir 'res'
- }
}
supportLibrary {
diff --git a/content/src/android/support/content/ContentPager.java b/content/src/main/java/android/support/content/ContentPager.java
similarity index 100%
rename from content/src/android/support/content/ContentPager.java
rename to content/src/main/java/android/support/content/ContentPager.java
diff --git a/content/src/android/support/content/InMemoryCursor.java b/content/src/main/java/android/support/content/InMemoryCursor.java
similarity index 100%
rename from content/src/android/support/content/InMemoryCursor.java
rename to content/src/main/java/android/support/content/InMemoryCursor.java
diff --git a/content/src/android/support/content/LoaderQueryRunner.java b/content/src/main/java/android/support/content/LoaderQueryRunner.java
similarity index 100%
rename from content/src/android/support/content/LoaderQueryRunner.java
rename to content/src/main/java/android/support/content/LoaderQueryRunner.java
diff --git a/content/src/android/support/content/Query.java b/content/src/main/java/android/support/content/Query.java
similarity index 100%
rename from content/src/android/support/content/Query.java
rename to content/src/main/java/android/support/content/Query.java
diff --git a/core-ui/Android.mk b/core-ui/Android.mk
index bb7a4be..184d7be 100644
--- a/core-ui/Android.mk
+++ b/core-ui/Android.mk
@@ -26,7 +26,7 @@
LOCAL_USE_AAPT2 := true
LOCAL_MODULE := android-support-core-ui
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-LOCAL_SRC_FILES := $(call all-java-files-under,java)
+LOCAL_SRC_FILES := $(call all-java-files-under,src/main/java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
diff --git a/core-ui/build.gradle b/core-ui/build.gradle
index 46abf57..38a4fe2 100644
--- a/core-ui/build.gradle
+++ b/core-ui/build.gradle
@@ -16,12 +16,6 @@
minSdkVersion 14
}
- sourceSets {
- main.java.srcDirs = [
- 'java'
- ]
- }
-
buildTypes.all {
consumerProguardFiles 'proguard-rules.pro'
}
diff --git a/core-ui/java/android/support/v4/app/ActionBarDrawerToggle.java b/core-ui/src/main/java/android/support/v4/app/ActionBarDrawerToggle.java
similarity index 100%
rename from core-ui/java/android/support/v4/app/ActionBarDrawerToggle.java
rename to core-ui/src/main/java/android/support/v4/app/ActionBarDrawerToggle.java
diff --git a/core-ui/java/android/support/v4/app/package.html b/core-ui/src/main/java/android/support/v4/app/package.html
similarity index 100%
rename from core-ui/java/android/support/v4/app/package.html
rename to core-ui/src/main/java/android/support/v4/app/package.html
diff --git a/core-ui/java/android/support/v4/view/AbsSavedState.java b/core-ui/src/main/java/android/support/v4/view/AbsSavedState.java
similarity index 90%
rename from core-ui/java/android/support/v4/view/AbsSavedState.java
rename to core-ui/src/main/java/android/support/v4/view/AbsSavedState.java
index 4cf38ac..86f491f 100644
--- a/core-ui/java/android/support/v4/view/AbsSavedState.java
+++ b/core-ui/src/main/java/android/support/v4/view/AbsSavedState.java
@@ -18,6 +18,8 @@
import android.os.Parcel;
import android.os.Parcelable;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
/**
* A {@link Parcelable} implementation that should be used by inheritance
@@ -40,7 +42,7 @@
*
* @param superState The state of the superclass of this view
*/
- protected AbsSavedState(Parcelable superState) {
+ protected AbsSavedState(@NonNull Parcelable superState) {
if (superState == null) {
throw new IllegalArgumentException("superState must not be null");
}
@@ -52,7 +54,7 @@
*
* @param source parcel to read from
*/
- protected AbsSavedState(Parcel source) {
+ protected AbsSavedState(@NonNull Parcel source) {
this(source, null);
}
@@ -62,11 +64,12 @@
* @param source parcel to read from
* @param loader ClassLoader to use for reading
*/
- protected AbsSavedState(Parcel source, ClassLoader loader) {
+ protected AbsSavedState(@NonNull Parcel source, @Nullable ClassLoader loader) {
Parcelable superState = source.readParcelable(loader);
mSuperState = superState != null ? superState : EMPTY_STATE;
}
+ @Nullable
public final Parcelable getSuperState() {
return mSuperState;
}
diff --git a/core-ui/java/android/support/v4/view/AsyncLayoutInflater.java b/core-ui/src/main/java/android/support/v4/view/AsyncLayoutInflater.java
similarity index 98%
rename from core-ui/java/android/support/v4/view/AsyncLayoutInflater.java
rename to core-ui/src/main/java/android/support/v4/view/AsyncLayoutInflater.java
index e194a50..d26e5b8 100644
--- a/core-ui/java/android/support/v4/view/AsyncLayoutInflater.java
+++ b/core-ui/src/main/java/android/support/v4/view/AsyncLayoutInflater.java
@@ -107,7 +107,8 @@
};
public interface OnInflateFinishedListener {
- void onInflateFinished(View view, int resid, ViewGroup parent);
+ void onInflateFinished(@NonNull View view, @LayoutRes int resid,
+ @Nullable ViewGroup parent);
}
private static class InflateRequest {
diff --git a/core-ui/java/android/support/v4/view/NestedScrollingChildHelper.java b/core-ui/src/main/java/android/support/v4/view/NestedScrollingChildHelper.java
similarity index 100%
rename from core-ui/java/android/support/v4/view/NestedScrollingChildHelper.java
rename to core-ui/src/main/java/android/support/v4/view/NestedScrollingChildHelper.java
diff --git a/core-ui/java/android/support/v4/view/NestedScrollingParentHelper.java b/core-ui/src/main/java/android/support/v4/view/NestedScrollingParentHelper.java
similarity index 100%
rename from core-ui/java/android/support/v4/view/NestedScrollingParentHelper.java
rename to core-ui/src/main/java/android/support/v4/view/NestedScrollingParentHelper.java
diff --git a/core-ui/java/android/support/v4/view/PagerAdapter.java b/core-ui/src/main/java/android/support/v4/view/PagerAdapter.java
similarity index 90%
rename from core-ui/java/android/support/v4/view/PagerAdapter.java
rename to core-ui/src/main/java/android/support/v4/view/PagerAdapter.java
index 1b1dc3d..a8fb099 100644
--- a/core-ui/java/android/support/v4/view/PagerAdapter.java
+++ b/core-ui/src/main/java/android/support/v4/view/PagerAdapter.java
@@ -19,6 +19,8 @@
import android.database.DataSetObservable;
import android.database.DataSetObserver;
import android.os.Parcelable;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.view.View;
import android.view.ViewGroup;
@@ -92,7 +94,7 @@
* @param container The containing View which is displaying this adapter's
* page views.
*/
- public void startUpdate(ViewGroup container) {
+ public void startUpdate(@NonNull ViewGroup container) {
startUpdate((View) container);
}
@@ -107,7 +109,8 @@
* @return Returns an Object representing the new page. This does not
* need to be a View, but can be some other container of the page.
*/
- public Object instantiateItem(ViewGroup container, int position) {
+ @NonNull
+ public Object instantiateItem(@NonNull ViewGroup container, int position) {
return instantiateItem((View) container, position);
}
@@ -121,7 +124,7 @@
* @param object The same object that was returned by
* {@link #instantiateItem(View, int)}.
*/
- public void destroyItem(ViewGroup container, int position, Object object) {
+ public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
destroyItem((View) container, position, object);
}
@@ -134,7 +137,7 @@
* @param object The same object that was returned by
* {@link #instantiateItem(View, int)}.
*/
- public void setPrimaryItem(ViewGroup container, int position, Object object) {
+ public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
setPrimaryItem((View) container, position, object);
}
@@ -145,7 +148,7 @@
* @param container The containing View which is displaying this adapter's
* page views.
*/
- public void finishUpdate(ViewGroup container) {
+ public void finishUpdate(@NonNull ViewGroup container) {
finishUpdate((View) container);
}
@@ -157,7 +160,7 @@
* @deprecated Use {@link #startUpdate(ViewGroup)}
*/
@Deprecated
- public void startUpdate(View container) {
+ public void startUpdate(@NonNull View container) {
}
/**
@@ -174,7 +177,8 @@
* @deprecated Use {@link #instantiateItem(ViewGroup, int)}
*/
@Deprecated
- public Object instantiateItem(View container, int position) {
+ @NonNull
+ public Object instantiateItem(@NonNull View container, int position) {
throw new UnsupportedOperationException(
"Required method instantiateItem was not overridden");
}
@@ -192,7 +196,7 @@
* @deprecated Use {@link #destroyItem(ViewGroup, int, Object)}
*/
@Deprecated
- public void destroyItem(View container, int position, Object object) {
+ public void destroyItem(@NonNull View container, int position, @NonNull Object object) {
throw new UnsupportedOperationException("Required method destroyItem was not overridden");
}
@@ -208,7 +212,7 @@
* @deprecated Use {@link #setPrimaryItem(ViewGroup, int, Object)}
*/
@Deprecated
- public void setPrimaryItem(View container, int position, Object object) {
+ public void setPrimaryItem(@NonNull View container, int position, @NonNull Object object) {
}
/**
@@ -221,7 +225,7 @@
* @deprecated Use {@link #finishUpdate(ViewGroup)}
*/
@Deprecated
- public void finishUpdate(View container) {
+ public void finishUpdate(@NonNull View container) {
}
/**
@@ -233,7 +237,7 @@
* @param object Object to check for association with <code>view</code>
* @return true if <code>view</code> is associated with the key object <code>object</code>
*/
- public abstract boolean isViewFromObject(View view, Object object);
+ public abstract boolean isViewFromObject(@NonNull View view, @NonNull Object object);
/**
* Save any instance state associated with this adapter and its pages that should be
@@ -241,6 +245,7 @@
*
* @return Saved state for this adapter
*/
+ @Nullable
public Parcelable saveState() {
return null;
}
@@ -252,7 +257,7 @@
* @param state State previously saved by a call to {@link #saveState()}
* @param loader A ClassLoader that should be used to instantiate any restored objects
*/
- public void restoreState(Parcelable state, ClassLoader loader) {
+ public void restoreState(@Nullable Parcelable state, @Nullable ClassLoader loader) {
}
/**
@@ -270,7 +275,7 @@
* {@link #POSITION_UNCHANGED} if the object's position has not changed,
* or {@link #POSITION_NONE} if the item is no longer present.
*/
- public int getItemPosition(Object object) {
+ public int getItemPosition(@NonNull Object object) {
return POSITION_UNCHANGED;
}
@@ -292,7 +297,7 @@
*
* @param observer The {@link android.database.DataSetObserver} which will receive callbacks.
*/
- public void registerDataSetObserver(DataSetObserver observer) {
+ public void registerDataSetObserver(@NonNull DataSetObserver observer) {
mObservable.registerObserver(observer);
}
@@ -301,7 +306,7 @@
*
* @param observer The {@link android.database.DataSetObserver} which will be unregistered.
*/
- public void unregisterDataSetObserver(DataSetObserver observer) {
+ public void unregisterDataSetObserver(@NonNull DataSetObserver observer) {
mObservable.unregisterObserver(observer);
}
@@ -320,6 +325,7 @@
* @param position The position of the title requested
* @return A title for the requested page
*/
+ @Nullable
public CharSequence getPageTitle(int position) {
return null;
}
diff --git a/core-ui/java/android/support/v4/view/PagerTabStrip.java b/core-ui/src/main/java/android/support/v4/view/PagerTabStrip.java
similarity index 97%
rename from core-ui/java/android/support/v4/view/PagerTabStrip.java
rename to core-ui/src/main/java/android/support/v4/view/PagerTabStrip.java
index f4c0b21..6c88572 100644
--- a/core-ui/java/android/support/v4/view/PagerTabStrip.java
+++ b/core-ui/src/main/java/android/support/v4/view/PagerTabStrip.java
@@ -24,6 +24,8 @@
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 android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -76,11 +78,11 @@
private float mInitialMotionY;
private int mTouchSlop;
- public PagerTabStrip(Context context) {
+ public PagerTabStrip(@NonNull Context context) {
this(context, null);
}
- public PagerTabStrip(Context context, AttributeSet attrs) {
+ public PagerTabStrip(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mIndicatorColor = mTextColor;
diff --git a/core-ui/java/android/support/v4/view/PagerTitleStrip.java b/core-ui/src/main/java/android/support/v4/view/PagerTitleStrip.java
similarity index 98%
rename from core-ui/java/android/support/v4/view/PagerTitleStrip.java
rename to core-ui/src/main/java/android/support/v4/view/PagerTitleStrip.java
index b63e4f4..79a6240 100644
--- a/core-ui/java/android/support/v4/view/PagerTitleStrip.java
+++ b/core-ui/src/main/java/android/support/v4/view/PagerTitleStrip.java
@@ -22,6 +22,8 @@
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.annotation.FloatRange;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.v4.widget.TextViewCompat;
import android.text.TextUtils.TruncateAt;
import android.text.method.SingleLineTransformationMethod;
@@ -102,11 +104,11 @@
text.setTransformationMethod(new SingleLineAllCapsTransform(text.getContext()));
}
- public PagerTitleStrip(Context context) {
+ public PagerTitleStrip(@NonNull Context context) {
this(context, null);
}
- public PagerTitleStrip(Context context, AttributeSet attrs) {
+ public PagerTitleStrip(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
addView(mPrevText = new TextView(context));
diff --git a/core-ui/java/android/support/v4/view/ViewPager.java b/core-ui/src/main/java/android/support/v4/view/ViewPager.java
similarity index 98%
rename from core-ui/java/android/support/v4/view/ViewPager.java
rename to core-ui/src/main/java/android/support/v4/view/ViewPager.java
index 8cd973c..36d8696 100644
--- a/core-ui/java/android/support/v4/view/ViewPager.java
+++ b/core-ui/src/main/java/android/support/v4/view/ViewPager.java
@@ -347,7 +347,7 @@
* position of the pager. 0 is front and center. 1 is one full
* page position to the right, and -1 is one page position to the left.
*/
- void transformPage(View page, float position);
+ void transformPage(@NonNull View page, float position);
}
/**
@@ -381,12 +381,12 @@
public @interface DecorView {
}
- public ViewPager(Context context) {
+ public ViewPager(@NonNull Context context) {
super(context);
initViewPager();
}
- public ViewPager(Context context, AttributeSet attrs) {
+ public ViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initViewPager();
}
@@ -496,7 +496,7 @@
*
* @param adapter Adapter to use
*/
- public void setAdapter(PagerAdapter adapter) {
+ public void setAdapter(@Nullable PagerAdapter adapter) {
if (mAdapter != null) {
mAdapter.setViewPagerObserver(null);
mAdapter.startUpdate(this);
@@ -561,6 +561,7 @@
*
* @return The currently registered PagerAdapter
*/
+ @Nullable
public PagerAdapter getAdapter() {
return mAdapter;
}
@@ -712,7 +713,7 @@
*
* @param listener listener to add
*/
- public void addOnPageChangeListener(OnPageChangeListener listener) {
+ public void addOnPageChangeListener(@NonNull OnPageChangeListener listener) {
if (mOnPageChangeListeners == null) {
mOnPageChangeListeners = new ArrayList<>();
}
@@ -725,7 +726,7 @@
*
* @param listener listener to remove
*/
- public void removeOnPageChangeListener(OnPageChangeListener listener) {
+ public void removeOnPageChangeListener(@NonNull OnPageChangeListener listener) {
if (mOnPageChangeListeners != null) {
mOnPageChangeListeners.remove(listener);
}
@@ -757,7 +758,8 @@
* to be drawn from last to first instead of first to last.
* @param transformer PageTransformer that will modify each page's animation properties
*/
- public void setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer) {
+ public void setPageTransformer(boolean reverseDrawingOrder,
+ @Nullable PageTransformer transformer) {
setPageTransformer(reverseDrawingOrder, transformer, View.LAYER_TYPE_HARDWARE);
}
@@ -774,8 +776,8 @@
* {@link View#LAYER_TYPE_SOFTWARE}, or
* {@link View#LAYER_TYPE_NONE}.
*/
- public void setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer,
- int pageLayerType) {
+ public void setPageTransformer(boolean reverseDrawingOrder,
+ @Nullable PageTransformer transformer, int pageLayerType) {
final boolean hasTransformer = transformer != null;
final boolean needsPopulate = hasTransformer != (mPageTransformer != null);
mPageTransformer = transformer;
@@ -881,7 +883,7 @@
*
* @param d Drawable to display between pages
*/
- public void setPageMarginDrawable(Drawable d) {
+ public void setPageMarginDrawable(@Nullable Drawable d) {
mMarginDrawable = d;
if (d != null) refreshDrawableState();
setWillNotDraw(d == null);
@@ -1383,7 +1385,7 @@
Parcelable adapterState;
ClassLoader loader;
- public SavedState(Parcelable superState) {
+ public SavedState(@NonNull Parcelable superState) {
super(superState);
}
@@ -2744,7 +2746,7 @@
* @param event The key event to execute.
* @return Return true if the event was handled, else false.
*/
- public boolean executeKeyEvent(KeyEvent event) {
+ public boolean executeKeyEvent(@NonNull KeyEvent event) {
boolean handled = false;
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (event.getKeyCode()) {
diff --git a/core-ui/java/android/support/v4/view/animation/FastOutLinearInInterpolator.java b/core-ui/src/main/java/android/support/v4/view/animation/FastOutLinearInInterpolator.java
similarity index 100%
rename from core-ui/java/android/support/v4/view/animation/FastOutLinearInInterpolator.java
rename to core-ui/src/main/java/android/support/v4/view/animation/FastOutLinearInInterpolator.java
diff --git a/core-ui/java/android/support/v4/view/animation/FastOutSlowInInterpolator.java b/core-ui/src/main/java/android/support/v4/view/animation/FastOutSlowInInterpolator.java
similarity index 100%
rename from core-ui/java/android/support/v4/view/animation/FastOutSlowInInterpolator.java
rename to core-ui/src/main/java/android/support/v4/view/animation/FastOutSlowInInterpolator.java
diff --git a/core-ui/java/android/support/v4/view/animation/LinearOutSlowInInterpolator.java b/core-ui/src/main/java/android/support/v4/view/animation/LinearOutSlowInInterpolator.java
similarity index 100%
rename from core-ui/java/android/support/v4/view/animation/LinearOutSlowInInterpolator.java
rename to core-ui/src/main/java/android/support/v4/view/animation/LinearOutSlowInInterpolator.java
diff --git a/core-ui/java/android/support/v4/view/animation/LookupTableInterpolator.java b/core-ui/src/main/java/android/support/v4/view/animation/LookupTableInterpolator.java
similarity index 100%
rename from core-ui/java/android/support/v4/view/animation/LookupTableInterpolator.java
rename to core-ui/src/main/java/android/support/v4/view/animation/LookupTableInterpolator.java
diff --git a/core-ui/java/android/support/v4/view/package.html b/core-ui/src/main/java/android/support/v4/view/package.html
similarity index 100%
rename from core-ui/java/android/support/v4/view/package.html
rename to core-ui/src/main/java/android/support/v4/view/package.html
diff --git a/core-ui/java/android/support/v4/widget/AutoScrollHelper.java b/core-ui/src/main/java/android/support/v4/widget/AutoScrollHelper.java
similarity index 99%
rename from core-ui/java/android/support/v4/widget/AutoScrollHelper.java
rename to core-ui/src/main/java/android/support/v4/widget/AutoScrollHelper.java
index d0407be..60d208d 100644
--- a/core-ui/java/android/support/v4/widget/AutoScrollHelper.java
+++ b/core-ui/src/main/java/android/support/v4/widget/AutoScrollHelper.java
@@ -18,6 +18,7 @@
import android.content.res.Resources;
import android.os.SystemClock;
+import android.support.annotation.NonNull;
import android.support.v4.view.ViewCompat;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
@@ -205,7 +206,7 @@
*
* @param target The view to automatically scroll.
*/
- public AutoScrollHelper(View target) {
+ public AutoScrollHelper(@NonNull View target) {
mTarget = target;
final DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
@@ -289,6 +290,7 @@
* {@link #NO_MAX} to leave the relative value unconstrained.
* @return The scroll helper, which may used to chain setter calls.
*/
+ @NonNull
public AutoScrollHelper setMaximumVelocity(float horizontalMax, float verticalMax) {
mMaximumVelocity[HORIZONTAL] = horizontalMax / 1000f;
mMaximumVelocity[VERTICAL] = verticalMax / 1000f;
@@ -307,6 +309,7 @@
* {@link #NO_MIN} to leave the relative value unconstrained.
* @return The scroll helper, which may used to chain setter calls.
*/
+ @NonNull
public AutoScrollHelper setMinimumVelocity(float horizontalMin, float verticalMin) {
mMinimumVelocity[HORIZONTAL] = horizontalMin / 1000f;
mMinimumVelocity[VERTICAL] = verticalMin / 1000f;
@@ -328,6 +331,7 @@
* ignore.
* @return The scroll helper, which may used to chain setter calls.
*/
+ @NonNull
public AutoScrollHelper setRelativeVelocity(float horizontal, float vertical) {
mRelativeVelocity[HORIZONTAL] = horizontal / 1000f;
mRelativeVelocity[VERTICAL] = vertical / 1000f;
@@ -349,6 +353,7 @@
* @param type The type of edge to use.
* @return The scroll helper, which may used to chain setter calls.
*/
+ @NonNull
public AutoScrollHelper setEdgeType(int type) {
mEdgeType = type;
return this;
@@ -368,6 +373,7 @@
* maximum value.
* @return The scroll helper, which may used to chain setter calls.
*/
+ @NonNull
public AutoScrollHelper setRelativeEdges(float horizontal, float vertical) {
mRelativeEdges[HORIZONTAL] = horizontal;
mRelativeEdges[VERTICAL] = vertical;
@@ -390,6 +396,7 @@
* value.
* @return The scroll helper, which may used to chain setter calls.
*/
+ @NonNull
public AutoScrollHelper setMaximumEdges(float horizontalMax, float verticalMax) {
mMaximumEdges[HORIZONTAL] = horizontalMax;
mMaximumEdges[VERTICAL] = verticalMax;
@@ -407,6 +414,7 @@
* @param delayMillis The activation delay in milliseconds.
* @return The scroll helper, which may used to chain setter calls.
*/
+ @NonNull
public AutoScrollHelper setActivationDelay(int delayMillis) {
mActivationDelay = delayMillis;
return this;
@@ -422,6 +430,7 @@
* @param durationMillis The ramp-up duration in milliseconds.
* @return The scroll helper, which may used to chain setter calls.
*/
+ @NonNull
public AutoScrollHelper setRampUpDuration(int durationMillis) {
mScroller.setRampUpDuration(durationMillis);
return this;
@@ -437,6 +446,7 @@
* @param durationMillis The ramp-down duration in milliseconds.
* @return The scroll helper, which may used to chain setter calls.
*/
+ @NonNull
public AutoScrollHelper setRampDownDuration(int durationMillis) {
mScroller.setRampDownDuration(durationMillis);
return this;
diff --git a/core-ui/java/android/support/v4/widget/CircleImageView.java b/core-ui/src/main/java/android/support/v4/widget/CircleImageView.java
similarity index 100%
rename from core-ui/java/android/support/v4/widget/CircleImageView.java
rename to core-ui/src/main/java/android/support/v4/widget/CircleImageView.java
diff --git a/core-ui/java/android/support/v4/widget/CircularProgressDrawable.java b/core-ui/src/main/java/android/support/v4/widget/CircularProgressDrawable.java
similarity index 99%
rename from core-ui/java/android/support/v4/widget/CircularProgressDrawable.java
rename to core-ui/src/main/java/android/support/v4/widget/CircularProgressDrawable.java
index ac29541..2055669 100644
--- a/core-ui/java/android/support/v4/widget/CircularProgressDrawable.java
+++ b/core-ui/src/main/java/android/support/v4/widget/CircularProgressDrawable.java
@@ -132,7 +132,7 @@
/**
* @param context application context
*/
- public CircularProgressDrawable(Context context) {
+ public CircularProgressDrawable(@NonNull Context context) {
mResources = Preconditions.checkNotNull(context).getResources();
mRing = new Ring();
@@ -215,7 +215,7 @@
*
* @param strokeCap stroke cap
*/
- public void setStrokeCap(Paint.Cap strokeCap) {
+ public void setStrokeCap(@NonNull Paint.Cap strokeCap) {
mRing.setStrokeCap(strokeCap);
invalidateSelf();
}
@@ -225,6 +225,7 @@
*
* @return stroke cap
*/
+ @NonNull
public Paint.Cap getStrokeCap() {
return mRing.getStrokeCap();
}
@@ -373,6 +374,7 @@
*
* @return list of ARGB colors
*/
+ @NonNull
public int[] getColorSchemeColors() {
return mRing.getColors();
}
@@ -383,7 +385,7 @@
*
* @param colors list of ARGB colors to be used in the spinner
*/
- public void setColorSchemeColors(int... colors) {
+ public void setColorSchemeColors(@NonNull int... colors) {
mRing.setColors(colors);
mRing.setColorIndex(0);
invalidateSelf();
diff --git a/core-ui/java/android/support/v4/widget/ContentLoadingProgressBar.java b/core-ui/src/main/java/android/support/v4/widget/ContentLoadingProgressBar.java
similarity index 93%
rename from core-ui/java/android/support/v4/widget/ContentLoadingProgressBar.java
rename to core-ui/src/main/java/android/support/v4/widget/ContentLoadingProgressBar.java
index 98b63a4..356c7b9 100644
--- a/core-ui/java/android/support/v4/widget/ContentLoadingProgressBar.java
+++ b/core-ui/src/main/java/android/support/v4/widget/ContentLoadingProgressBar.java
@@ -17,6 +17,8 @@
package android.support.v4.widget;
import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ProgressBar;
@@ -61,11 +63,11 @@
}
};
- public ContentLoadingProgressBar(Context context) {
+ public ContentLoadingProgressBar(@NonNull Context context) {
this(context, null);
}
- public ContentLoadingProgressBar(Context context, AttributeSet attrs) {
+ public ContentLoadingProgressBar(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs, 0);
}
diff --git a/core-ui/java/android/support/v4/widget/CursorAdapter.java b/core-ui/src/main/java/android/support/v4/widget/CursorAdapter.java
similarity index 100%
rename from core-ui/java/android/support/v4/widget/CursorAdapter.java
rename to core-ui/src/main/java/android/support/v4/widget/CursorAdapter.java
diff --git a/core-ui/java/android/support/v4/widget/CursorFilter.java b/core-ui/src/main/java/android/support/v4/widget/CursorFilter.java
similarity index 100%
rename from core-ui/java/android/support/v4/widget/CursorFilter.java
rename to core-ui/src/main/java/android/support/v4/widget/CursorFilter.java
diff --git a/core-ui/java/android/support/v4/widget/DrawerLayout.java b/core-ui/src/main/java/android/support/v4/widget/DrawerLayout.java
similarity index 98%
rename from core-ui/java/android/support/v4/widget/DrawerLayout.java
rename to core-ui/src/main/java/android/support/v4/widget/DrawerLayout.java
index c7b40e9..a73e1f1 100644
--- a/core-ui/java/android/support/v4/widget/DrawerLayout.java
+++ b/core-ui/src/main/java/android/support/v4/widget/DrawerLayout.java
@@ -248,7 +248,7 @@
* @param drawerView The child view that was moved
* @param slideOffset The new offset of this drawer within its range, from 0-1
*/
- void onDrawerSlide(View drawerView, float slideOffset);
+ void onDrawerSlide(@NonNull View drawerView, float slideOffset);
/**
* Called when a drawer has settled in a completely open state.
@@ -256,14 +256,14 @@
*
* @param drawerView Drawer view that is now open
*/
- void onDrawerOpened(View drawerView);
+ void onDrawerOpened(@NonNull View drawerView);
/**
* Called when a drawer has settled in a completely closed state.
*
* @param drawerView Drawer view that is now closed
*/
- void onDrawerClosed(View drawerView);
+ void onDrawerClosed(@NonNull View drawerView);
/**
* Called when the drawer motion state changes. The new state will
@@ -296,15 +296,15 @@
}
}
- public DrawerLayout(Context context) {
+ public DrawerLayout(@NonNull Context context) {
this(context, null);
}
- public DrawerLayout(Context context, AttributeSet attrs) {
+ public DrawerLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
- public DrawerLayout(Context context, AttributeSet attrs, int defStyle) {
+ public DrawerLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
final float density = getResources().getDisplayMetrics().density;
@@ -626,7 +626,7 @@
* @see #LOCK_MODE_LOCKED_CLOSED
* @see #LOCK_MODE_LOCKED_OPEN
*/
- public void setDrawerLockMode(@LockMode int lockMode, View drawerView) {
+ public void setDrawerLockMode(@LockMode int lockMode, @NonNull View drawerView) {
if (!isDrawerView(drawerView)) {
throw new IllegalArgumentException("View " + drawerView + " is not a "
+ "drawer with appropriate layout_gravity");
@@ -700,7 +700,7 @@
* {@link #LOCK_MODE_LOCKED_OPEN}.
*/
@LockMode
- public int getDrawerLockMode(View drawerView) {
+ public int getDrawerLockMode(@NonNull View drawerView) {
if (!isDrawerView(drawerView)) {
throw new IllegalArgumentException("View " + drawerView + " is not a drawer");
}
@@ -718,7 +718,7 @@
* drawer to set the title for.
* @param title The title for the drawer.
*/
- public void setDrawerTitle(@EdgeGravity int edgeGravity, CharSequence title) {
+ public void setDrawerTitle(@EdgeGravity int edgeGravity, @Nullable CharSequence title) {
final int absGravity = GravityCompat.getAbsoluteGravity(
edgeGravity, ViewCompat.getLayoutDirection(this));
if (absGravity == Gravity.LEFT) {
@@ -1276,7 +1276,7 @@
*
* @param bg Background drawable to draw behind the status bar
*/
- public void setStatusBarBackground(Drawable bg) {
+ public void setStatusBarBackground(@Nullable Drawable bg) {
mStatusBarBackground = bg;
invalidate();
}
@@ -1286,6 +1286,7 @@
*
* @return The status bar background drawable, or null if none set
*/
+ @Nullable
public Drawable getStatusBarBackgroundDrawable() {
return mStatusBarBackground;
}
@@ -1577,7 +1578,7 @@
*
* @param drawerView Drawer view to open
*/
- public void openDrawer(View drawerView) {
+ public void openDrawer(@NonNull View drawerView) {
openDrawer(drawerView, true);
}
@@ -1587,7 +1588,7 @@
* @param drawerView Drawer view to open
* @param animate Whether opening of the drawer should be animated.
*/
- public void openDrawer(View drawerView, boolean animate) {
+ public void openDrawer(@NonNull View drawerView, boolean animate) {
if (!isDrawerView(drawerView)) {
throw new IllegalArgumentException("View " + drawerView + " is not a sliding drawer");
}
@@ -1646,7 +1647,7 @@
*
* @param drawerView Drawer view to close
*/
- public void closeDrawer(View drawerView) {
+ public void closeDrawer(@NonNull View drawerView) {
closeDrawer(drawerView, true);
}
@@ -1656,7 +1657,7 @@
* @param drawerView Drawer view to close
* @param animate Whether closing of the drawer should be animated.
*/
- public void closeDrawer(View drawerView, boolean animate) {
+ public void closeDrawer(@NonNull View drawerView, boolean animate) {
if (!isDrawerView(drawerView)) {
throw new IllegalArgumentException("View " + drawerView + " is not a sliding drawer");
}
@@ -1718,7 +1719,7 @@
* @return true if the given drawer view is in an open state
* @see #isDrawerVisible(android.view.View)
*/
- public boolean isDrawerOpen(View drawer) {
+ public boolean isDrawerOpen(@NonNull View drawer) {
if (!isDrawerView(drawer)) {
throw new IllegalArgumentException("View " + drawer + " is not a drawer");
}
@@ -1751,7 +1752,7 @@
* @return true if the given drawer is visible on-screen
* @see #isDrawerOpen(android.view.View)
*/
- public boolean isDrawerVisible(View drawer) {
+ public boolean isDrawerVisible(@NonNull View drawer) {
if (!isDrawerView(drawer)) {
throw new IllegalArgumentException("View " + drawer + " is not a drawer");
}
@@ -2001,7 +2002,7 @@
@LockMode int lockModeStart;
@LockMode int lockModeEnd;
- public SavedState(Parcel in, ClassLoader loader) {
+ public SavedState(@NonNull Parcel in, @Nullable ClassLoader loader) {
super(in, loader);
openDrawerGravity = in.readInt();
lockModeLeft = in.readInt();
@@ -2010,7 +2011,7 @@
lockModeEnd = in.readInt();
}
- public SavedState(Parcelable superState) {
+ public SavedState(@NonNull Parcelable superState) {
super(superState);
}
@@ -2218,7 +2219,7 @@
boolean isPeeking;
int openState;
- public LayoutParams(Context c, AttributeSet attrs) {
+ public LayoutParams(@NonNull Context c, @Nullable AttributeSet attrs) {
super(c, attrs);
final TypedArray a = c.obtainStyledAttributes(attrs, LAYOUT_ATTRS);
@@ -2235,16 +2236,16 @@
this.gravity = gravity;
}
- public LayoutParams(LayoutParams source) {
+ public LayoutParams(@NonNull LayoutParams source) {
super(source);
this.gravity = source.gravity;
}
- public LayoutParams(ViewGroup.LayoutParams source) {
+ public LayoutParams(@NonNull ViewGroup.LayoutParams source) {
super(source);
}
- public LayoutParams(ViewGroup.MarginLayoutParams source) {
+ public LayoutParams(@NonNull ViewGroup.MarginLayoutParams source) {
super(source);
}
}
diff --git a/core-ui/java/android/support/v4/widget/ExploreByTouchHelper.java b/core-ui/src/main/java/android/support/v4/widget/ExploreByTouchHelper.java
similarity index 98%
rename from core-ui/java/android/support/v4/widget/ExploreByTouchHelper.java
rename to core-ui/src/main/java/android/support/v4/widget/ExploreByTouchHelper.java
index 8a29eff..2b5ed0a 100644
--- a/core-ui/java/android/support/v4/widget/ExploreByTouchHelper.java
+++ b/core-ui/src/main/java/android/support/v4/widget/ExploreByTouchHelper.java
@@ -129,7 +129,7 @@
*
* @param host view whose virtual view hierarchy is exposed by this helper
*/
- public ExploreByTouchHelper(View host) {
+ public ExploreByTouchHelper(@NonNull View host) {
if (host == null) {
throw new IllegalArgumentException("View may not be null");
}
@@ -1107,7 +1107,8 @@
* populate the event
* @param event The event to populate
*/
- protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {
+ protected void onPopulateEventForVirtualView(int virtualViewId,
+ @NonNull AccessibilityEvent event) {
// Default implementation is no-op.
}
@@ -1119,7 +1120,7 @@
*
* @param event the event to populate with information about the host view
*/
- protected void onPopulateEventForHost(AccessibilityEvent event) {
+ protected void onPopulateEventForHost(@NonNull AccessibilityEvent event) {
// Default implementation is no-op.
}
@@ -1187,7 +1188,7 @@
* @param node The node to populate
*/
protected abstract void onPopulateNodeForVirtualView(
- int virtualViewId, AccessibilityNodeInfoCompat node);
+ int virtualViewId, @NonNull AccessibilityNodeInfoCompat node);
/**
* Populates an {@link AccessibilityNodeInfoCompat} with information
@@ -1197,7 +1198,7 @@
*
* @param node the node to populate with information about the host view
*/
- protected void onPopulateNodeForHost(AccessibilityNodeInfoCompat node) {
+ protected void onPopulateNodeForHost(@NonNull AccessibilityNodeInfoCompat node) {
// Default implementation is no-op.
}
@@ -1225,7 +1226,7 @@
* @return true if the action was performed
*/
protected abstract boolean onPerformActionForVirtualView(
- int virtualViewId, int action, Bundle arguments);
+ int virtualViewId, int action, @Nullable Bundle arguments);
/**
* Exposes a virtual view hierarchy to the accessibility framework.
diff --git a/core-ui/java/android/support/v4/widget/FocusStrategy.java b/core-ui/src/main/java/android/support/v4/widget/FocusStrategy.java
similarity index 100%
rename from core-ui/java/android/support/v4/widget/FocusStrategy.java
rename to core-ui/src/main/java/android/support/v4/widget/FocusStrategy.java
diff --git a/core-ui/java/android/support/v4/widget/ListViewAutoScrollHelper.java b/core-ui/src/main/java/android/support/v4/widget/ListViewAutoScrollHelper.java
similarity index 95%
rename from core-ui/java/android/support/v4/widget/ListViewAutoScrollHelper.java
rename to core-ui/src/main/java/android/support/v4/widget/ListViewAutoScrollHelper.java
index 73d18ce..c373f27 100644
--- a/core-ui/java/android/support/v4/widget/ListViewAutoScrollHelper.java
+++ b/core-ui/src/main/java/android/support/v4/widget/ListViewAutoScrollHelper.java
@@ -16,6 +16,7 @@
package android.support.v4.widget;
+import android.support.annotation.NonNull;
import android.view.View;
import android.widget.ListView;
@@ -26,7 +27,7 @@
public class ListViewAutoScrollHelper extends AutoScrollHelper {
private final ListView mTarget;
- public ListViewAutoScrollHelper(ListView target) {
+ public ListViewAutoScrollHelper(@NonNull ListView target) {
super(target);
mTarget = target;
diff --git a/core-ui/java/android/support/v4/widget/NestedScrollView.java b/core-ui/src/main/java/android/support/v4/widget/NestedScrollView.java
similarity index 99%
rename from core-ui/java/android/support/v4/widget/NestedScrollView.java
rename to core-ui/src/main/java/android/support/v4/widget/NestedScrollView.java
index 517686f..73ff084 100644
--- a/core-ui/java/android/support/v4/widget/NestedScrollView.java
+++ b/core-ui/src/main/java/android/support/v4/widget/NestedScrollView.java
@@ -26,6 +26,8 @@
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.annotation.RestrictTo;
import android.support.v4.view.AccessibilityDelegateCompat;
import android.support.v4.view.InputDeviceCompat;
@@ -181,15 +183,16 @@
private OnScrollChangeListener mOnScrollChangeListener;
- public NestedScrollView(Context context) {
+ public NestedScrollView(@NonNull Context context) {
this(context, null);
}
- public NestedScrollView(Context context, AttributeSet attrs) {
+ public NestedScrollView(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
- public NestedScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
+ public NestedScrollView(@NonNull Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr) {
super(context, attrs, defStyleAttr);
initScrollView();
@@ -441,7 +444,7 @@
* @see android.view.View#getScrollX()
* @see android.view.View#getScrollY()
*/
- public void setOnScrollChangeListener(OnScrollChangeListener l) {
+ public void setOnScrollChangeListener(@Nullable OnScrollChangeListener l) {
mOnScrollChangeListener = l;
}
@@ -552,7 +555,7 @@
* @param event The key event to execute.
* @return Return true if the event was handled, else false.
*/
- public boolean executeKeyEvent(KeyEvent event) {
+ public boolean executeKeyEvent(@NonNull KeyEvent event) {
mTempRect.setEmpty();
if (!canScroll()) {
diff --git a/core-ui/java/android/support/v4/widget/ResourceCursorAdapter.java b/core-ui/src/main/java/android/support/v4/widget/ResourceCursorAdapter.java
similarity index 100%
rename from core-ui/java/android/support/v4/widget/ResourceCursorAdapter.java
rename to core-ui/src/main/java/android/support/v4/widget/ResourceCursorAdapter.java
diff --git a/core-ui/java/android/support/v4/widget/SimpleCursorAdapter.java b/core-ui/src/main/java/android/support/v4/widget/SimpleCursorAdapter.java
similarity index 100%
rename from core-ui/java/android/support/v4/widget/SimpleCursorAdapter.java
rename to core-ui/src/main/java/android/support/v4/widget/SimpleCursorAdapter.java
diff --git a/core-ui/java/android/support/v4/widget/SlidingPaneLayout.java b/core-ui/src/main/java/android/support/v4/widget/SlidingPaneLayout.java
similarity index 98%
rename from core-ui/java/android/support/v4/widget/SlidingPaneLayout.java
rename to core-ui/src/main/java/android/support/v4/widget/SlidingPaneLayout.java
index 602df70..5676ccf 100644
--- a/core-ui/java/android/support/v4/widget/SlidingPaneLayout.java
+++ b/core-ui/src/main/java/android/support/v4/widget/SlidingPaneLayout.java
@@ -30,6 +30,8 @@
import android.os.Parcelable;
import android.support.annotation.ColorInt;
import android.support.annotation.DrawableRes;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.AbsSavedState;
@@ -213,20 +215,20 @@
* @param panel The child view that was moved
* @param slideOffset The new offset of this sliding pane within its range, from 0-1
*/
- void onPanelSlide(View panel, float slideOffset);
+ void onPanelSlide(@NonNull View panel, float slideOffset);
/**
* Called when a sliding pane becomes slid completely open. The pane may or may not
* be interactive at this point depending on how much of the pane is visible.
* @param panel The child view that was slid to an open position, revealing other panes
*/
- void onPanelOpened(View panel);
+ void onPanelOpened(@NonNull View panel);
/**
* Called when a sliding pane becomes slid completely closed. The pane is now guaranteed
* to be interactive. It may now obscure other views in the layout.
* @param panel The child view that was slid to a closed position
*/
- void onPanelClosed(View panel);
+ void onPanelClosed(@NonNull View panel);
}
/**
@@ -245,15 +247,15 @@
}
}
- public SlidingPaneLayout(Context context) {
+ public SlidingPaneLayout(@NonNull Context context) {
this(context, null);
}
- public SlidingPaneLayout(Context context, AttributeSet attrs) {
+ public SlidingPaneLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
- public SlidingPaneLayout(Context context, AttributeSet attrs, int defStyle) {
+ public SlidingPaneLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
final float density = context.getResources().getDisplayMetrics().density;
@@ -324,7 +326,7 @@
return mCoveredFadeColor;
}
- public void setPanelSlideListener(PanelSlideListener listener) {
+ public void setPanelSlideListener(@Nullable PanelSlideListener listener) {
mPanelSlideListener = listener;
}
@@ -1081,7 +1083,7 @@
*
* @param d drawable to use as a shadow
*/
- public void setShadowDrawableLeft(Drawable d) {
+ public void setShadowDrawableLeft(@Nullable Drawable d) {
mShadowDrawableLeft = d;
}
@@ -1091,7 +1093,7 @@
*
* @param d drawable to use as a shadow
*/
- public void setShadowDrawableRight(Drawable d) {
+ public void setShadowDrawableRight(@Nullable Drawable d) {
mShadowDrawableRight = d;
}
@@ -1410,20 +1412,20 @@
super(width, height);
}
- public LayoutParams(android.view.ViewGroup.LayoutParams source) {
+ public LayoutParams(@NonNull android.view.ViewGroup.LayoutParams source) {
super(source);
}
- public LayoutParams(MarginLayoutParams source) {
+ public LayoutParams(@NonNull MarginLayoutParams source) {
super(source);
}
- public LayoutParams(LayoutParams source) {
+ public LayoutParams(@NonNull LayoutParams source) {
super(source);
this.weight = source.weight;
}
- public LayoutParams(Context c, AttributeSet attrs) {
+ public LayoutParams(@NonNull Context c, @Nullable AttributeSet attrs) {
super(c, attrs);
final TypedArray a = c.obtainStyledAttributes(attrs, ATTRS);
diff --git a/core-ui/java/android/support/v4/widget/Space.java b/core-ui/src/main/java/android/support/v4/widget/Space.java
similarity index 88%
rename from core-ui/java/android/support/v4/widget/Space.java
rename to core-ui/src/main/java/android/support/v4/widget/Space.java
index 77a2d2e..7d37a72 100644
--- a/core-ui/java/android/support/v4/widget/Space.java
+++ b/core-ui/src/main/java/android/support/v4/widget/Space.java
@@ -19,6 +19,8 @@
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
@@ -28,18 +30,18 @@
*/
public class Space extends View {
- public Space(Context context, AttributeSet attrs, int defStyle) {
+ public Space(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (getVisibility() == VISIBLE) {
setVisibility(INVISIBLE);
}
}
- public Space(Context context, AttributeSet attrs) {
+ public Space(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
- public Space(Context context) {
+ public Space(@NonNull Context context) {
this(context, null);
}
diff --git a/core-ui/java/android/support/v4/widget/SwipeProgressBar.java b/core-ui/src/main/java/android/support/v4/widget/SwipeProgressBar.java
similarity index 100%
rename from core-ui/java/android/support/v4/widget/SwipeProgressBar.java
rename to core-ui/src/main/java/android/support/v4/widget/SwipeProgressBar.java
diff --git a/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java b/core-ui/src/main/java/android/support/v4/widget/SwipeRefreshLayout.java
similarity index 98%
rename from core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
rename to core-ui/src/main/java/android/support/v4/widget/SwipeRefreshLayout.java
index 2181bab..ca04e46 100644
--- a/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
+++ b/core-ui/src/main/java/android/support/v4/widget/SwipeRefreshLayout.java
@@ -20,6 +20,7 @@
import android.content.res.TypedArray;
import android.support.annotation.ColorInt;
import android.support.annotation.ColorRes;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.support.v4.content.ContextCompat;
@@ -316,7 +317,7 @@
*
* @param context
*/
- public SwipeRefreshLayout(Context context) {
+ public SwipeRefreshLayout(@NonNull Context context) {
this(context, null);
}
@@ -326,7 +327,7 @@
* @param context
* @param attrs
*/
- public SwipeRefreshLayout(Context context, AttributeSet attrs) {
+ public SwipeRefreshLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
@@ -387,7 +388,7 @@
* Set the listener to be notified when a refresh is triggered via the swipe
* gesture.
*/
- public void setOnRefreshListener(OnRefreshListener listener) {
+ public void setOnRefreshListener(@Nullable OnRefreshListener listener) {
mListener = listener;
}
@@ -1189,6 +1190,6 @@
*
* @return Whether it is possible for the child view of parent layout to scroll up.
*/
- boolean canChildScrollUp(SwipeRefreshLayout parent, @Nullable View child);
+ boolean canChildScrollUp(@NonNull SwipeRefreshLayout parent, @Nullable View child);
}
}
diff --git a/core-ui/java/android/support/v4/widget/ViewDragHelper.java b/core-ui/src/main/java/android/support/v4/widget/ViewDragHelper.java
similarity index 97%
rename from core-ui/java/android/support/v4/widget/ViewDragHelper.java
rename to core-ui/src/main/java/android/support/v4/widget/ViewDragHelper.java
index c222c17..09c6f66 100644
--- a/core-ui/java/android/support/v4/widget/ViewDragHelper.java
+++ b/core-ui/src/main/java/android/support/v4/widget/ViewDragHelper.java
@@ -18,6 +18,8 @@
package android.support.v4.widget;
import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.util.Log;
import android.view.MotionEvent;
@@ -167,7 +169,9 @@
* @param dx Change in X position from the last call
* @param dy Change in Y position from the last call
*/
- public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {}
+ public void onViewPositionChanged(@NonNull View changedView, int left, int top, int dx,
+ int dy) {
+ }
/**
* Called when a child view is captured for dragging or settling. The ID of the pointer
@@ -178,7 +182,7 @@
* @param capturedChild Child view that was captured
* @param activePointerId Pointer id tracking the child capture
*/
- public void onViewCaptured(View capturedChild, int activePointerId) {}
+ public void onViewCaptured(@NonNull View capturedChild, int activePointerId) {}
/**
* Called when the child view is no longer being actively dragged.
@@ -198,7 +202,7 @@
* @param xvel X velocity of the pointer as it left the screen in pixels per second.
* @param yvel Y velocity of the pointer as it left the screen in pixels per second.
*/
- public void onViewReleased(View releasedChild, float xvel, float yvel) {}
+ public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel) {}
/**
* Called when one of the subscribed edges in the parent view has been touched
@@ -256,7 +260,7 @@
* @param child Child view to check
* @return range of horizontal motion in pixels
*/
- public int getViewHorizontalDragRange(View child) {
+ public int getViewHorizontalDragRange(@NonNull View child) {
return 0;
}
@@ -267,7 +271,7 @@
* @param child Child view to check
* @return range of vertical motion in pixels
*/
- public int getViewVerticalDragRange(View child) {
+ public int getViewVerticalDragRange(@NonNull View child) {
return 0;
}
@@ -287,7 +291,7 @@
* @param pointerId ID of the pointer attempting the capture
* @return true if capture should be allowed, false otherwise
*/
- public abstract boolean tryCaptureView(View child, int pointerId);
+ public abstract boolean tryCaptureView(@NonNull View child, int pointerId);
/**
* Restrict the motion of the dragged child view along the horizontal axis.
@@ -300,7 +304,7 @@
* @param dx Proposed change in position for left
* @return The new clamped position for left
*/
- public int clampViewPositionHorizontal(View child, int left, int dx) {
+ public int clampViewPositionHorizontal(@NonNull View child, int left, int dx) {
return 0;
}
@@ -315,7 +319,7 @@
* @param dy Proposed change in position for top
* @return The new clamped position for top
*/
- public int clampViewPositionVertical(View child, int top, int dy) {
+ public int clampViewPositionVertical(@NonNull View child, int top, int dy) {
return 0;
}
}
@@ -345,7 +349,7 @@
* @param cb Callback to provide information and receive events
* @return a new ViewDragHelper instance
*/
- public static ViewDragHelper create(ViewGroup forParent, Callback cb) {
+ public static ViewDragHelper create(@NonNull ViewGroup forParent, @NonNull Callback cb) {
return new ViewDragHelper(forParent.getContext(), forParent, cb);
}
@@ -358,7 +362,8 @@
* @param cb Callback to provide information and receive events
* @return a new ViewDragHelper instance
*/
- public static ViewDragHelper create(ViewGroup forParent, float sensitivity, Callback cb) {
+ public static ViewDragHelper create(@NonNull ViewGroup forParent, float sensitivity,
+ @NonNull Callback cb) {
final ViewDragHelper helper = create(forParent, cb);
helper.mTouchSlop = (int) (helper.mTouchSlop * (1 / sensitivity));
return helper;
@@ -372,7 +377,8 @@
* @param context Context to initialize config-dependent params from
* @param forParent Parent view to monitor
*/
- private ViewDragHelper(Context context, ViewGroup forParent, Callback cb) {
+ private ViewDragHelper(@NonNull Context context, @NonNull ViewGroup forParent,
+ @NonNull Callback cb) {
if (forParent == null) {
throw new IllegalArgumentException("Parent view may not be null");
}
@@ -458,7 +464,7 @@
* @param childView Child view to capture
* @param activePointerId ID of the pointer that is dragging the captured child view
*/
- public void captureChildView(View childView, int activePointerId) {
+ public void captureChildView(@NonNull View childView, int activePointerId) {
if (childView.getParent() != mParentView) {
throw new IllegalArgumentException("captureChildView: parameter must be a descendant "
+ "of the ViewDragHelper's tracked parent view (" + mParentView + ")");
@@ -473,6 +479,7 @@
/**
* @return The currently captured view, or null if no view has been captured.
*/
+ @Nullable
public View getCapturedView() {
return mCapturedView;
}
@@ -537,7 +544,7 @@
* @param finalTop Final top position of child
* @return true if animation should continue through {@link #continueSettling(boolean)} calls
*/
- public boolean smoothSlideViewTo(View child, int finalLeft, int finalTop) {
+ public boolean smoothSlideViewTo(@NonNull View child, int finalLeft, int finalTop) {
mCapturedView = child;
mActivePointerId = INVALID_POINTER;
@@ -918,7 +925,7 @@
* @param y Y coordinate of the active touch point
* @return true if child views of v can be scrolled by delta of dx.
*/
- protected boolean canScroll(View v, boolean checkV, int dx, int dy, int x, int y) {
+ protected boolean canScroll(@NonNull View v, boolean checkV, int dx, int dy, int x, int y) {
if (v instanceof ViewGroup) {
final ViewGroup group = (ViewGroup) v;
final int scrollX = v.getScrollX();
@@ -948,7 +955,7 @@
* @param ev MotionEvent provided to onInterceptTouchEvent
* @return true if the parent view should return true from onInterceptTouchEvent
*/
- public boolean shouldInterceptTouchEvent(MotionEvent ev) {
+ public boolean shouldInterceptTouchEvent(@NonNull MotionEvent ev) {
final int action = ev.getActionMasked();
final int actionIndex = ev.getActionIndex();
@@ -1082,7 +1089,7 @@
*
* @param ev The touch event received by the parent view
*/
- public void processTouchEvent(MotionEvent ev) {
+ public void processTouchEvent(@NonNull MotionEvent ev) {
final int action = ev.getActionMasked();
final int actionIndex = ev.getActionIndex();
@@ -1453,7 +1460,7 @@
* @param y Y position to test in the parent's coordinate system
* @return true if the supplied view is under the given point, false otherwise
*/
- public boolean isViewUnder(View view, int x, int y) {
+ public boolean isViewUnder(@Nullable View view, int x, int y) {
if (view == null) {
return false;
}
@@ -1471,6 +1478,7 @@
* @param y Y position to test in the parent's coordinate system
* @return The topmost child view under (x, y) or null if none found.
*/
+ @Nullable
public View findTopChildUnder(int x, int y) {
final int childCount = mParentView.getChildCount();
for (int i = childCount - 1; i >= 0; i--) {
diff --git a/core-ui/java/android/support/v4/widget/package.html b/core-ui/src/main/java/android/support/v4/widget/package.html
similarity index 100%
rename from core-ui/java/android/support/v4/widget/package.html
rename to core-ui/src/main/java/android/support/v4/widget/package.html
diff --git a/customtabs/Android.mk b/customtabs/Android.mk
index cfd9971..f9195e8 100644
--- a/customtabs/Android.mk
+++ b/customtabs/Android.mk
@@ -26,10 +26,10 @@
LOCAL_USE_AAPT2 := true
LOCAL_MODULE := android-support-customtabs
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-LOCAL_AIDL_INCLUDES := $LOCAL_PATH/src
+LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/src/main/java
LOCAL_SRC_FILES := \
- $(call all-java-files-under,src) \
- $(call all-Iaidl-files-under,src)
+ $(call all-java-files-under,src/main/java) \
+ $(call all-Iaidl-files-under,src/main/java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-annotations \
diff --git a/customtabs/api/current.txt b/customtabs/api/current.txt
index 05c16c1..8494391 100644
--- a/customtabs/api/current.txt
+++ b/customtabs/api/current.txt
@@ -114,6 +114,7 @@
}
public final class CustomTabsSession {
+ method public static android.support.customtabs.CustomTabsSession createMockSessionForTesting(android.content.ComponentName);
method public boolean mayLaunchUrl(android.net.Uri, android.os.Bundle, java.util.List<android.os.Bundle>);
method public int postMessage(java.lang.String, android.os.Bundle);
method public boolean requestPostMessageChannel(android.net.Uri);
@@ -124,6 +125,7 @@
}
public class CustomTabsSessionToken {
+ method public static android.support.customtabs.CustomTabsSessionToken createMockSessionTokenForTesting();
method public android.support.customtabs.CustomTabsCallback getCallback();
method public static android.support.customtabs.CustomTabsSessionToken getSessionTokenFromIntent(android.content.Intent);
method public boolean isAssociatedWith(android.support.customtabs.CustomTabsSession);
@@ -146,5 +148,10 @@
method public void unbindFromContext(android.content.Context);
}
+ public class TrustedWebUtils {
+ method public static void launchAsTrustedWebActivity(android.content.Context, android.support.customtabs.CustomTabsIntent, android.net.Uri);
+ field public static final java.lang.String EXTRA_LAUNCH_AS_TRUSTED_WEB_ACTIVITY = "android.support.customtabs.extra.LAUNCH_AS_TRUSTED_WEB_ACTIVITY";
+ }
+
}
diff --git a/customtabs/build.gradle b/customtabs/build.gradle
index 6cf8b77..fc90301 100644
--- a/customtabs/build.gradle
+++ b/customtabs/build.gradle
@@ -15,11 +15,7 @@
}
sourceSets {
- main.java.srcDirs = ['src']
- main.aidl.srcDirs = ['src']
- main.res.srcDir 'res'
- main.assets.srcDir 'assets'
- main.resources.srcDir 'java'
+ main.aidl.srcDirs = ['src/main/java']
}
}
diff --git a/customtabs/src/android/support/customtabs/CustomTabsCallback.java b/customtabs/src/main/java/android/support/customtabs/CustomTabsCallback.java
similarity index 100%
rename from customtabs/src/android/support/customtabs/CustomTabsCallback.java
rename to customtabs/src/main/java/android/support/customtabs/CustomTabsCallback.java
diff --git a/customtabs/src/android/support/customtabs/CustomTabsClient.java b/customtabs/src/main/java/android/support/customtabs/CustomTabsClient.java
similarity index 100%
rename from customtabs/src/android/support/customtabs/CustomTabsClient.java
rename to customtabs/src/main/java/android/support/customtabs/CustomTabsClient.java
diff --git a/customtabs/src/android/support/customtabs/CustomTabsIntent.java b/customtabs/src/main/java/android/support/customtabs/CustomTabsIntent.java
similarity index 100%
rename from customtabs/src/android/support/customtabs/CustomTabsIntent.java
rename to customtabs/src/main/java/android/support/customtabs/CustomTabsIntent.java
diff --git a/customtabs/src/android/support/customtabs/CustomTabsService.java b/customtabs/src/main/java/android/support/customtabs/CustomTabsService.java
similarity index 100%
rename from customtabs/src/android/support/customtabs/CustomTabsService.java
rename to customtabs/src/main/java/android/support/customtabs/CustomTabsService.java
diff --git a/customtabs/src/android/support/customtabs/CustomTabsServiceConnection.java b/customtabs/src/main/java/android/support/customtabs/CustomTabsServiceConnection.java
similarity index 100%
rename from customtabs/src/android/support/customtabs/CustomTabsServiceConnection.java
rename to customtabs/src/main/java/android/support/customtabs/CustomTabsServiceConnection.java
diff --git a/customtabs/src/android/support/customtabs/CustomTabsSession.java b/customtabs/src/main/java/android/support/customtabs/CustomTabsSession.java
similarity index 94%
rename from customtabs/src/android/support/customtabs/CustomTabsSession.java
rename to customtabs/src/main/java/android/support/customtabs/CustomTabsSession.java
index d4930ae..a84d63c 100644
--- a/customtabs/src/android/support/customtabs/CustomTabsSession.java
+++ b/customtabs/src/main/java/android/support/customtabs/CustomTabsSession.java
@@ -25,6 +25,7 @@
import android.os.RemoteException;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
import android.support.customtabs.CustomTabsService.Relation;
import android.support.customtabs.CustomTabsService.Result;
import android.view.View;
@@ -43,6 +44,21 @@
private final ICustomTabsCallback mCallback;
private final ComponentName mComponentName;
+ /**
+ * Provides browsers a way to generate a mock {@link CustomTabsSession} for testing
+ * purposes.
+ *
+ * @param componentName The component the session should be created for.
+ * @return A mock session with no functionality.
+ */
+ @VisibleForTesting
+ @NonNull
+ public static CustomTabsSession createMockSessionForTesting(
+ @NonNull ComponentName componentName) {
+ return new CustomTabsSession(
+ null, new CustomTabsSessionToken.MockCallback(), componentName);
+ }
+
/* package */ CustomTabsSession(
ICustomTabsService service, ICustomTabsCallback callback, ComponentName componentName) {
mService = service;
diff --git a/customtabs/src/android/support/customtabs/CustomTabsSessionToken.java b/customtabs/src/main/java/android/support/customtabs/CustomTabsSessionToken.java
similarity index 82%
rename from customtabs/src/android/support/customtabs/CustomTabsSessionToken.java
rename to customtabs/src/main/java/android/support/customtabs/CustomTabsSessionToken.java
index ee47278..5a9e1b6 100644
--- a/customtabs/src/android/support/customtabs/CustomTabsSessionToken.java
+++ b/customtabs/src/main/java/android/support/customtabs/CustomTabsSessionToken.java
@@ -21,6 +21,7 @@
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
+import android.support.annotation.NonNull;
import android.support.customtabs.CustomTabsService.Relation;
import android.support.v4.app.BundleCompat;
import android.util.Log;
@@ -34,6 +35,29 @@
private final ICustomTabsCallback mCallbackBinder;
private final CustomTabsCallback mCallback;
+ /* package */ static class MockCallback extends ICustomTabsCallback.Stub {
+ @Override
+ public void onNavigationEvent(int navigationEvent, Bundle extras) {}
+
+ @Override
+ public void extraCallback(String callbackName, Bundle args) {}
+
+ @Override
+ public void onMessageChannelReady(Bundle extras) {}
+
+ @Override
+ public void onPostMessage(String message, Bundle extras) {}
+
+ @Override
+ public void onRelationshipValidationResult(@Relation int relation, Uri requestedOrigin,
+ boolean result, Bundle extras) {}
+
+ @Override
+ public IBinder asBinder() {
+ return this;
+ }
+ }
+
/**
* Obtain a {@link CustomTabsSessionToken} from an intent. See {@link CustomTabsIntent.Builder}
* for ways to generate an intent for custom tabs.
@@ -48,6 +72,17 @@
return new CustomTabsSessionToken(ICustomTabsCallback.Stub.asInterface(binder));
}
+ /**
+ * Provides browsers a way to generate a mock {@link CustomTabsSessionToken} for testing
+ * purposes.
+ *
+ * @return A mock token with no functionality.
+ */
+ @NonNull
+ public static CustomTabsSessionToken createMockSessionTokenForTesting() {
+ return new CustomTabsSessionToken(new MockCallback());
+ }
+
CustomTabsSessionToken(ICustomTabsCallback callbackBinder) {
mCallbackBinder = callbackBinder;
mCallback = new CustomTabsCallback() {
diff --git a/customtabs/src/android/support/customtabs/ICustomTabsCallback.aidl b/customtabs/src/main/java/android/support/customtabs/ICustomTabsCallback.aidl
similarity index 100%
rename from customtabs/src/android/support/customtabs/ICustomTabsCallback.aidl
rename to customtabs/src/main/java/android/support/customtabs/ICustomTabsCallback.aidl
diff --git a/customtabs/src/android/support/customtabs/ICustomTabsService.aidl b/customtabs/src/main/java/android/support/customtabs/ICustomTabsService.aidl
similarity index 100%
rename from customtabs/src/android/support/customtabs/ICustomTabsService.aidl
rename to customtabs/src/main/java/android/support/customtabs/ICustomTabsService.aidl
diff --git a/customtabs/src/android/support/customtabs/IPostMessageService.aidl b/customtabs/src/main/java/android/support/customtabs/IPostMessageService.aidl
similarity index 100%
rename from customtabs/src/android/support/customtabs/IPostMessageService.aidl
rename to customtabs/src/main/java/android/support/customtabs/IPostMessageService.aidl
diff --git a/customtabs/src/android/support/customtabs/PostMessageService.java b/customtabs/src/main/java/android/support/customtabs/PostMessageService.java
similarity index 100%
rename from customtabs/src/android/support/customtabs/PostMessageService.java
rename to customtabs/src/main/java/android/support/customtabs/PostMessageService.java
diff --git a/customtabs/src/android/support/customtabs/PostMessageServiceConnection.java b/customtabs/src/main/java/android/support/customtabs/PostMessageServiceConnection.java
similarity index 100%
rename from customtabs/src/android/support/customtabs/PostMessageServiceConnection.java
rename to customtabs/src/main/java/android/support/customtabs/PostMessageServiceConnection.java
diff --git a/customtabs/src/main/java/android/support/customtabs/TrustedWebUtils.java b/customtabs/src/main/java/android/support/customtabs/TrustedWebUtils.java
new file mode 100644
index 0000000..e9a2233
--- /dev/null
+++ b/customtabs/src/main/java/android/support/customtabs/TrustedWebUtils.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 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.customtabs;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.app.BundleCompat;
+
+/**
+ * Class for utilities and convenience calls for opening a qualifying web page as a
+ * Trusted Web Activity.
+ *
+ * Trusted Web Activity is a fullscreen UI with no visible browser controls that hosts web pages
+ * meeting certain criteria. The full list of qualifications is at the implementing browser's
+ * discretion, but minimum recommended set is for the web page :
+ * <ul>
+ * <li>To have declared delegate_permission/common.handle_all_urls relationship with the
+ * launching client application ensuring 1:1 trust between the Android native and web
+ * components. See https://developers.google.com/digital-asset-links/ for details.</li>
+ * <li>To work as a reliable, fast and engaging standalone component within the launching app's
+ * flow.</li>
+ * <li>To be accessible and operable even when offline.</li>
+ * </ul>
+ *
+ * Fallback behaviors may also differ with implementation. Possibilities are launching the page in
+ * a custom tab, or showing it in browser UI. Browsers are encouraged to use
+ * {@link CustomTabsCallback#onRelationshipValidationResult(int, Uri, boolean, Bundle)}
+ * for sending details of the verification results.
+ */
+public class TrustedWebUtils {
+
+ /**
+ * Boolean extra that triggers a {@link CustomTabsIntent} launch to be in a fullscreen UI with
+ * no browser controls.
+ *
+ * @see TrustedWebUtils#launchAsTrustedWebActivity(Context, CustomTabsIntent, Uri).
+ */
+ public static final String EXTRA_LAUNCH_AS_TRUSTED_WEB_ACTIVITY =
+ "android.support.customtabs.extra.LAUNCH_AS_TRUSTED_WEB_ACTIVITY";
+
+ private TrustedWebUtils() {}
+
+ /**
+ * Launch the given {@link CustomTabsIntent} as a Trusted Web Activity. The given
+ * {@link CustomTabsIntent} should have a valid {@link CustomTabsSession} associated with it
+ * during construction. Once the Trusted Web Activity is launched, browser side implementations
+ * may have their own fallback behavior (e.g. Showing the page in a custom tab UI with toolbar)
+ * based on qualifications listed above or more.
+ *
+ * @param context {@link Context} to use while launching the {@link CustomTabsIntent}.
+ * @param customTabsIntent The {@link CustomTabsIntent} to use for launching the
+ * Trusted Web Activity. Note that all customizations in the given
+ * associated with browser toolbar controls will be ignored.
+ * @param uri The web page to launch as Trusted Web Activity.
+ */
+ public static void launchAsTrustedWebActivity(@NonNull Context context,
+ @NonNull CustomTabsIntent customTabsIntent, @NonNull Uri uri) {
+ if (BundleCompat.getBinder(
+ customTabsIntent.intent.getExtras(), CustomTabsIntent.EXTRA_SESSION) == null) {
+ throw new IllegalArgumentException(
+ "Given CustomTabsIntent should be associated with a valid CustomTabsSession");
+ }
+ customTabsIntent.intent.putExtra(EXTRA_LAUNCH_AS_TRUSTED_WEB_ACTIVITY, true);
+ customTabsIntent.launchUrl(context, uri);
+ }
+}
diff --git a/customtabs/tests/src/android/support/customtabs/TrustedWebUtilsTest.java b/customtabs/tests/src/android/support/customtabs/TrustedWebUtilsTest.java
new file mode 100644
index 0000000..a9a5abc
--- /dev/null
+++ b/customtabs/tests/src/android/support/customtabs/TrustedWebUtilsTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2017 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.customtabs;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.net.Uri;
+import android.support.test.filters.SmallTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v4.app.BundleCompat;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for TrustedWebUtils.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class TrustedWebUtilsTest {
+ @Rule
+ public final ActivityTestRule<TestActivity> mActivityTestRule;
+
+ public TrustedWebUtilsTest() {
+ mActivityTestRule = new ActivityTestRule<TestActivity>(TestActivity.class);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testTrustedWebIntentRequiresValidSession() {
+ CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder().build();
+ TrustedWebUtils.launchAsTrustedWebActivity(
+ mActivityTestRule.getActivity(), customTabsIntent, Uri.EMPTY);
+ }
+
+ @Test(expected = ActivityNotFoundException.class)
+ public void testTrustedWebIntentContainsRequiredExtra() {
+ CustomTabsSession mockSession = CustomTabsSession.createMockSessionForTesting(
+ mActivityTestRule.getActivity().getComponentName());
+ CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder(mockSession).build();
+ TrustedWebUtils.launchAsTrustedWebActivity(
+ mActivityTestRule.getActivity(), customTabsIntent, Uri.EMPTY);
+ assertNotNull(BundleCompat.getBinder(
+ customTabsIntent.intent.getExtras(), CustomTabsIntent.EXTRA_SESSION));
+ assertEquals(customTabsIntent.intent.getAction(), Intent.ACTION_VIEW);
+ assertTrue(customTabsIntent.intent.hasExtra(
+ TrustedWebUtils.EXTRA_LAUNCH_AS_TRUSTED_WEB_ACTIVITY));
+ }
+}
diff --git a/dynamic-animation/Android.mk b/dynamic-animation/Android.mk
index 1b33094..11aa484 100644
--- a/dynamic-animation/Android.mk
+++ b/dynamic-animation/Android.mk
@@ -18,7 +18,7 @@
LOCAL_USE_AAPT2 := true
LOCAL_MODULE := android-support-dynamic-animation
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
+LOCAL_SRC_FILES := $(call all-java-files-under,src/main/java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
diff --git a/dynamic-animation/build.gradle b/dynamic-animation/build.gradle
index b1557e8..220758d 100644
--- a/dynamic-animation/build.gradle
+++ b/dynamic-animation/build.gradle
@@ -13,11 +13,6 @@
defaultConfig {
minSdkVersion 14
}
-
- sourceSets {
- main.java.srcDir 'src'
- main.res.srcDirs 'res', 'res-public'
- }
}
supportLibrary {
diff --git a/dynamic-animation/src/android/support/animation/AnimationHandler.java b/dynamic-animation/src/main/java/android/support/animation/AnimationHandler.java
similarity index 100%
rename from dynamic-animation/src/android/support/animation/AnimationHandler.java
rename to dynamic-animation/src/main/java/android/support/animation/AnimationHandler.java
diff --git a/dynamic-animation/src/android/support/animation/DynamicAnimation.java b/dynamic-animation/src/main/java/android/support/animation/DynamicAnimation.java
similarity index 100%
rename from dynamic-animation/src/android/support/animation/DynamicAnimation.java
rename to dynamic-animation/src/main/java/android/support/animation/DynamicAnimation.java
diff --git a/dynamic-animation/src/android/support/animation/FlingAnimation.java b/dynamic-animation/src/main/java/android/support/animation/FlingAnimation.java
similarity index 100%
rename from dynamic-animation/src/android/support/animation/FlingAnimation.java
rename to dynamic-animation/src/main/java/android/support/animation/FlingAnimation.java
diff --git a/dynamic-animation/src/android/support/animation/FloatPropertyCompat.java b/dynamic-animation/src/main/java/android/support/animation/FloatPropertyCompat.java
similarity index 100%
rename from dynamic-animation/src/android/support/animation/FloatPropertyCompat.java
rename to dynamic-animation/src/main/java/android/support/animation/FloatPropertyCompat.java
diff --git a/dynamic-animation/src/android/support/animation/FloatValueHolder.java b/dynamic-animation/src/main/java/android/support/animation/FloatValueHolder.java
similarity index 100%
rename from dynamic-animation/src/android/support/animation/FloatValueHolder.java
rename to dynamic-animation/src/main/java/android/support/animation/FloatValueHolder.java
diff --git a/dynamic-animation/src/android/support/animation/Force.java b/dynamic-animation/src/main/java/android/support/animation/Force.java
similarity index 100%
rename from dynamic-animation/src/android/support/animation/Force.java
rename to dynamic-animation/src/main/java/android/support/animation/Force.java
diff --git a/dynamic-animation/src/android/support/animation/SpringAnimation.java b/dynamic-animation/src/main/java/android/support/animation/SpringAnimation.java
similarity index 100%
rename from dynamic-animation/src/android/support/animation/SpringAnimation.java
rename to dynamic-animation/src/main/java/android/support/animation/SpringAnimation.java
diff --git a/dynamic-animation/src/android/support/animation/SpringForce.java b/dynamic-animation/src/main/java/android/support/animation/SpringForce.java
similarity index 100%
rename from dynamic-animation/src/android/support/animation/SpringForce.java
rename to dynamic-animation/src/main/java/android/support/animation/SpringForce.java
diff --git a/exifinterface/src/android/support/media/ExifInterface.java b/exifinterface/src/android/support/media/ExifInterface.java
index b790cd2..72b61cb 100644
--- a/exifinterface/src/android/support/media/ExifInterface.java
+++ b/exifinterface/src/android/support/media/ExifInterface.java
@@ -22,6 +22,7 @@
import android.location.Location;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.util.Log;
import android.util.Pair;
@@ -3699,7 +3700,7 @@
/**
* Reads Exif tags from the specified image file.
*/
- public ExifInterface(String filename) throws IOException {
+ public ExifInterface(@NonNull String filename) throws IOException {
if (filename == null) {
throw new IllegalArgumentException("filename cannot be null");
}
@@ -3720,7 +3721,7 @@
* should close the input stream after use. This constructor is not intended to be used with
* an input stream that performs any networking operations.
*/
- public ExifInterface(InputStream inputStream) throws IOException {
+ public ExifInterface(@NonNull InputStream inputStream) throws IOException {
if (inputStream == null) {
throw new IllegalArgumentException("inputStream cannot be null");
}
@@ -3739,7 +3740,8 @@
*
* @param tag the name of the tag.
*/
- private ExifAttribute getExifAttribute(String tag) {
+ @Nullable
+ private ExifAttribute getExifAttribute(@NonNull String tag) {
if (TAG_ISO_SPEED_RATINGS.equals(tag)) {
if (DEBUG) {
Log.d(TAG, "getExifAttribute: Replacing TAG_ISO_SPEED_RATINGS with "
@@ -3764,7 +3766,8 @@
*
* @param tag the name of the tag.
*/
- public String getAttribute(String tag) {
+ @Nullable
+ public String getAttribute(@NonNull String tag) {
ExifAttribute attribute = getExifAttribute(tag);
if (attribute != null) {
if (!sTagSetForCompatibility.contains(tag)) {
@@ -3804,7 +3807,7 @@
* @param tag the name of the tag.
* @param defaultValue the value to return if the tag is not available.
*/
- public int getAttributeInt(String tag, int defaultValue) {
+ public int getAttributeInt(@NonNull String tag, int defaultValue) {
ExifAttribute exifAttribute = getExifAttribute(tag);
if (exifAttribute == null) {
return defaultValue;
@@ -3825,7 +3828,7 @@
* @param tag the name of the tag.
* @param defaultValue the value to return if the tag is not available.
*/
- public double getAttributeDouble(String tag, double defaultValue) {
+ public double getAttributeDouble(@NonNull String tag, double defaultValue) {
ExifAttribute exifAttribute = getExifAttribute(tag);
if (exifAttribute == null) {
return defaultValue;
@@ -3844,7 +3847,7 @@
* @param tag the name of the tag.
* @param value the value of the tag.
*/
- public void setAttribute(String tag, String value) {
+ public void setAttribute(@NonNull String tag, @Nullable String value) {
if (TAG_ISO_SPEED_RATINGS.equals(tag)) {
if (DEBUG) {
Log.d(TAG, "setAttribute: Replacing TAG_ISO_SPEED_RATINGS with "
@@ -4320,6 +4323,7 @@
* The returned data can be decoded using
* {@link android.graphics.BitmapFactory#decodeByteArray(byte[],int,int)}
*/
+ @Nullable
public byte[] getThumbnail() {
if (mThumbnailCompression == DATA_JPEG || mThumbnailCompression == DATA_JPEG_COMPRESSED) {
return getThumbnailBytes();
@@ -4331,6 +4335,7 @@
* Returns the thumbnail bytes inside the image file, regardless of the compression type of the
* thumbnail image.
*/
+ @Nullable
public byte[] getThumbnailBytes() {
if (!mHasThumbnail) {
return null;
@@ -4379,6 +4384,7 @@
* Creates and returns a Bitmap object of the thumbnail image based on the byte array and the
* thumbnail compression value, or {@code null} if the compression type is unsupported.
*/
+ @Nullable
public Bitmap getThumbnailBitmap() {
if (!mHasThumbnail) {
return null;
@@ -4425,6 +4431,7 @@
* @return two-element array, the offset in the first value, and length in
* the second, or {@code null} if no thumbnail was found.
*/
+ @Nullable
public long[] getThumbnailRange() {
if (!mHasThumbnail) {
return null;
@@ -4462,6 +4469,7 @@
* array where the first element is the latitude and the second element is the longitude.
* Otherwise, it returns null.
*/
+ @Nullable
public double[] getLatLong() {
String latValue = getAttribute(TAG_GPS_LATITUDE);
String latRef = getAttribute(TAG_GPS_LATITUDE_REF);
diff --git a/fragment/Android.mk b/fragment/Android.mk
index cc1b5f8..efac954 100644
--- a/fragment/Android.mk
+++ b/fragment/Android.mk
@@ -30,7 +30,7 @@
LOCAL_MODULE := android-support-fragment
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
LOCAL_SRC_FILES := \
- $(call all-java-files-under, java)
+ $(call all-java-files-under, src/main/java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
diff --git a/fragment/build.gradle b/fragment/build.gradle
index 954cdd8..3a86f38 100644
--- a/fragment/build.gradle
+++ b/fragment/build.gradle
@@ -16,10 +16,6 @@
defaultConfig {
minSdkVersion 14
}
-
- sourceSets {
- main.java.srcDirs = ['java']
- }
}
supportLibrary {
diff --git a/fragment/java/android/support/v4/app/BackStackRecord.java b/fragment/src/main/java/android/support/v4/app/BackStackRecord.java
similarity index 100%
rename from fragment/java/android/support/v4/app/BackStackRecord.java
rename to fragment/src/main/java/android/support/v4/app/BackStackRecord.java
diff --git a/fragment/java/android/support/v4/app/BaseFragmentActivityApi14.java b/fragment/src/main/java/android/support/v4/app/BaseFragmentActivityApi14.java
similarity index 100%
rename from fragment/java/android/support/v4/app/BaseFragmentActivityApi14.java
rename to fragment/src/main/java/android/support/v4/app/BaseFragmentActivityApi14.java
diff --git a/fragment/java/android/support/v4/app/BaseFragmentActivityApi16.java b/fragment/src/main/java/android/support/v4/app/BaseFragmentActivityApi16.java
similarity index 100%
rename from fragment/java/android/support/v4/app/BaseFragmentActivityApi16.java
rename to fragment/src/main/java/android/support/v4/app/BaseFragmentActivityApi16.java
diff --git a/fragment/java/android/support/v4/app/DialogFragment.java b/fragment/src/main/java/android/support/v4/app/DialogFragment.java
similarity index 100%
rename from fragment/java/android/support/v4/app/DialogFragment.java
rename to fragment/src/main/java/android/support/v4/app/DialogFragment.java
diff --git a/fragment/java/android/support/v4/app/Fragment.java b/fragment/src/main/java/android/support/v4/app/Fragment.java
similarity index 98%
rename from fragment/java/android/support/v4/app/Fragment.java
rename to fragment/src/main/java/android/support/v4/app/Fragment.java
index 0eb7083..2415e79 100644
--- a/fragment/java/android/support/v4/app/Fragment.java
+++ b/fragment/src/main/java/android/support/v4/app/Fragment.java
@@ -463,6 +463,7 @@
/**
* Get the tag name of the fragment, if specified.
*/
+ @Nullable
final public String getTag() {
return mTag;
}
@@ -474,7 +475,7 @@
* <p>This method cannot be called if the fragment is added to a FragmentManager and
* if {@link #isStateSaved()} would return true.</p>
*/
- public void setArguments(Bundle args) {
+ public void setArguments(@Nullable Bundle args) {
if (mIndex >= 0 && isStateSaved()) {
throw new IllegalStateException("Fragment already active and state has been saved");
}
@@ -485,6 +486,7 @@
* Return the arguments supplied when the fragment was instantiated,
* if any.
*/
+ @Nullable
final public Bundle getArguments() {
return mArguments;
}
@@ -512,7 +514,7 @@
*
* @param state The state the fragment should be restored from.
*/
- public void setInitialSavedState(SavedState state) {
+ public void setInitialSavedState(@Nullable SavedState state) {
if (mIndex >= 0) {
throw new IllegalStateException("Fragment already active");
}
@@ -532,7 +534,7 @@
* are going to call back with {@link #onActivityResult(int, int, Intent)}.
*/
@SuppressWarnings("ReferenceEquality")
- public void setTargetFragment(Fragment fragment, int requestCode) {
+ public void setTargetFragment(@Nullable Fragment fragment, int requestCode) {
// Don't allow a caller to set a target fragment in another FragmentManager,
// but there's a snag: people do set target fragments before fragments get added.
// We'll have the FragmentManager check that for validity when we move
@@ -558,6 +560,7 @@
/**
* Return the target fragment set by {@link #setTargetFragment}.
*/
+ @Nullable
final public Fragment getTargetFragment() {
return mTarget;
}
@@ -572,6 +575,7 @@
/**
* Return the {@link Context} this fragment is currently associated with.
*/
+ @Nullable
public Context getContext() {
return mHost == null ? null : mHost.getContext();
}
@@ -581,6 +585,7 @@
* May return {@code null} if the fragment is associated with a {@link Context}
* instead.
*/
+ @Nullable
final public FragmentActivity getActivity() {
return mHost == null ? null : (FragmentActivity) mHost.getActivity();
}
@@ -589,6 +594,7 @@
* Return the host object of this fragment. May return {@code null} if the fragment
* isn't currently being hosted.
*/
+ @Nullable
final public Object getHost() {
return mHost == null ? null : mHost.onGetHost();
}
@@ -596,6 +602,7 @@
/**
* Return <code>getActivity().getResources()</code>.
*/
+ @NonNull
final public Resources getResources() {
if (mHost == null) {
throw new IllegalStateException("Fragment " + this + " not attached to Activity");
@@ -609,6 +616,7 @@
*
* @param resId Resource id for the CharSequence text
*/
+ @NonNull
public final CharSequence getText(@StringRes int resId) {
return getResources().getText(resId);
}
@@ -619,6 +627,7 @@
*
* @param resId Resource id for the string
*/
+ @NonNull
public final String getString(@StringRes int resId) {
return getResources().getString(resId);
}
@@ -631,7 +640,7 @@
* @param resId Resource id for the format string
* @param formatArgs The format arguments that will be used for substitution.
*/
-
+ @NonNull
public final String getString(@StringRes int resId, Object... formatArgs) {
return getResources().getString(resId, formatArgs);
}
@@ -646,6 +655,7 @@
* <p>If this Fragment is a child of another Fragment, the FragmentManager
* returned here will be the parent's {@link #getChildFragmentManager()}.
*/
+ @Nullable
final public FragmentManager getFragmentManager() {
return mFragmentManager;
}
@@ -654,6 +664,7 @@
* Return a private FragmentManager for placing and managing Fragments
* inside of this Fragment.
*/
+ @NonNull
final public FragmentManager getChildFragmentManager() {
if (mChildFragmentManager == null) {
instantiateChildFragmentManager();
@@ -674,6 +685,7 @@
* Return this fragment's child FragmentManager one has been previously created,
* otherwise null.
*/
+ @Nullable
FragmentManager peekChildFragmentManager() {
return mChildFragmentManager;
}
@@ -682,6 +694,7 @@
* Returns the parent Fragment containing this Fragment. If this Fragment
* is attached directly to an Activity, returns null.
*/
+ @Nullable
final public Fragment getParentFragment() {
return mParentFragment;
}
@@ -1082,7 +1095,8 @@
* a previous saved state, this is the state.
* @return The LayoutInflater used to inflate Views of this Fragment.
*/
- public LayoutInflater onGetLayoutInflater(Bundle savedInstanceState) {
+ @NonNull
+ public LayoutInflater onGetLayoutInflater(@Nullable Bundle savedInstanceState) {
// TODO: move the implementation in getLayoutInflater to here
return getLayoutInflater(savedInstanceState);
}
@@ -1113,7 +1127,8 @@
* a previous saved state, this is the state.
* @return The LayoutInflater used to inflate Views of this Fragment.
*/
- LayoutInflater performGetLayoutInflater(Bundle savedInstanceState) {
+ @NonNull
+ LayoutInflater performGetLayoutInflater(@Nullable Bundle savedInstanceState) {
LayoutInflater layoutInflater = onGetLayoutInflater(savedInstanceState);
mLayoutInflater = layoutInflater;
return mLayoutInflater;
@@ -1129,8 +1144,9 @@
* {@link #getLayoutInflater()} instead of this method.
*/
@Deprecated
+ @NonNull
@RestrictTo(LIBRARY_GROUP)
- public LayoutInflater getLayoutInflater(Bundle savedFragmentState) {
+ public LayoutInflater getLayoutInflater(@Nullable Bundle savedFragmentState) {
if (mHost == null) {
throw new IllegalStateException("onGetLayoutInflater() cannot be executed until the "
+ "Fragment is attached to the FragmentManager.");
@@ -1356,7 +1372,7 @@
* @return Return the View for the fragment's UI, or null.
*/
@Nullable
- public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return null;
}
@@ -1768,7 +1784,7 @@
*
* @param transition The Transition to use to move Views into the initial Scene.
*/
- public void setEnterTransition(Object transition) {
+ public void setEnterTransition(@Nullable Object transition) {
ensureAnimationInfo().mEnterTransition = transition;
}
@@ -1781,6 +1797,7 @@
*
* @return the Transition to use to move Views into the initial Scene.
*/
+ @Nullable
public Object getEnterTransition() {
if (mAnimationInfo == null) {
return null;
@@ -1802,7 +1819,7 @@
* is preparing to close. <code>transition</code> must be an
* android.transition.Transition.
*/
- public void setReturnTransition(Object transition) {
+ public void setReturnTransition(@Nullable Object transition) {
ensureAnimationInfo().mReturnTransition = transition;
}
@@ -1818,6 +1835,7 @@
* @return the Transition to use to move Views out of the Scene when the Fragment
* is preparing to close.
*/
+ @Nullable
public Object getReturnTransition() {
if (mAnimationInfo == null) {
return null;
@@ -1839,7 +1857,7 @@
* is being closed not due to popping the back stack. <code>transition</code>
* must be an android.transition.Transition.
*/
- public void setExitTransition(Object transition) {
+ public void setExitTransition(@Nullable Object transition) {
ensureAnimationInfo().mExitTransition = transition;
}
@@ -1855,6 +1873,7 @@
* @return the Transition to use to move Views out of the Scene when the Fragment
* is being closed not due to popping the back stack.
*/
+ @Nullable
public Object getExitTransition() {
if (mAnimationInfo == null) {
return null;
@@ -1875,7 +1894,7 @@
* previously-started Activity. <code>transition</code>
* must be an android.transition.Transition.
*/
- public void setReenterTransition(Object transition) {
+ public void setReenterTransition(@Nullable Object transition) {
ensureAnimationInfo().mReenterTransition = transition;
}
@@ -1908,7 +1927,7 @@
* @param transition The Transition to use for shared elements transferred into the content
* Scene. <code>transition</code> must be an android.transition.Transition.
*/
- public void setSharedElementEnterTransition(Object transition) {
+ public void setSharedElementEnterTransition(@Nullable Object transition) {
ensureAnimationInfo().mSharedElementEnterTransition = transition;
}
@@ -1921,6 +1940,7 @@
* @return The Transition to use for shared elements transferred into the content
* Scene.
*/
+ @Nullable
public Object getSharedElementEnterTransition() {
if (mAnimationInfo == null) {
return null;
@@ -1940,7 +1960,7 @@
* @param transition The Transition to use for shared elements transferred out of the content
* Scene. <code>transition</code> must be an android.transition.Transition.
*/
- public void setSharedElementReturnTransition(Object transition) {
+ public void setSharedElementReturnTransition(@Nullable Object transition) {
ensureAnimationInfo().mSharedElementReturnTransition = transition;
}
@@ -1956,6 +1976,7 @@
* @return The Transition to use for shared elements transferred out of the content
* Scene.
*/
+ @Nullable
public Object getSharedElementReturnTransition() {
if (mAnimationInfo == null) {
return null;
@@ -2231,8 +2252,8 @@
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
- View performCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
+ View performCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
if (mChildFragmentManager != null) {
mChildFragmentManager.noteStateNotSaved();
}
diff --git a/fragment/java/android/support/v4/app/FragmentActivity.java b/fragment/src/main/java/android/support/v4/app/FragmentActivity.java
similarity index 100%
rename from fragment/java/android/support/v4/app/FragmentActivity.java
rename to fragment/src/main/java/android/support/v4/app/FragmentActivity.java
diff --git a/fragment/java/android/support/v4/app/FragmentContainer.java b/fragment/src/main/java/android/support/v4/app/FragmentContainer.java
similarity index 100%
rename from fragment/java/android/support/v4/app/FragmentContainer.java
rename to fragment/src/main/java/android/support/v4/app/FragmentContainer.java
diff --git a/fragment/java/android/support/v4/app/FragmentController.java b/fragment/src/main/java/android/support/v4/app/FragmentController.java
similarity index 100%
rename from fragment/java/android/support/v4/app/FragmentController.java
rename to fragment/src/main/java/android/support/v4/app/FragmentController.java
diff --git a/fragment/java/android/support/v4/app/FragmentHostCallback.java b/fragment/src/main/java/android/support/v4/app/FragmentHostCallback.java
similarity index 98%
rename from fragment/java/android/support/v4/app/FragmentHostCallback.java
rename to fragment/src/main/java/android/support/v4/app/FragmentHostCallback.java
index 7dc9f59..eeae62a 100644
--- a/fragment/java/android/support/v4/app/FragmentHostCallback.java
+++ b/fragment/src/main/java/android/support/v4/app/FragmentHostCallback.java
@@ -94,8 +94,9 @@
* Return a {@link LayoutInflater}.
* See {@link Activity#getLayoutInflater()}.
*/
+ @NonNull
public LayoutInflater onGetLayoutInflater() {
- return (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ return LayoutInflater.from(mContext);
}
/**
diff --git a/fragment/java/android/support/v4/app/FragmentManager.java b/fragment/src/main/java/android/support/v4/app/FragmentManager.java
similarity index 100%
rename from fragment/java/android/support/v4/app/FragmentManager.java
rename to fragment/src/main/java/android/support/v4/app/FragmentManager.java
diff --git a/fragment/java/android/support/v4/app/FragmentManagerNonConfig.java b/fragment/src/main/java/android/support/v4/app/FragmentManagerNonConfig.java
similarity index 100%
rename from fragment/java/android/support/v4/app/FragmentManagerNonConfig.java
rename to fragment/src/main/java/android/support/v4/app/FragmentManagerNonConfig.java
diff --git a/fragment/java/android/support/v4/app/FragmentPagerAdapter.java b/fragment/src/main/java/android/support/v4/app/FragmentPagerAdapter.java
similarity index 100%
rename from fragment/java/android/support/v4/app/FragmentPagerAdapter.java
rename to fragment/src/main/java/android/support/v4/app/FragmentPagerAdapter.java
diff --git a/fragment/java/android/support/v4/app/FragmentState.java b/fragment/src/main/java/android/support/v4/app/FragmentState.java
similarity index 100%
rename from fragment/java/android/support/v4/app/FragmentState.java
rename to fragment/src/main/java/android/support/v4/app/FragmentState.java
diff --git a/fragment/java/android/support/v4/app/FragmentStatePagerAdapter.java b/fragment/src/main/java/android/support/v4/app/FragmentStatePagerAdapter.java
similarity index 100%
rename from fragment/java/android/support/v4/app/FragmentStatePagerAdapter.java
rename to fragment/src/main/java/android/support/v4/app/FragmentStatePagerAdapter.java
diff --git a/fragment/java/android/support/v4/app/FragmentTabHost.java b/fragment/src/main/java/android/support/v4/app/FragmentTabHost.java
similarity index 100%
rename from fragment/java/android/support/v4/app/FragmentTabHost.java
rename to fragment/src/main/java/android/support/v4/app/FragmentTabHost.java
diff --git a/fragment/java/android/support/v4/app/FragmentTransaction.java b/fragment/src/main/java/android/support/v4/app/FragmentTransaction.java
similarity index 100%
rename from fragment/java/android/support/v4/app/FragmentTransaction.java
rename to fragment/src/main/java/android/support/v4/app/FragmentTransaction.java
diff --git a/fragment/java/android/support/v4/app/FragmentTransition.java b/fragment/src/main/java/android/support/v4/app/FragmentTransition.java
similarity index 100%
rename from fragment/java/android/support/v4/app/FragmentTransition.java
rename to fragment/src/main/java/android/support/v4/app/FragmentTransition.java
diff --git a/fragment/java/android/support/v4/app/FragmentTransitionCompat21.java b/fragment/src/main/java/android/support/v4/app/FragmentTransitionCompat21.java
similarity index 100%
rename from fragment/java/android/support/v4/app/FragmentTransitionCompat21.java
rename to fragment/src/main/java/android/support/v4/app/FragmentTransitionCompat21.java
diff --git a/fragment/java/android/support/v4/app/FragmentTransitionImpl.java b/fragment/src/main/java/android/support/v4/app/FragmentTransitionImpl.java
similarity index 100%
rename from fragment/java/android/support/v4/app/FragmentTransitionImpl.java
rename to fragment/src/main/java/android/support/v4/app/FragmentTransitionImpl.java
diff --git a/fragment/java/android/support/v4/app/ListFragment.java b/fragment/src/main/java/android/support/v4/app/ListFragment.java
similarity index 100%
rename from fragment/java/android/support/v4/app/ListFragment.java
rename to fragment/src/main/java/android/support/v4/app/ListFragment.java
diff --git a/fragment/java/android/support/v4/app/LoaderManager.java b/fragment/src/main/java/android/support/v4/app/LoaderManager.java
similarity index 100%
rename from fragment/java/android/support/v4/app/LoaderManager.java
rename to fragment/src/main/java/android/support/v4/app/LoaderManager.java
diff --git a/fragment/java/android/support/v4/app/OneShotPreDrawListener.java b/fragment/src/main/java/android/support/v4/app/OneShotPreDrawListener.java
similarity index 100%
rename from fragment/java/android/support/v4/app/OneShotPreDrawListener.java
rename to fragment/src/main/java/android/support/v4/app/OneShotPreDrawListener.java
diff --git a/fragment/java/android/support/v4/app/SuperNotCalledException.java b/fragment/src/main/java/android/support/v4/app/SuperNotCalledException.java
similarity index 100%
rename from fragment/java/android/support/v4/app/SuperNotCalledException.java
rename to fragment/src/main/java/android/support/v4/app/SuperNotCalledException.java
diff --git a/fragment/java/android/support/v4/app/package.html b/fragment/src/main/java/android/support/v4/app/package.html
similarity index 100%
rename from fragment/java/android/support/v4/app/package.html
rename to fragment/src/main/java/android/support/v4/app/package.html
diff --git a/graphics/drawable/Android.mk b/graphics/drawable/Android.mk
index b06fd76..b1f0b38 100644
--- a/graphics/drawable/Android.mk
+++ b/graphics/drawable/Android.mk
@@ -23,7 +23,7 @@
LOCAL_USE_AAPT2 := true
LOCAL_MODULE := android-support-vectordrawable
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-LOCAL_SRC_FILES := $(call all-java-files-under, static/src)
+LOCAL_SRC_FILES := $(call all-java-files-under, static/src/main/java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/static/res
LOCAL_MANIFEST_FILE := static/AndroidManifest.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
@@ -42,7 +42,7 @@
LOCAL_USE_AAPT2 := true
LOCAL_MODULE := android-support-animatedvectordrawable
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-LOCAL_SRC_FILES := $(call all-java-files-under, animated/src)
+LOCAL_SRC_FILES := $(call all-java-files-under, animated/src/main/java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/animated/res
LOCAL_MANIFEST_FILE := animated/AndroidManifest.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
diff --git a/graphics/drawable/AndroidManifest.xml b/graphics/drawable/AndroidManifest.xml
deleted file mode 100644
index 83124c7..0000000
--- a/graphics/drawable/AndroidManifest.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.support.graphics.drawable">
- <application />
-</manifest>
diff --git a/graphics/drawable/animated/build.gradle b/graphics/drawable/animated/build.gradle
index 29aeb3b..6036284 100644
--- a/graphics/drawable/animated/build.gradle
+++ b/graphics/drawable/animated/build.gradle
@@ -15,10 +15,6 @@
generatedDensities = []
}
- sourceSets {
- main.java.srcDir 'src'
- }
-
aaptOptions {
additionalParameters "--no-version-vectors"
}
diff --git a/graphics/drawable/animated/lint-baseline.xml b/graphics/drawable/animated/lint-baseline.xml
index eab8464..9fbd83c 100644
--- a/graphics/drawable/animated/lint-baseline.xml
+++ b/graphics/drawable/animated/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="4" by="lint 3.0.0-alpha9">
+<issues format="4" by="lint 3.0.0-beta6">
<issue
id="ResourceType"
@@ -7,7 +7,7 @@
errorLine1=" parser = resources.getAnimation(id);"
errorLine2=" ~~">
<location
- file="src/android/support/graphics/drawable/AnimatorInflaterCompat.java"
+ file="src/main/java/android/support/graphics/drawable/AnimatorInflaterCompat.java"
line="130"
column="45"/>
</issue>
diff --git a/graphics/drawable/animated/src/android/support/graphics/drawable/Animatable2Compat.java b/graphics/drawable/animated/src/main/java/android/support/graphics/drawable/Animatable2Compat.java
similarity index 100%
rename from graphics/drawable/animated/src/android/support/graphics/drawable/Animatable2Compat.java
rename to graphics/drawable/animated/src/main/java/android/support/graphics/drawable/Animatable2Compat.java
diff --git a/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java b/graphics/drawable/animated/src/main/java/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java
similarity index 100%
rename from graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java
rename to graphics/drawable/animated/src/main/java/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java
diff --git a/graphics/drawable/animated/src/android/support/graphics/drawable/AnimationUtilsCompat.java b/graphics/drawable/animated/src/main/java/android/support/graphics/drawable/AnimationUtilsCompat.java
similarity index 100%
rename from graphics/drawable/animated/src/android/support/graphics/drawable/AnimationUtilsCompat.java
rename to graphics/drawable/animated/src/main/java/android/support/graphics/drawable/AnimationUtilsCompat.java
diff --git a/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatorInflaterCompat.java b/graphics/drawable/animated/src/main/java/android/support/graphics/drawable/AnimatorInflaterCompat.java
similarity index 100%
rename from graphics/drawable/animated/src/android/support/graphics/drawable/AnimatorInflaterCompat.java
rename to graphics/drawable/animated/src/main/java/android/support/graphics/drawable/AnimatorInflaterCompat.java
diff --git a/graphics/drawable/animated/src/android/support/graphics/drawable/ArgbEvaluator.java b/graphics/drawable/animated/src/main/java/android/support/graphics/drawable/ArgbEvaluator.java
similarity index 100%
rename from graphics/drawable/animated/src/android/support/graphics/drawable/ArgbEvaluator.java
rename to graphics/drawable/animated/src/main/java/android/support/graphics/drawable/ArgbEvaluator.java
diff --git a/graphics/drawable/animated/src/android/support/graphics/drawable/PathInterpolatorCompat.java b/graphics/drawable/animated/src/main/java/android/support/graphics/drawable/PathInterpolatorCompat.java
similarity index 100%
rename from graphics/drawable/animated/src/android/support/graphics/drawable/PathInterpolatorCompat.java
rename to graphics/drawable/animated/src/main/java/android/support/graphics/drawable/PathInterpolatorCompat.java
diff --git a/graphics/drawable/static/build.gradle b/graphics/drawable/static/build.gradle
index ee24ad5..949ba89 100644
--- a/graphics/drawable/static/build.gradle
+++ b/graphics/drawable/static/build.gradle
@@ -14,10 +14,6 @@
generatedDensities = []
}
- sourceSets {
- main.java.srcDir 'src'
- }
-
aaptOptions {
additionalParameters "--no-version-vectors"
}
diff --git a/graphics/drawable/static/src/android/support/graphics/drawable/AndroidResources.java b/graphics/drawable/static/src/main/java/android/support/graphics/drawable/AndroidResources.java
similarity index 100%
rename from graphics/drawable/static/src/android/support/graphics/drawable/AndroidResources.java
rename to graphics/drawable/static/src/main/java/android/support/graphics/drawable/AndroidResources.java
diff --git a/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCommon.java b/graphics/drawable/static/src/main/java/android/support/graphics/drawable/VectorDrawableCommon.java
similarity index 100%
rename from graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCommon.java
rename to graphics/drawable/static/src/main/java/android/support/graphics/drawable/VectorDrawableCommon.java
diff --git a/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java b/graphics/drawable/static/src/main/java/android/support/graphics/drawable/VectorDrawableCompat.java
similarity index 100%
rename from graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java
rename to graphics/drawable/static/src/main/java/android/support/graphics/drawable/VectorDrawableCompat.java
diff --git a/lifecycle/common/src/main/java/android/arch/lifecycle/Lifecycling.java b/lifecycle/common/src/main/java/android/arch/lifecycle/Lifecycling.java
index ed9aa3f..63d8a0e 100644
--- a/lifecycle/common/src/main/java/android/arch/lifecycle/Lifecycling.java
+++ b/lifecycle/common/src/main/java/android/arch/lifecycle/Lifecycling.java
@@ -30,7 +30,7 @@
* @hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-class Lifecycling {
+public class Lifecycling {
private static Constructor<? extends GenericLifecycleObserver> sREFLECTIVE;
static {
@@ -152,7 +152,10 @@
return klass != null && LifecycleObserver.class.isAssignableFrom(klass);
}
- static String getAdapterName(String className) {
+ /**
+ * Create a name for an adapter class.
+ */
+ public static String getAdapterName(String className) {
return className.replace(".", "_") + "_LifecycleAdapter";
}
}
diff --git a/lifecycle/compiler/build.gradle b/lifecycle/compiler/build.gradle
index 44bf15d..e784f80 100644
--- a/lifecycle/compiler/build.gradle
+++ b/lifecycle/compiler/build.gradle
@@ -26,6 +26,19 @@
version = LibraryVersions.LIFECYCLES_EXT.toString()
createKotlinCheckstyle(project)
+// we actually need to compile :lifecycle:common, but compileJava is easier
+task compileTestLibrarySource(type: JavaCompile, dependsOn: compileJava) {
+ source "src/tests/test-data/lib/src"
+ classpath = project.compileJava.classpath
+ destinationDir = new File(project.buildDir, 'test-data/lib/classes')
+}
+
+task jarTestLibrarySource(type: Jar, dependsOn: compileTestLibrarySource) {
+ from compileTestLibrarySource.destinationDir
+ archiveName = "test-library.jar"
+ destinationDir = file("src/tests/test-data/lib/")
+}
+
supportLibrary {
name 'Android Lifecycles Compiler'
publish true
diff --git a/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/ErrorMessages.kt b/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/ErrorMessages.kt
index 8dac863..10180a6 100644
--- a/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/ErrorMessages.kt
+++ b/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/ErrorMessages.kt
@@ -33,5 +33,4 @@
const val INVALID_ENCLOSING_ELEMENT =
"Parent of OnLifecycleEvent should be a class or interface"
const val INVALID_ANNOTATED_ELEMENT = "OnLifecycleEvent can only be added to methods"
-
}
diff --git a/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/input_collector.kt b/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/input_collector.kt
index 5183df5..43368936 100644
--- a/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/input_collector.kt
+++ b/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/input_collector.kt
@@ -18,6 +18,7 @@
import android.arch.lifecycle.model.EventMethod
import android.arch.lifecycle.model.LifecycleObserverInfo
+import android.arch.lifecycle.model.getAdapterName
import com.google.auto.common.MoreElements
import com.google.auto.common.MoreTypes
import javax.annotation.processing.ProcessingEnvironment
@@ -28,32 +29,75 @@
import javax.lang.model.element.Modifier
import javax.lang.model.element.TypeElement
import javax.lang.model.element.VariableElement
+import javax.lang.model.type.TypeMirror
+import javax.lang.model.util.ElementFilter
+import javax.lang.model.util.Elements
+import javax.lang.model.util.Types
import javax.tools.Diagnostic
fun collectAndVerifyInput(processingEnv: ProcessingEnvironment,
roundEnv: RoundEnvironment): Map<TypeElement, LifecycleObserverInfo> {
val validator = Validator(processingEnv)
-
- return roundEnv.getElementsAnnotatedWith(OnLifecycleEvent::class.java).map { elem ->
+ val worldCollector = ObserversCollector(processingEnv)
+ roundEnv.getElementsAnnotatedWith(OnLifecycleEvent::class.java).forEach { elem ->
if (elem.kind != ElementKind.METHOD) {
validator.printErrorMessage(ErrorMessages.INVALID_ANNOTATED_ELEMENT, elem)
- null
} else {
val enclosingElement = elem.enclosingElement
- val onState = elem.getAnnotation(OnLifecycleEvent::class.java)
- val method = MoreElements.asExecutable(elem)
- if (validator.validateClass(enclosingElement)
- && validator.validateMethod(method, onState.value)) {
- EventMethod(method, onState, MoreElements.asType(enclosingElement))
- } else {
- null
+ if (validator.validateClass(enclosingElement)) {
+ worldCollector.collect(MoreElements.asType(enclosingElement))
}
}
}
- .filterNotNull()
- .groupBy { MoreElements.asType(it.method.enclosingElement) }
- .mapValues { entry -> LifecycleObserverInfo(entry.key, entry.value) }
+ return worldCollector.observers
+}
+class ObserversCollector(processingEnv: ProcessingEnvironment) {
+ val typeUtils: Types = processingEnv.typeUtils
+ val elementUtils: Elements = processingEnv.elementUtils
+ val lifecycleObserverTypeMirror: TypeMirror =
+ elementUtils.getTypeElement(LifecycleObserver::class.java.canonicalName).asType()
+ val validator = Validator(processingEnv)
+ val observers: MutableMap<TypeElement, LifecycleObserverInfo> = mutableMapOf()
+
+ fun collect(type: TypeElement): LifecycleObserverInfo? {
+ if (type in observers) {
+ return observers[type]
+ }
+ val parents = (listOf(type.superclass) + type.interfaces)
+ .filter { typeUtils.isAssignable(it, lifecycleObserverTypeMirror) }
+ .filterNot { typeUtils.isSameType(it, lifecycleObserverTypeMirror) }
+ .map { collect(MoreTypes.asTypeElement(it)) }
+ .filterNotNull()
+ val info = createObserverInfo(type, parents)
+ if (info != null) {
+ observers[type] = info
+ }
+ return info
+ }
+
+ private fun hasAdapter(type: TypeElement): Boolean {
+ val packageName = if (type.getPackageQName().isEmpty()) "" else "${type.getPackageQName()}."
+ return elementUtils.getTypeElement(packageName + getAdapterName(type)) != null
+ }
+
+ private fun createObserverInfo(typeElement: TypeElement,
+ parents: List<LifecycleObserverInfo>): LifecycleObserverInfo? {
+ if (!validator.validateClass(typeElement)) {
+ return null
+ }
+ val methods = ElementFilter.methodsIn(typeElement.enclosedElements).filter { executable ->
+ MoreElements.isAnnotationPresent(executable, OnLifecycleEvent::class.java)
+ }.map { executable ->
+ val onState = executable.getAnnotation(OnLifecycleEvent::class.java)
+ if (validator.validateMethod(executable, onState.value)) {
+ EventMethod(executable, onState, typeElement)
+ } else {
+ null
+ }
+ }.filterNotNull()
+ return LifecycleObserverInfo(typeElement, methods, hasAdapter(typeElement), parents)
+ }
}
class Validator(val processingEnv: ProcessingEnvironment) {
@@ -100,7 +144,7 @@
}
fun validateClass(classElement: Element): Boolean {
- if (classElement.kind != ElementKind.CLASS && classElement.kind != ElementKind.INTERFACE) {
+ if (!MoreElements.isType(classElement)) {
printErrorMessage(ErrorMessages.INVALID_ENCLOSING_ELEMENT, classElement)
return false
}
diff --git a/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/model/AdapterClass.kt b/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/model/AdapterClass.kt
index 1e76fa8..bd7759a 100644
--- a/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/model/AdapterClass.kt
+++ b/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/model/AdapterClass.kt
@@ -16,9 +16,19 @@
package android.arch.lifecycle.model
+import android.arch.lifecycle.Lifecycling
+import android.arch.lifecycle.getPackage
import javax.lang.model.element.ExecutableElement
import javax.lang.model.element.TypeElement
data class AdapterClass(val type: TypeElement,
val calls: List<EventMethodCall>,
- val syntheticMethods: Set<ExecutableElement>)
\ No newline at end of file
+ val syntheticMethods: Set<ExecutableElement>)
+
+fun getAdapterName(type: TypeElement): String {
+ val packageElement = type.getPackage()
+ val qName = type.qualifiedName.toString()
+ val partialName = if (packageElement.isUnnamed) qName else qName.substring(
+ packageElement.qualifiedName.toString().length + 1)
+ return Lifecycling.getAdapterName(partialName)
+}
diff --git a/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/model/LifecycleObserverInfo.kt b/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/model/LifecycleObserverInfo.kt
index d8bc364..0693478 100644
--- a/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/model/LifecycleObserverInfo.kt
+++ b/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/model/LifecycleObserverInfo.kt
@@ -20,4 +20,6 @@
data class LifecycleObserverInfo(
val type: TypeElement,
- val methods: List<EventMethod>)
\ No newline at end of file
+ val methods: List<EventMethod>,
+ val hasAdapter: Boolean,
+ val parents: List<LifecycleObserverInfo> = listOf())
\ No newline at end of file
diff --git a/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/transformation.kt b/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/transformation.kt
index 66fabf7..16c3d81 100644
--- a/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/transformation.kt
+++ b/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/transformation.kt
@@ -20,39 +20,11 @@
import android.arch.lifecycle.model.EventMethod
import android.arch.lifecycle.model.EventMethodCall
import android.arch.lifecycle.model.LifecycleObserverInfo
-import com.google.auto.common.MoreTypes
import com.google.common.collect.HashMultimap
-import java.util.LinkedList
import javax.annotation.processing.ProcessingEnvironment
import javax.lang.model.element.TypeElement
-import javax.lang.model.type.NoType
-import javax.lang.model.type.TypeMirror
import javax.tools.Diagnostic
-
-private fun superObservers(world: Map<TypeElement, LifecycleObserverInfo>,
- observer: LifecycleObserverInfo): List<LifecycleObserverInfo> {
- val stack = LinkedList<TypeMirror>()
- stack += observer.type.interfaces.reversed()
- stack += observer.type.superclass
- val result = mutableListOf<LifecycleObserverInfo>()
- while (stack.isNotEmpty()) {
- val typeMirror = stack.removeLast()
- if (typeMirror is NoType) {
- continue
- }
- val type = MoreTypes.asTypeElement(typeMirror)
- val currentObserver = world[type]
- if (currentObserver != null) {
- result.add(currentObserver)
- } else {
- stack += type.interfaces.reversed()
- stack += type.superclass
- }
- }
- return result
-}
-
private fun mergeAndVerifyMethods(processingEnv: ProcessingEnvironment,
type: TypeElement,
classMethods: List<EventMethod>,
@@ -80,26 +52,26 @@
fun flattenObservers(processingEnv: ProcessingEnvironment,
world: Map<TypeElement, LifecycleObserverInfo>): List<LifecycleObserverInfo> {
val flattened: MutableMap<LifecycleObserverInfo, LifecycleObserverInfo> = mutableMapOf()
- val superObservers = world.mapValues { superObservers(world, it.value) }
fun traverse(observer: LifecycleObserverInfo) {
if (observer in flattened) {
return
}
- val observers = superObservers[observer.type]!!
- if (observers.isEmpty()) {
+ if (observer.parents.isEmpty()) {
flattened[observer] = observer
return
}
- observers.filter { it !in flattened }.forEach(::traverse)
- val methods = observers
+ observer.parents.forEach(::traverse)
+ val methods = observer.parents
.map(flattened::get)
.fold(emptyList<EventMethod>()) { list, parentObserver ->
- mergeAndVerifyMethods(processingEnv, observer.type, parentObserver!!.methods, list)
+ mergeAndVerifyMethods(processingEnv, observer.type,
+ parentObserver!!.methods, list)
}
flattened[observer] = LifecycleObserverInfo(observer.type,
- mergeAndVerifyMethods(processingEnv, observer.type, observer.methods, methods))
+ mergeAndVerifyMethods(processingEnv, observer.type, observer.methods, methods),
+ observer.hasAdapter)
}
world.values.forEach(::traverse)
@@ -110,21 +82,24 @@
world: Map<TypeElement, LifecycleObserverInfo>): List<AdapterClass> {
val flatObservers = flattenObservers(processingEnv, world)
val syntheticMethods = HashMultimap.create<TypeElement, EventMethodCall>()
- val adapterCalls = flatObservers.map { (type, methods) ->
- val calls = methods.map { eventMethod ->
- val executable = eventMethod.method
- if (type.getPackageQName() != eventMethod.packageName()
- && (executable.isPackagePrivate() || executable.isProtected())) {
- EventMethodCall(eventMethod, eventMethod.type)
- } else {
- EventMethodCall(eventMethod)
- }
- }
- calls.filter { it.syntheticAccess != null }.forEach { eventMethod ->
- syntheticMethods.put(eventMethod.method.type, eventMethod)
- }
- type to calls
- }.toMap()
+ flatObservers.filterNot(LifecycleObserverInfo::hasAdapter)
+ val adapterCalls = flatObservers
+ .filterNot(LifecycleObserverInfo::hasAdapter)
+ .map { (type, methods) ->
+ val calls = methods.map { eventMethod ->
+ val executable = eventMethod.method
+ if (type.getPackageQName() != eventMethod.packageName()
+ && (executable.isPackagePrivate() || executable.isProtected())) {
+ EventMethodCall(eventMethod, eventMethod.type)
+ } else {
+ EventMethodCall(eventMethod)
+ }
+ }
+ calls.filter { it.syntheticAccess != null }.forEach { eventMethod ->
+ syntheticMethods.put(eventMethod.method.type, eventMethod)
+ }
+ type to calls
+ }.toMap()
return adapterCalls.map { (type, calls) ->
val methods = syntheticMethods.get(type) ?: setOf()
diff --git a/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/writer.kt b/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/writer.kt
index 4f12ff4..6b9b7a6 100644
--- a/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/writer.kt
+++ b/lifecycle/compiler/src/main/kotlin/android/arch/lifecycle/writer.kt
@@ -18,6 +18,7 @@
import android.arch.lifecycle.model.AdapterClass
import android.arch.lifecycle.model.EventMethodCall
+import android.arch.lifecycle.model.getAdapterName
import com.squareup.javapoet.AnnotationSpec
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.FieldSpec
@@ -36,7 +37,6 @@
infos.forEach({ writeAdapter(it, processingEnv) })
}
-
private val GENERATED_PACKAGE = "javax.annotation"
private val GENERATED_NAME = "Generated"
private val LIFECYCLE_OWNER = ClassName.get(LifecycleOwner::class.java)
@@ -63,9 +63,7 @@
val dispatchMethod = dispatchMethodBuilder.apply {
adapter.calls
.groupBy { (eventMethod) -> eventMethod.onLifecycleEvent.value }
- .forEach { entry ->
- val event = entry.key
- val calls = entry.value
+ .forEach { (event, calls) ->
if (event == Lifecycle.Event.ON_ANY) {
writeMethodCalls(eventParam, calls, ownerParam, receiverField)
} else {
@@ -184,12 +182,4 @@
private fun takeParams(count: Int, vararg params: Any) = params.take(count).toTypedArray()
-private fun generateParamString(count: Int) = (0..(count - 1)).joinToString(",") { N }
-
-private fun getAdapterName(type: TypeElement): String {
- val packageElement = type.getPackage()
- val qName = type.qualifiedName.toString()
- val partialName = if (packageElement.isUnnamed) qName else qName.substring(
- packageElement.qualifiedName.toString().length + 1)
- return Lifecycling.getAdapterName(partialName)
-}
+private fun generateParamString(count: Int) = (0 until count).joinToString(",") { N }
\ No newline at end of file
diff --git a/lifecycle/compiler/src/tests/kotlin/android/arch/lifecycle/ValidCasesTest.kt b/lifecycle/compiler/src/tests/kotlin/android/arch/lifecycle/ValidCasesTest.kt
index 247d416..a4fda54 100644
--- a/lifecycle/compiler/src/tests/kotlin/android/arch/lifecycle/ValidCasesTest.kt
+++ b/lifecycle/compiler/src/tests/kotlin/android/arch/lifecycle/ValidCasesTest.kt
@@ -19,10 +19,13 @@
import android.arch.lifecycle.utils.load
import android.arch.lifecycle.utils.processClass
import com.google.testing.compile.CompileTester
+import com.google.testing.compile.JavaSourcesSubject
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import javax.tools.StandardLocation
+import java.io.File
+import java.net.URLClassLoader
@RunWith(JUnit4::class)
class ValidCasesTest {
@@ -112,4 +115,16 @@
CompileTester.SuccessfulFileClause<T> {
return generatesFileNamed(StandardLocation.CLASS_OUTPUT, "", "META-INF/proguard/$name")
}
+
+ @Test
+ fun testJar() {
+ val jarUrl = File("src/tests/test-data/lib/test-library.jar").toURI().toURL()
+ val classLoader = URLClassLoader(arrayOf(jarUrl), this.javaClass.classLoader)
+ JavaSourcesSubject.assertThat(load("foo.DerivedFromJar", ""))
+ .withClasspathFrom(classLoader)
+ .processedWith(LifecycleProcessor())
+ .compilesWithoutError().and()
+ .generatesSources(load("foo.DerivedFromJar_LifecycleAdapter", "expected")
+ )
+ }
}
diff --git a/lifecycle/compiler/src/tests/test-data/Bar.java b/lifecycle/compiler/src/tests/test-data/Bar.java
index 773948e..cfc41ca 100644
--- a/lifecycle/compiler/src/tests/test-data/Bar.java
+++ b/lifecycle/compiler/src/tests/test-data/Bar.java
@@ -4,10 +4,11 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.OnLifecycleEvent;
-public class Bar {
+public class Bar implements LifecycleObserver {
@OnLifecycleEvent(ON_START)
public void doOnStart() {
}
@@ -20,17 +21,17 @@
public void doOnStop2Args(LifecycleOwner provider) {
}
- public static class Inner1 {
+ public static class Inner1 implements LifecycleObserver {
@OnLifecycleEvent(ON_START)
public void doOnStart() {
}
- public static class Inner2 {
+ public static class Inner2 implements LifecycleObserver {
@OnLifecycleEvent(ON_START)
public void doOnStart() {
}
- public static class Inner3 {
+ public static class Inner3 implements LifecycleObserver {
@OnLifecycleEvent(ON_START)
public void doOnStart() {
}
diff --git a/lifecycle/compiler/src/tests/test-data/DerivedFromJar.java b/lifecycle/compiler/src/tests/test-data/DerivedFromJar.java
new file mode 100644
index 0000000..d503903
--- /dev/null
+++ b/lifecycle/compiler/src/tests/test-data/DerivedFromJar.java
@@ -0,0 +1,12 @@
+package foo;
+
+import static android.arch.lifecycle.Lifecycle.Event.ON_START;
+
+import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.OnLifecycleEvent;
+
+public class DerivedFromJar extends test.library.LibraryBaseObserver {
+ @OnLifecycleEvent(ON_START)
+ public void doAnother() {
+ }
+}
diff --git a/lifecycle/compiler/src/tests/test-data/DifferentPackagesBase1.java b/lifecycle/compiler/src/tests/test-data/DifferentPackagesBase1.java
index cc9d5d5..fb0966d 100644
--- a/lifecycle/compiler/src/tests/test-data/DifferentPackagesBase1.java
+++ b/lifecycle/compiler/src/tests/test-data/DifferentPackagesBase1.java
@@ -19,10 +19,11 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.OnLifecycleEvent;
-public class DifferentPackagesBase1 {
+public class DifferentPackagesBase1 implements LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
void onStop(LifecycleOwner provider){}
}
diff --git a/lifecycle/compiler/src/tests/test-data/DifferentPackagesBase2.java b/lifecycle/compiler/src/tests/test-data/DifferentPackagesBase2.java
index e31921a..1c3ea72 100644
--- a/lifecycle/compiler/src/tests/test-data/DifferentPackagesBase2.java
+++ b/lifecycle/compiler/src/tests/test-data/DifferentPackagesBase2.java
@@ -19,10 +19,11 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.OnLifecycleEvent;
-class DifferentPackagesPreBase2 {
+class DifferentPackagesPreBase2 implements LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
void onStop(LifecycleOwner provider){}
}
diff --git a/lifecycle/compiler/src/tests/test-data/InheritanceOk1.java b/lifecycle/compiler/src/tests/test-data/InheritanceOk1.java
index 79c2151..889c463 100644
--- a/lifecycle/compiler/src/tests/test-data/InheritanceOk1.java
+++ b/lifecycle/compiler/src/tests/test-data/InheritanceOk1.java
@@ -19,10 +19,11 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.OnLifecycleEvent;
-class Base1 {
+class Base1 implements LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
public void onStop(LifecycleOwner provider) {
}
@@ -43,7 +44,7 @@
}
}
-class Base2 {
+class Base2 implements LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
public void onStop(LifecycleOwner provider) {
}
diff --git a/lifecycle/compiler/src/tests/test-data/InheritanceOk2.java b/lifecycle/compiler/src/tests/test-data/InheritanceOk2.java
index 31f0a41..bb00cca 100644
--- a/lifecycle/compiler/src/tests/test-data/InheritanceOk2.java
+++ b/lifecycle/compiler/src/tests/test-data/InheritanceOk2.java
@@ -3,10 +3,11 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.OnLifecycleEvent;
-class InheritanceOk2Base {
+class InheritanceOk2Base implements LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
public void onStop(LifecycleOwner provider) {
}
diff --git a/lifecycle/compiler/src/tests/test-data/InheritanceOk3.java b/lifecycle/compiler/src/tests/test-data/InheritanceOk3.java
index 50c4623..5a3c91d 100644
--- a/lifecycle/compiler/src/tests/test-data/InheritanceOk3.java
+++ b/lifecycle/compiler/src/tests/test-data/InheritanceOk3.java
@@ -19,10 +19,11 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.OnLifecycleEvent;
-class InheritanceOk3Base {
+class InheritanceOk3Base implements LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
public void onStop(LifecycleOwner provider) {
}
diff --git a/lifecycle/compiler/src/tests/test-data/InterfaceOk1.java b/lifecycle/compiler/src/tests/test-data/InterfaceOk1.java
index 3584f6d..8450302 100644
--- a/lifecycle/compiler/src/tests/test-data/InterfaceOk1.java
+++ b/lifecycle/compiler/src/tests/test-data/InterfaceOk1.java
@@ -17,10 +17,11 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.OnLifecycleEvent;
-interface InterfaceOk1 {
+interface InterfaceOk1 extends LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
void onStop(LifecycleOwner provider);
}
diff --git a/lifecycle/compiler/src/tests/test-data/InterfaceOk2.java b/lifecycle/compiler/src/tests/test-data/InterfaceOk2.java
index 58688d3..fee5b10 100644
--- a/lifecycle/compiler/src/tests/test-data/InterfaceOk2.java
+++ b/lifecycle/compiler/src/tests/test-data/InterfaceOk2.java
@@ -19,16 +19,17 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.OnLifecycleEvent;
-class InterfaceOk2Base {
+class InterfaceOk2Base implements LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
public void onStop1(LifecycleOwner provider) {
}
}
-interface InterfaceOk2Interface {
+interface InterfaceOk2Interface extends LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
void onStop2(LifecycleOwner provider);
}
diff --git a/lifecycle/compiler/src/tests/test-data/InvalidClassModifier.java b/lifecycle/compiler/src/tests/test-data/InvalidClassModifier.java
index 4c30bb6..919bb8c 100644
--- a/lifecycle/compiler/src/tests/test-data/InvalidClassModifier.java
+++ b/lifecycle/compiler/src/tests/test-data/InvalidClassModifier.java
@@ -19,10 +19,11 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.OnLifecycleEvent;
public class InvalidClassModifier {
- private static class Inner {
+ private static class Inner implements LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
private void onStop() {
}
diff --git a/lifecycle/compiler/src/tests/test-data/InvalidFirstArg1.java b/lifecycle/compiler/src/tests/test-data/InvalidFirstArg1.java
index 26bfc23..b028443 100644
--- a/lifecycle/compiler/src/tests/test-data/InvalidFirstArg1.java
+++ b/lifecycle/compiler/src/tests/test-data/InvalidFirstArg1.java
@@ -3,9 +3,10 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.OnLifecycleEvent;
-public class InvalidFirstArg1 {
+public class InvalidFirstArg1 implements LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
public void onStop(Event event) {
}
diff --git a/lifecycle/compiler/src/tests/test-data/InvalidFirstArg2.java b/lifecycle/compiler/src/tests/test-data/InvalidFirstArg2.java
index 459c316..d9937ac 100644
--- a/lifecycle/compiler/src/tests/test-data/InvalidFirstArg2.java
+++ b/lifecycle/compiler/src/tests/test-data/InvalidFirstArg2.java
@@ -3,9 +3,10 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_ANY;
import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.OnLifecycleEvent;
-public class InvalidFirstArg2 {
+public class InvalidFirstArg2 implements LifecycleObserver {
@OnLifecycleEvent(ON_ANY)
public void onStop(Event e2, Event event) {
}
diff --git a/lifecycle/compiler/src/tests/test-data/InvalidInheritance1.java b/lifecycle/compiler/src/tests/test-data/InvalidInheritance1.java
index 69f6bb2..d8f0f62 100644
--- a/lifecycle/compiler/src/tests/test-data/InvalidInheritance1.java
+++ b/lifecycle/compiler/src/tests/test-data/InvalidInheritance1.java
@@ -19,9 +19,10 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_START;
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.OnLifecycleEvent;
-class Base {
+class Base implements LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
void foo() {
}
diff --git a/lifecycle/compiler/src/tests/test-data/InvalidInheritance2.java b/lifecycle/compiler/src/tests/test-data/InvalidInheritance2.java
index b714e47..b63ad44 100644
--- a/lifecycle/compiler/src/tests/test-data/InvalidInheritance2.java
+++ b/lifecycle/compiler/src/tests/test-data/InvalidInheritance2.java
@@ -19,10 +19,10 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_START;
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
-import android.arch.lifecycle.LifecycleOwner;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.OnLifecycleEvent;
-interface Base {
+interface Base extends LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
void foo();
}
diff --git a/lifecycle/compiler/src/tests/test-data/InvalidMethodModifier.java b/lifecycle/compiler/src/tests/test-data/InvalidMethodModifier.java
index 6540333..5eed7b8 100644
--- a/lifecycle/compiler/src/tests/test-data/InvalidMethodModifier.java
+++ b/lifecycle/compiler/src/tests/test-data/InvalidMethodModifier.java
@@ -19,9 +19,10 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.OnLifecycleEvent;
-public class InvalidMethodModifier {
+public class InvalidMethodModifier implements LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
private void onStop() {
}
diff --git a/lifecycle/compiler/src/tests/test-data/InvalidSecondArg.java b/lifecycle/compiler/src/tests/test-data/InvalidSecondArg.java
index e98d915..60ad464 100644
--- a/lifecycle/compiler/src/tests/test-data/InvalidSecondArg.java
+++ b/lifecycle/compiler/src/tests/test-data/InvalidSecondArg.java
@@ -2,10 +2,11 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_ANY;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.OnLifecycleEvent;
-public class InvalidSecondArg {
+public class InvalidSecondArg implements LifecycleObserver {
@OnLifecycleEvent(ON_ANY)
public void onStop(LifecycleOwner provider, Object lastEvent) {
}
diff --git a/lifecycle/compiler/src/tests/test-data/NoPackageOk.java b/lifecycle/compiler/src/tests/test-data/NoPackageOk.java
index a00283d..e7a84ef 100644
--- a/lifecycle/compiler/src/tests/test-data/NoPackageOk.java
+++ b/lifecycle/compiler/src/tests/test-data/NoPackageOk.java
@@ -17,10 +17,11 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.OnLifecycleEvent;
-class NoPackageOk {
+class NoPackageOk implements LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
void onStop(LifecycleOwner provider){}
}
diff --git a/lifecycle/compiler/src/tests/test-data/OnAnyMethod.java b/lifecycle/compiler/src/tests/test-data/OnAnyMethod.java
index f03f1cd..8761774 100644
--- a/lifecycle/compiler/src/tests/test-data/OnAnyMethod.java
+++ b/lifecycle/compiler/src/tests/test-data/OnAnyMethod.java
@@ -20,10 +20,11 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.OnLifecycleEvent;
-public class OnAnyMethod {
+public class OnAnyMethod implements LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
void onStop(LifecycleOwner provider){}
@@ -31,7 +32,6 @@
@OnLifecycleEvent(ON_ANY)
void any(LifecycleOwner provider){}
-
@OnLifecycleEvent(ON_ANY)
void any(LifecycleOwner provider, Event event){}
}
diff --git a/lifecycle/compiler/src/tests/test-data/TooManyArgs1.java b/lifecycle/compiler/src/tests/test-data/TooManyArgs1.java
index 0d65098..cdcff60 100644
--- a/lifecycle/compiler/src/tests/test-data/TooManyArgs1.java
+++ b/lifecycle/compiler/src/tests/test-data/TooManyArgs1.java
@@ -3,10 +3,11 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_ANY;
import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.OnLifecycleEvent;
-public class TooManyArgs1 {
+public class TooManyArgs1 implements LifecycleObserver {
@OnLifecycleEvent(ON_ANY)
public void onAny(LifecycleOwner provider, Event event, int x) {
}
diff --git a/lifecycle/compiler/src/tests/test-data/TooManyArgs2.java b/lifecycle/compiler/src/tests/test-data/TooManyArgs2.java
index f332d0b..b38d906 100644
--- a/lifecycle/compiler/src/tests/test-data/TooManyArgs2.java
+++ b/lifecycle/compiler/src/tests/test-data/TooManyArgs2.java
@@ -3,10 +3,11 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.OnLifecycleEvent;
-public class TooManyArgs2 {
+public class TooManyArgs2 implements LifecycleObserver {
@OnLifecycleEvent(ON_STOP)
public void onStop(LifecycleOwner provider, Event event) {
}
diff --git a/lifecycle/compiler/src/tests/test-data/expected/DerivedFromJar_LifecycleAdapter.java b/lifecycle/compiler/src/tests/test-data/expected/DerivedFromJar_LifecycleAdapter.java
new file mode 100644
index 0000000..f3889a1
--- /dev/null
+++ b/lifecycle/compiler/src/tests/test-data/expected/DerivedFromJar_LifecycleAdapter.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 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 foo;
+
+import android.arch.lifecycle.GenericLifecycleObserver;
+import android.arch.lifecycle.Lifecycle;
+import android.arch.lifecycle.LifecycleOwner;
+import java.lang.Override;
+import javax.annotation.Generated;
+
+@Generated("android.arch.lifecycle.LifecycleProcessor")
+public class DerivedFromJar_LifecycleAdapter implements GenericLifecycleObserver {
+ final DerivedFromJar mReceiver;
+
+ DerivedFromJar_LifecycleAdapter(DerivedFromJar receiver) {
+ this.mReceiver = receiver;
+ }
+
+ @Override
+ public void onStateChanged(LifecycleOwner owner, Lifecycle.Event event) {
+ if (event == Lifecycle.Event.ON_START) {
+ mReceiver.doOnStart();
+ mReceiver.doAnother();
+ }
+ }
+}
diff --git a/lifecycle/compiler/src/tests/test-data/lib/src/test/library/LibraryBaseObserver.java b/lifecycle/compiler/src/tests/test-data/lib/src/test/library/LibraryBaseObserver.java
new file mode 100644
index 0000000..d43347f
--- /dev/null
+++ b/lifecycle/compiler/src/tests/test-data/lib/src/test/library/LibraryBaseObserver.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 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 test.library;
+
+import static android.arch.lifecycle.Lifecycle.Event.ON_START;
+import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
+
+import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
+import android.arch.lifecycle.LifecycleOwner;
+import android.arch.lifecycle.OnLifecycleEvent;
+
+public class LibraryBaseObserver implements LifecycleObserver {
+ @OnLifecycleEvent(ON_START)
+ public void doOnStart() {
+ }
+}
diff --git a/lifecycle/compiler/src/tests/test-data/lib/src/test/library/LibraryBaseObserver_LifecycleAdapter.java b/lifecycle/compiler/src/tests/test-data/lib/src/test/library/LibraryBaseObserver_LifecycleAdapter.java
new file mode 100644
index 0000000..da44f92
--- /dev/null
+++ b/lifecycle/compiler/src/tests/test-data/lib/src/test/library/LibraryBaseObserver_LifecycleAdapter.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 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 test.library;
+
+import android.arch.lifecycle.GenericLifecycleObserver;
+import android.arch.lifecycle.Lifecycle;
+import android.arch.lifecycle.LifecycleOwner;
+import java.lang.Override;
+import javax.annotation.Generated;
+
+@Generated("android.arch.lifecycle.LifecycleProcessor")
+public class LibraryBaseObserver_LifecycleAdapter implements GenericLifecycleObserver {
+ final LibraryBaseObserver mReceiver;
+
+ LibraryBaseObserver_LifecycleAdapter(LibraryBaseObserver receiver) {
+ this.mReceiver = receiver;
+ }
+
+ @Override
+ public void onStateChanged(LifecycleOwner owner, Lifecycle.Event event) {
+ if (event == Lifecycle.Event.ON_START) {
+ mReceiver.doOnStart();
+ }
+ }
+}
diff --git a/lifecycle/compiler/src/tests/test-data/lib/test-library.jar b/lifecycle/compiler/src/tests/test-data/lib/test-library.jar
new file mode 100644
index 0000000..f1156ad
--- /dev/null
+++ b/lifecycle/compiler/src/tests/test-data/lib/test-library.jar
Binary files differ
diff --git a/lifecycle/extensions/build.gradle b/lifecycle/extensions/build.gradle
index 9d33e55..79be36c 100644
--- a/lifecycle/extensions/build.gradle
+++ b/lifecycle/extensions/build.gradle
@@ -45,8 +45,6 @@
compile libs.support.fragments, libs.support_exclude_config
compile project(":lifecycle:common")
- annotationProcessor project(":lifecycle:compiler")
-
testCompile project(":arch:core-testing")
testCompile libs.junit
testCompile libs.mockito_core
diff --git a/lifecycle/extensions/src/main/java/android/arch/lifecycle/LiveData.java b/lifecycle/extensions/src/main/java/android/arch/lifecycle/LiveData.java
index da5600c..4c0b7a4 100644
--- a/lifecycle/extensions/src/main/java/android/arch/lifecycle/LiveData.java
+++ b/lifecycle/extensions/src/main/java/android/arch/lifecycle/LiveData.java
@@ -354,7 +354,7 @@
return mActiveCount > 0;
}
- class LifecycleBoundObserver implements LifecycleObserver {
+ class LifecycleBoundObserver implements GenericLifecycleObserver {
public final LifecycleOwner owner;
public final Observer<T> observer;
public boolean active;
@@ -365,9 +365,8 @@
this.observer = observer;
}
- @SuppressWarnings("unused")
- @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
- void onStateChange() {
+ @Override
+ public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(observer);
return;
diff --git a/lifecycle/reactivestreams/src/main/java/android/arch/lifecycle/LiveDataReactiveStreams.java b/lifecycle/reactivestreams/src/main/java/android/arch/lifecycle/LiveDataReactiveStreams.java
index ec9b7f1..2b25bc9 100644
--- a/lifecycle/reactivestreams/src/main/java/android/arch/lifecycle/LiveDataReactiveStreams.java
+++ b/lifecycle/reactivestreams/src/main/java/android/arch/lifecycle/LiveDataReactiveStreams.java
@@ -17,6 +17,7 @@
package android.arch.lifecycle;
import android.arch.core.executor.ArchTaskExecutor;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.reactivestreams.Publisher;
@@ -133,40 +134,101 @@
/**
* Creates an Observable {@link LiveData} stream from a ReactiveStreams publisher.
+ *
+ * <p>
+ * When the LiveData becomes active, it subscribes to the emissions from the Publisher.
+ *
+ * <p>
+ * When the LiveData becomes inactive, the subscription is cleared.
+ * LiveData holds the last value emitted by the Publisher when the LiveData was active.
+ * <p>
+ * Therefore, in the case of a hot RxJava Observable, when a new LiveData {@link Observer} is
+ * added, it will automatically notify with the last value held in LiveData,
+ * which might not be the last value emitted by the Publisher.
+ *
+ * @param <T> The type of data hold by this instance.
*/
public static <T> LiveData<T> fromPublisher(final Publisher<T> publisher) {
- MutableLiveData<T> liveData = new MutableLiveData<>();
- // Since we don't have a way to directly observe cancels, weakly hold the live data.
- final WeakReference<MutableLiveData<T>> liveDataRef = new WeakReference<>(liveData);
-
- publisher.subscribe(new Subscriber<T>() {
- @Override
- public void onSubscribe(Subscription s) {
- // Don't worry about backpressure. If the stream is too noisy then backpressure can
- // be handled upstream.
- s.request(Long.MAX_VALUE);
- }
-
- @Override
- public void onNext(final T t) {
- final LiveData<T> liveData = liveDataRef.get();
- if (liveData != null) {
- liveData.postValue(t);
- }
- }
-
- @Override
- public void onError(Throwable t) {
- // Errors should be handled upstream, so propagate as a crash.
- throw new RuntimeException(t);
- }
-
- @Override
- public void onComplete() {
- }
- });
-
- return liveData;
+ return new PublisherLiveData<>(publisher);
}
+ /**
+ * Defines a {@link LiveData} object that wraps a {@link Publisher}.
+ *
+ * <p>
+ * When the LiveData becomes active, it subscribes to the emissions from the Publisher.
+ *
+ * <p>
+ * When the LiveData becomes inactive, the subscription is cleared.
+ * LiveData holds the last value emitted by the Publisher when the LiveData was active.
+ * <p>
+ * Therefore, in the case of a hot RxJava Observable, when a new LiveData {@link Observer} is
+ * added, it will automatically notify with the last value held in LiveData,
+ * which might not be the last value emitted by the Publisher.
+ *
+ * @param <T> The type of data hold by this instance.
+ */
+ private static class PublisherLiveData<T> extends LiveData<T> {
+ private WeakReference<Subscription> mSubscriptionRef;
+ private final Publisher mPublisher;
+ private final Object mLock = new Object();
+
+ PublisherLiveData(@NonNull final Publisher publisher) {
+ mPublisher = publisher;
+ }
+
+ @Override
+ protected void onActive() {
+ super.onActive();
+
+ mPublisher.subscribe(new Subscriber<T>() {
+ @Override
+ public void onSubscribe(Subscription s) {
+ // Don't worry about backpressure. If the stream is too noisy then
+ // backpressure can be handled upstream.
+ synchronized (mLock) {
+ s.request(Long.MAX_VALUE);
+ mSubscriptionRef = new WeakReference<>(s);
+ }
+ }
+
+ @Override
+ public void onNext(final T t) {
+ postValue(t);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ synchronized (mLock) {
+ mSubscriptionRef = null;
+ }
+ // Errors should be handled upstream, so propagate as a crash.
+ throw new RuntimeException(t);
+ }
+
+ @Override
+ public void onComplete() {
+ synchronized (mLock) {
+ mSubscriptionRef = null;
+ }
+ }
+ });
+
+ }
+
+ @Override
+ protected void onInactive() {
+ super.onInactive();
+ synchronized (mLock) {
+ WeakReference<Subscription> subscriptionRef = mSubscriptionRef;
+ if (subscriptionRef != null) {
+ Subscription subscription = subscriptionRef.get();
+ if (subscription != null) {
+ subscription.cancel();
+ }
+ mSubscriptionRef = null;
+ }
+ }
+ }
+ }
}
diff --git a/lifecycle/reactivestreams/src/test/java/android/arch/lifecycle/LiveDataReactiveStreamsTest.java b/lifecycle/reactivestreams/src/test/java/android/arch/lifecycle/LiveDataReactiveStreamsTest.java
index ca52ee5..7278847 100644
--- a/lifecycle/reactivestreams/src/test/java/android/arch/lifecycle/LiveDataReactiveStreamsTest.java
+++ b/lifecycle/reactivestreams/src/test/java/android/arch/lifecycle/LiveDataReactiveStreamsTest.java
@@ -140,6 +140,38 @@
}
@Test
+ public void convertsFromPublisherAfterInactive() {
+ PublishProcessor<String> processor = PublishProcessor.create();
+ LiveData<String> liveData = LiveDataReactiveStreams.fromPublisher(processor);
+
+ liveData.observe(mLifecycleOwner, mObserver);
+ processor.onNext("foo");
+ liveData.removeObserver(mObserver);
+ processor.onNext("bar");
+
+ liveData.observe(mLifecycleOwner, mObserver);
+ processor.onNext("baz");
+
+ assertThat(mLiveDataOutput, is(Arrays.asList("foo", "foo", "baz")));
+ }
+
+ @Test
+ public void convertsFromPublisherManagesSubcriptions() {
+ PublishProcessor<String> processor = PublishProcessor.create();
+ LiveData<String> liveData = LiveDataReactiveStreams.fromPublisher(processor);
+
+ assertThat(processor.hasSubscribers(), is(false));
+ liveData.observe(mLifecycleOwner, mObserver);
+
+ // once the live data is active, there's a subscriber
+ assertThat(processor.hasSubscribers(), is(true));
+
+ liveData.removeObserver(mObserver);
+ // once the live data is inactive, the subscriber is removed
+ assertThat(processor.hasSubscribers(), is(false));
+ }
+
+ @Test
public void convertsFromAsyncPublisher() {
Flowable<String> input = Flowable.just("foo")
.concatWith(Flowable.just("bar", "baz").observeOn(sBackgroundScheduler));
diff --git a/paging/common/src/main/java/android/arch/paging/ContiguousDataSource.java b/paging/common/src/main/java/android/arch/paging/ContiguousDataSource.java
index 9ff1117..afcc208 100644
--- a/paging/common/src/main/java/android/arch/paging/ContiguousDataSource.java
+++ b/paging/common/src/main/java/android/arch/paging/ContiguousDataSource.java
@@ -41,6 +41,8 @@
return true;
}
+ /** @hide */
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@WorkerThread
@Nullable
public abstract NullPaddedList<Value> loadInitial(
@@ -58,7 +60,10 @@
* @param pageSize Suggested number of items to load.
* @return List of items, starting at position currentEndIndex + 1. Null if the data source is
* no longer valid, and should not be queried again.
+ *
+ * @hide
*/
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@WorkerThread
@Nullable
public final List<Value> loadAfter(int currentEndIndex,
@@ -88,7 +93,10 @@
* on item contents.
* @param pageSize Suggested number of items to load.
* @return List of items, in descending order, starting at position currentBeginIndex - 1.
+ *
+ * @hide
*/
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@WorkerThread
@Nullable
public final List<Value> loadBefore(int currentBeginIndex,
diff --git a/percent/src/android/support/percent/PercentFrameLayout.java b/percent/src/android/support/percent/PercentFrameLayout.java
index b9abd39..4190858 100644
--- a/percent/src/android/support/percent/PercentFrameLayout.java
+++ b/percent/src/android/support/percent/PercentFrameLayout.java
@@ -126,6 +126,7 @@
* app:layout_constraintBottom_toBottomOf="@+id/bottom_guideline" />
*
* </android.support.constraint.ConstraintLayout>
+ * </pre>
*/
@Deprecated
public class PercentFrameLayout extends FrameLayout {
diff --git a/recommendation/Android.mk b/recommendation/Android.mk
index 99ba65f..ea819e9 100644
--- a/recommendation/Android.mk
+++ b/recommendation/Android.mk
@@ -25,7 +25,7 @@
LOCAL_USE_AAPT2 := true
LOCAL_MODULE := android-support-recommendation
LOCAL_SDK_VERSION := current
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES := $(call all-java-files-under, src/main/java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-v4 \
diff --git a/recommendation/build.gradle b/recommendation/build.gradle
index 61b2fb2..0c38487 100644
--- a/recommendation/build.gradle
+++ b/recommendation/build.gradle
@@ -8,12 +8,6 @@
defaultConfig {
minSdkVersion 21
}
-
- sourceSets {
- main.java.srcDirs = ['src']
- main.res.srcDir 'res'
- }
-
}
supportLibrary {
diff --git a/recommendation/src/android/support/app/recommendation/ContentRecommendation.java b/recommendation/src/main/java/android/support/app/recommendation/ContentRecommendation.java
similarity index 100%
rename from recommendation/src/android/support/app/recommendation/ContentRecommendation.java
rename to recommendation/src/main/java/android/support/app/recommendation/ContentRecommendation.java
diff --git a/recommendation/src/android/support/app/recommendation/RecommendationExtender.java b/recommendation/src/main/java/android/support/app/recommendation/RecommendationExtender.java
similarity index 100%
rename from recommendation/src/android/support/app/recommendation/RecommendationExtender.java
rename to recommendation/src/main/java/android/support/app/recommendation/RecommendationExtender.java
diff --git a/room/common/src/main/java/android/arch/persistence/room/RoomWarnings.java b/room/common/src/main/java/android/arch/persistence/room/RoomWarnings.java
index 91f32e4..c64be96 100644
--- a/room/common/src/main/java/android/arch/persistence/room/RoomWarnings.java
+++ b/room/common/src/main/java/android/arch/persistence/room/RoomWarnings.java
@@ -117,4 +117,12 @@
*/
public static final String MISSING_INDEX_ON_FOREIGN_KEY_CHILD =
"ROOM_MISSING_FOREIGN_KEY_CHILD_INDEX";
+
+ /**
+ * Reported when a Pojo has multiple constructors, one of which is a no-arg constructor. Room
+ * will pick that one by default but will print this warning in case the constructor choice is
+ * important. You can always guide Room to use the right constructor using the @Ignore
+ * annotation.
+ */
+ public static final String DEFAULT_CONSTRUCTOR = "ROOM_DEFAULT_CONSTRUCTOR";
}
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/ext/javapoet_ext.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/ext/javapoet_ext.kt
index daaa8e3..066bd1f 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/ext/javapoet_ext.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/ext/javapoet_ext.kt
@@ -78,6 +78,8 @@
ClassName.get("android.arch.persistence.room.util", "TableInfo.Column")
val TABLE_INFO_FOREIGN_KEY : ClassName =
ClassName.get("android.arch.persistence.room.util", "TableInfo.ForeignKey")
+ val TABLE_INFO_INDEX : ClassName =
+ ClassName.get("android.arch.persistence.room.util", "TableInfo.Index")
val LIMIT_OFFSET_DATA_SOURCE : ClassName =
ClassName.get("android.arch.persistence.room.paging", "LimitOffsetDataSource")
}
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/EntityProcessor.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/EntityProcessor.kt
index 540c95a..405c6b1 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/EntityProcessor.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/EntityProcessor.kt
@@ -247,21 +247,27 @@
context.checker.check(candidates.isNotEmpty(), element, ProcessorErrors.MISSING_PRIMARY_KEY)
// 1. If a key is not autogenerated, but is Primary key or is part of Primary key we
- // force the @NonNull annotation
+ // force the @NonNull annotation. If the key is a single Primary Key, Integer or Long, we
+ // don't force the @NonNull annotation since SQLite will automatically generate IDs.
// 2. If a key is autogenerate, we generate NOT NULL in table spec, but we don't require
// @NonNull annotation on the field itself.
candidates.filter { candidate -> !candidate.autoGenerateId }
.map { candidate ->
candidate.fields.map { field ->
- context.checker.check(field.nonNull, field.element,
- ProcessorErrors.primaryKeyNull(field.getPath()))
- // Validate parents for nullability
- var parent = field.parent
- while(parent != null) {
- val parentField = parent.field
- context.checker.check(parentField.nonNull, parentField.element,
- ProcessorErrors.primaryKeyNull(parentField.getPath()))
- parent = parentField.parent
+ if (candidate.fields.size > 1 ||
+ (candidate.fields.size == 1
+ && field.affinity != SQLTypeAffinity.INTEGER)) {
+ context.checker.check(field.nonNull, field.element,
+ ProcessorErrors.primaryKeyNull(field.getPath()))
+ // Validate parents for nullability
+ var parent = field.parent
+ while (parent != null) {
+ val parentField = parent.field
+ context.checker.check(parentField.nonNull,
+ parentField.element,
+ ProcessorErrors.primaryKeyNull(parentField.getPath()))
+ parent = parentField.parent
+ }
}
}
}
@@ -518,7 +524,7 @@
}
private fun createIndexName(columnNames: List<String>, tableName: String): String {
- return "index_" + tableName + "_" + columnNames.joinToString("_")
+ return Index.DEFAULT_PREFIX + tableName + "_" + columnNames.joinToString("_")
}
private fun extractForeignKeys(annotation: AnnotationMirror): List<ForeignKeyInput> {
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/PojoProcessor.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/PojoProcessor.kt
index 21c7fcc..535e116 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/PojoProcessor.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/PojoProcessor.kt
@@ -16,10 +16,10 @@
package android.arch.persistence.room.processor
-import android.arch.persistence.room.Relation
import android.arch.persistence.room.ColumnInfo
import android.arch.persistence.room.Embedded
import android.arch.persistence.room.Ignore
+import android.arch.persistence.room.Relation
import android.arch.persistence.room.ext.getAllFieldsIncludingPrivateSupers
import android.arch.persistence.room.ext.getAnnotationValue
import android.arch.persistence.room.ext.getAsString
@@ -35,17 +35,17 @@
import android.arch.persistence.room.processor.cache.Cache
import android.arch.persistence.room.vo.CallType
import android.arch.persistence.room.vo.Constructor
-import android.arch.persistence.room.vo.Field
-import android.arch.persistence.room.vo.FieldGetter
import android.arch.persistence.room.vo.EmbeddedField
import android.arch.persistence.room.vo.Entity
+import android.arch.persistence.room.vo.Field
+import android.arch.persistence.room.vo.FieldGetter
import android.arch.persistence.room.vo.FieldSetter
import android.arch.persistence.room.vo.Pojo
+import android.arch.persistence.room.vo.Warning
import com.google.auto.common.AnnotationMirrors
import com.google.auto.common.MoreElements
import com.google.auto.common.MoreTypes
import javax.lang.model.element.ExecutableElement
-import javax.lang.model.element.Modifier
import javax.lang.model.element.Modifier.ABSTRACT
import javax.lang.model.element.Modifier.PRIVATE
import javax.lang.model.element.Modifier.PROTECTED
@@ -276,14 +276,22 @@
}
context.logger.e(element, ProcessorErrors.MISSING_POJO_CONSTRUCTOR)
return null
- }
- if (goodConstructors.size > 1) {
+ } else if (goodConstructors.size > 1) {
+ // if there is a no-arg constructor, pick it. Even though it is weird, easily happens
+ // with kotlin data classes.
+ val noArg = goodConstructors.firstOrNull { it.params.isEmpty() }
+ if (noArg != null) {
+ context.logger.w(Warning.DEFAULT_CONSTRUCTOR, element,
+ ProcessorErrors.TOO_MANY_POJO_CONSTRUCTORS_CHOOSING_NO_ARG)
+ return noArg
+ }
goodConstructors.forEach {
context.logger.e(it.element, ProcessorErrors.TOO_MANY_POJO_CONSTRUCTORS)
}
return null
+ } else {
+ return goodConstructors.first()
}
- return goodConstructors.first()
}
private fun processEmbeddedField(declaredType: DeclaredType?, variableElement: VariableElement)
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/ProcessorErrors.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/ProcessorErrors.kt
index 8058ff9..be26297 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/ProcessorErrors.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/ProcessorErrors.kt
@@ -460,6 +460,11 @@
unwanted constructors with @Ignore.
""".trim()
+ val TOO_MANY_POJO_CONSTRUCTORS_CHOOSING_NO_ARG = """
+ There are multiple good constructors and Room will pick the no-arg constructor.
+ You can use the @Ignore annotation to eliminate unwanted constructors.
+ """.trim()
+
val PAGING_SPECIFY_DATA_SOURCE_TYPE = "For now, Room only supports TiledDataSource class."
fun primaryKeyNull(field: String): String{
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Index.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Index.kt
index 69f16f3..0bee2e0 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Index.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Index.kt
@@ -23,7 +23,10 @@
* Represents a processed index.
*/
data class Index(val name : String, val unique : Boolean, val fields : List<Field>) {
-
+ companion object {
+ // should match the value in TableInfo.Index.DEFAULT_PREFIX
+ const val DEFAULT_PREFIX = "index_"
+ }
fun createQuery(tableName : String) : String {
val uniqueSQL = if (unique) {
"UNIQUE"
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Warning.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Warning.kt
index 9cf137d..91bcb33 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Warning.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Warning.kt
@@ -31,7 +31,8 @@
INDEX_FROM_PARENT_FIELD_IS_DROPPED("ROOM_PARENT_FIELD_INDEX_IS_DROPPED"),
RELATION_TYPE_MISMATCH("ROOM_RELATION_TYPE_MISMATCH"),
MISSING_SCHEMA_LOCATION("ROOM_MISSING_SCHEMA_LOCATION"),
- MISSING_INDEX_ON_FOREIGN_KEY_CHILD("ROOM_MISSING_FOREIGN_KEY_CHILD_INDEX");
+ MISSING_INDEX_ON_FOREIGN_KEY_CHILD("ROOM_MISSING_FOREIGN_KEY_CHILD_INDEX"),
+ DEFAULT_CONSTRUCTOR("ROOM_DEFAULT_CONSTRUCTOR");
companion object {
val PUBLIC_KEY_MAP = Warning.values().associateBy { it.publicKey }
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/TableInfoValidationWriter.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/TableInfoValidationWriter.kt
index fe9e743..e54f986 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/TableInfoValidationWriter.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/TableInfoValidationWriter.kt
@@ -75,9 +75,26 @@
/*parent column names*/ refColumnNames)
}
- addStatement("final $T $L = new $T($S, $L, $L)",
+ val indicesSetVar = scope.getTmpVar("_indices$suffix")
+ val indicesType = ParameterizedTypeName.get(HashSet::class.typeName(),
+ RoomTypeNames.TABLE_INFO_INDEX)
+ addStatement("final $T $L = new $T($L)", indicesType, indicesSetVar,
+ indicesType, entity.indices.size)
+ entity.indices.forEach { index ->
+ val columnNames = index.fields
+ .joinToString(",") { "\"${it.columnName}\"" }
+ addStatement("$L.add(new $T($S, $L, $T.asList($L)))",
+ indicesSetVar,
+ RoomTypeNames.TABLE_INFO_INDEX,
+ index.name,
+ index.unique,
+ Arrays::class.typeName(),
+ columnNames)
+ }
+
+ addStatement("final $T $L = new $T($S, $L, $L, $L)",
RoomTypeNames.TABLE_INFO, expectedInfoVar, RoomTypeNames.TABLE_INFO,
- entity.tableName, columnListVar, foreignKeySetVar)
+ entity.tableName, columnListVar, foreignKeySetVar, indicesSetVar)
val existingVar = scope.getTmpVar("_existing$suffix")
addStatement("final $T $L = $T.read($N, $S)",
diff --git a/room/compiler/src/test/data/databasewriter/output/ComplexDatabase.java b/room/compiler/src/test/data/databasewriter/output/ComplexDatabase.java
index 80d73a9..cfdc110 100644
--- a/room/compiler/src/test/data/databasewriter/output/ComplexDatabase.java
+++ b/room/compiler/src/test/data/databasewriter/output/ComplexDatabase.java
@@ -11,6 +11,7 @@
import android.arch.persistence.room.util.TableInfo;
import android.arch.persistence.room.util.TableInfo.Column;
import android.arch.persistence.room.util.TableInfo.ForeignKey;
+import android.arch.persistence.room.util.TableInfo.Index;
import java.lang.IllegalStateException;
import java.lang.Override;
import java.lang.String;
@@ -59,7 +60,8 @@
_columnsUser.put("lastName", new TableInfo.Column("lastName", "TEXT", false, 0));
_columnsUser.put("ageColumn", new TableInfo.Column("ageColumn", "INTEGER", true, 0));
final HashSet<TableInfo.ForeignKey> _foreignKeysUser = new HashSet<TableInfo.ForeignKey>(0);
- final TableInfo _infoUser = new TableInfo("User", _columnsUser, _foreignKeysUser);
+ final HashSet<TableInfo.Index> _indicesUser = new HashSet<TableInfo.Index>(0);
+ final TableInfo _infoUser = new TableInfo("User", _columnsUser, _foreignKeysUser, _indicesUser);
final TableInfo _existingUser = TableInfo.read(_db, "User");
if (! _infoUser.equals(_existingUser)) {
throw new IllegalStateException("Migration didn't properly handle User(foo.bar.User).\n"
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/EntityProcessorTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/EntityProcessorTest.kt
index 533d8c4..4abf13d 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/EntityProcessorTest.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/EntityProcessorTest.kt
@@ -1002,6 +1002,21 @@
}
@Test
+ fun primaryKey_nonNull_notNeeded() {
+ listOf("long", "Long", "Integer", "int").forEach { type ->
+ singleEntity(
+ """
+ @PrimaryKey
+ public $type id;
+ """) { entity, _ ->
+ assertThat(entity.primaryKey.fields.size, `is`(1))
+ assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id"))
+ assertThat(entity.primaryKey.autoGenerateId, `is`(false))
+ }.compilesWithoutError()
+ }
+ }
+
+ @Test
fun primaryKey_autoGenerateBadType() {
listOf("String", "float", "Float", "Double", "double").forEach { type ->
singleEntity(
@@ -1270,7 +1285,7 @@
public String b;
static class Baz {
- public String bb;
+ public Integer bb;
}
}
""") { _, _ ->
@@ -1386,6 +1401,71 @@
}
@Test
+ fun primaryKey_integerOverrideEmbedded() {
+ val parent = JavaFileObjects.forSourceLines("foo.bar.Base",
+ """
+ package foo.bar;
+ import android.support.annotation.NonNull;
+ import android.arch.persistence.room.*;
+
+ public class Base {
+ long baseId;
+ String name, lastName;
+ @Embedded(prefix = "bar_")
+ @PrimaryKey
+ public Foo foo;
+
+ static class Foo {
+ public Integer a;
+ }
+ }
+ """)
+ singleEntity(
+ """
+ @PrimaryKey
+ public int id;
+ """,
+ baseClass = "foo.bar.Base",
+ jfos = listOf(parent)) { _, _ ->
+ }.compilesWithoutError().withNoteContaining(
+ "PrimaryKey[foo > a] is overridden by PrimaryKey[id]")
+ }
+
+ @Test
+ fun primaryKey_singleStringPrimaryKeyOverrideEmbedded() {
+ val parent = JavaFileObjects.forSourceLines("foo.bar.Base",
+ """
+ package foo.bar;
+ import android.support.annotation.NonNull;
+ import android.arch.persistence.room.*;
+
+ public class Base {
+ long baseId;
+ String name, lastName;
+ @Embedded(prefix = "bar_")
+ @PrimaryKey
+ public Foo foo;
+
+ static class Foo {
+ public String a;
+ }
+ }
+ """)
+ singleEntity(
+ """
+ @PrimaryKey
+ public int id;
+ """,
+ baseClass = "foo.bar.Base",
+ jfos = listOf(parent)) { _, _ ->
+ }.failsToCompile().withErrorContaining(ProcessorErrors.primaryKeyNull("foo"))
+ .and().withErrorContaining(ProcessorErrors.primaryKeyNull("foo > a"))
+ .and().withNoteContaining(
+ "PrimaryKey[foo > a] is overridden by PrimaryKey[id]")
+ .and().withErrorCount(2)
+ }
+
+ @Test
fun relationInEntity() {
singleEntity(
"""
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/PojoProcessorTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/PojoProcessorTest.kt
index ebb8372..4f14fdb 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/PojoProcessorTest.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/PojoProcessorTest.kt
@@ -694,6 +694,21 @@
}
@Test
+ fun constructor_multipleMatching_withNoArg() {
+ singleRun("""
+ String mName;
+ String mLastName;
+ public MyPojo() {
+ }
+ public MyPojo(String name, String lastName) {
+ }
+ """) { pojo ->
+ assertThat(pojo.constructor?.params?.size ?: -1, `is`(0))
+ }.compilesWithoutError().withWarningContaining(
+ ProcessorErrors.TOO_MANY_POJO_CONSTRUCTORS_CHOOSING_NO_ARG)
+ }
+
+ @Test
fun recursion_1Level() {
singleRun(
"""
diff --git a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.TestDatabase/1.json b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.TestDatabase/1.json
index 6425de7..e6bb21c 100644
--- a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.TestDatabase/1.json
+++ b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.TestDatabase/1.json
@@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 1,
- "identityHash": "7beb328c9cd44a7782dfaa18c30ecb83",
+ "identityHash": "933c7e2810b0f89ab84faa68bbea5852",
"entities": [
{
"tableName": "Book",
@@ -161,11 +161,37 @@
]
}
]
+ },
+ {
+ "tableName": "NoArgClass",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `class_name` TEXT NOT NULL, PRIMARY KEY(`id`))",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "class_name",
+ "columnName": "class_name",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
}
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
- "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"7beb328c9cd44a7782dfaa18c30ecb83\")"
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"933c7e2810b0f89ab84faa68bbea5852\")"
]
}
}
\ No newline at end of file
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/TestDatabase.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/TestDatabase.kt
index b9344af..74d8853 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/TestDatabase.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/TestDatabase.kt
@@ -23,9 +23,11 @@
import android.arch.persistence.room.integration.kotlintestapp.vo.Author
import android.arch.persistence.room.integration.kotlintestapp.vo.Book
import android.arch.persistence.room.integration.kotlintestapp.vo.BookAuthor
+import android.arch.persistence.room.integration.kotlintestapp.vo.NoArgClass
import android.arch.persistence.room.integration.kotlintestapp.vo.Publisher
-@Database(entities = arrayOf(Book::class, Author::class, Publisher::class, BookAuthor::class),
+@Database(entities = arrayOf(Book::class, Author::class, Publisher::class, BookAuthor::class,
+ NoArgClass::class),
version = 1)
abstract class TestDatabase : RoomDatabase() {
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/migration/MigrationKotlinTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/migration/MigrationKotlinTest.kt
index eb1a9b8..4265e19 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/migration/MigrationKotlinTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/migration/MigrationKotlinTest.kt
@@ -290,6 +290,8 @@
+ " (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`),"
+ " FOREIGN KEY(`name`) REFERENCES `Entity1`(`name`)"
+ " ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)")
+ database.execSQL("CREATE UNIQUE INDEX `index_entity1` ON "
+ + MigrationDbKotlin.Entity1.TABLE_NAME + " (`name`)")
}
}
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/NoArgClass.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/NoArgClass.kt
new file mode 100644
index 0000000..e1e1a7d
--- /dev/null
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/NoArgClass.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 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.arch.persistence.room.integration.kotlintestapp.vo
+
+import android.arch.persistence.room.Entity
+import android.arch.persistence.room.PrimaryKey
+
+/**
+ * just here to ensure that we handle no-arg constructors fine from kotlin.
+ */
+@Entity
+data class NoArgClass(@PrimaryKey var id: Long = 0, var class_name: String = "")
\ No newline at end of file
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/PKeyTestDatabase.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/PKeyTestDatabase.java
index b6339a8..63b9507 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/PKeyTestDatabase.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/PKeyTestDatabase.java
@@ -23,17 +23,19 @@
import android.arch.persistence.room.RoomDatabase;
import android.arch.persistence.room.integration.testapp.vo.IntAutoIncPKeyEntity;
import android.arch.persistence.room.integration.testapp.vo.IntegerAutoIncPKeyEntity;
+import android.arch.persistence.room.integration.testapp.vo.IntegerPKeyEntity;
import android.arch.persistence.room.integration.testapp.vo.ObjectPKeyEntity;
import java.util.List;
@Database(entities = {IntAutoIncPKeyEntity.class, IntegerAutoIncPKeyEntity.class,
- ObjectPKeyEntity.class}, version = 1,
+ ObjectPKeyEntity.class, IntegerPKeyEntity.class}, version = 1,
exportSchema = false)
public abstract class PKeyTestDatabase extends RoomDatabase {
public abstract IntPKeyDao intPKeyDao();
- public abstract IntegerPKeyDao integerPKeyDao();
+ public abstract IntegerAutoIncPKeyDao integerAutoIncPKeyDao();
public abstract ObjectPKeyDao objectPKeyDao();
+ public abstract IntegerPKeyDao integerPKeyDao();
@Dao
public interface IntPKeyDao {
@@ -53,7 +55,7 @@
}
@Dao
- public interface IntegerPKeyDao {
+ public interface IntegerAutoIncPKeyDao {
@Insert
void insertMe(IntegerAutoIncPKeyEntity item);
@@ -75,4 +77,13 @@
@Insert
void insertMe(ObjectPKeyEntity item);
}
+
+ @Dao
+ public interface IntegerPKeyDao {
+ @Insert
+ void insertMe(IntegerPKeyEntity item);
+
+ @Query("select * from IntegerPKeyEntity")
+ List<IntegerPKeyEntity> loadAll();
+ }
}
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/migration/MigrationTest.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/migration/MigrationTest.java
index 725d53f..7fe2bc9 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/migration/MigrationTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/migration/MigrationTest.java
@@ -318,6 +318,8 @@
+ " (`id` INTEGER NOT NULL, `name` TEXT COLLATE NOCASE, PRIMARY KEY(`id`),"
+ " FOREIGN KEY(`name`) REFERENCES `Entity1`(`name`)"
+ " ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)");
+ database.execSQL("CREATE UNIQUE INDEX `index_entity1` ON "
+ + MigrationDb.Entity1.TABLE_NAME + " (`name`)");
}
};
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/PrimaryKeyTest.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/PrimaryKeyTest.java
index 8d213f2..fda4373 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/PrimaryKeyTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/PrimaryKeyTest.java
@@ -26,6 +26,7 @@
import android.arch.persistence.room.integration.testapp.PKeyTestDatabase;
import android.arch.persistence.room.integration.testapp.vo.IntAutoIncPKeyEntity;
import android.arch.persistence.room.integration.testapp.vo.IntegerAutoIncPKeyEntity;
+import android.arch.persistence.room.integration.testapp.vo.IntegerPKeyEntity;
import android.arch.persistence.room.integration.testapp.vo.ObjectPKeyEntity;
import android.database.sqlite.SQLiteConstraintException;
import android.support.test.InstrumentationRegistry;
@@ -37,6 +38,7 @@
import org.junit.runner.RunWith;
import java.util.Arrays;
+import java.util.List;
@RunWith(AndroidJUnit4.class)
@SmallTest
@@ -53,8 +55,8 @@
public void integerTest() {
IntegerAutoIncPKeyEntity entity = new IntegerAutoIncPKeyEntity();
entity.data = "foo";
- mDatabase.integerPKeyDao().insertMe(entity);
- IntegerAutoIncPKeyEntity loaded = mDatabase.integerPKeyDao().getMe(1);
+ mDatabase.integerAutoIncPKeyDao().insertMe(entity);
+ IntegerAutoIncPKeyEntity loaded = mDatabase.integerAutoIncPKeyDao().getMe(1);
assertThat(loaded, notNullValue());
assertThat(loaded.data, is(entity.data));
}
@@ -64,8 +66,8 @@
IntegerAutoIncPKeyEntity entity = new IntegerAutoIncPKeyEntity();
entity.pKey = 0;
entity.data = "foo";
- mDatabase.integerPKeyDao().insertMe(entity);
- IntegerAutoIncPKeyEntity loaded = mDatabase.integerPKeyDao().getMe(0);
+ mDatabase.integerAutoIncPKeyDao().insertMe(entity);
+ IntegerAutoIncPKeyEntity loaded = mDatabase.integerAutoIncPKeyDao().getMe(0);
assertThat(loaded, notNullValue());
assertThat(loaded.data, is(entity.data));
}
@@ -102,8 +104,8 @@
public void getInsertedIdFromInteger() {
IntegerAutoIncPKeyEntity entity = new IntegerAutoIncPKeyEntity();
entity.data = "foo";
- final long id = mDatabase.integerPKeyDao().insertAndGetId(entity);
- assertThat(mDatabase.integerPKeyDao().getMe((int) id).data, is("foo"));
+ final long id = mDatabase.integerAutoIncPKeyDao().insertAndGetId(entity);
+ assertThat(mDatabase.integerAutoIncPKeyDao().getMe((int) id).data, is("foo"));
}
@Test
@@ -112,8 +114,9 @@
entity.data = "foo";
IntegerAutoIncPKeyEntity entity2 = new IntegerAutoIncPKeyEntity();
entity2.data = "foo2";
- final long[] ids = mDatabase.integerPKeyDao().insertAndGetIds(entity, entity2);
- assertThat(mDatabase.integerPKeyDao().loadDataById(ids), is(Arrays.asList("foo", "foo2")));
+ final long[] ids = mDatabase.integerAutoIncPKeyDao().insertAndGetIds(entity, entity2);
+ assertThat(mDatabase.integerAutoIncPKeyDao().loadDataById(ids),
+ is(Arrays.asList("foo", "foo2")));
}
@Test
@@ -129,4 +132,16 @@
assertNotNull("Was expecting an exception", throwable);
assertThat(throwable, instanceOf(SQLiteConstraintException.class));
}
+
+ @Test
+ public void insertNullPrimaryKeyForInteger() throws Exception {
+ IntegerPKeyEntity entity = new IntegerPKeyEntity();
+ entity.data = "data";
+ mDatabase.integerPKeyDao().insertMe(entity);
+
+ List<IntegerPKeyEntity> list = mDatabase.integerPKeyDao().loadAll();
+ assertThat(list.size(), is(1));
+ assertThat(list.get(0).data, is("data"));
+ assertNotNull(list.get(0).pKey);
+ }
}
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/IntegerPKeyEntity.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/IntegerPKeyEntity.java
new file mode 100644
index 0000000..cae1843
--- /dev/null
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/IntegerPKeyEntity.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 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.arch.persistence.room.integration.testapp.vo;
+
+import android.arch.persistence.room.Entity;
+import android.arch.persistence.room.PrimaryKey;
+
+@Entity
+public class IntegerPKeyEntity {
+ @PrimaryKey
+ public Integer pKey;
+ public String data;
+}
diff --git a/room/runtime/src/androidTest/java/android/arch/persistence/room/migration/TableInfoTest.java b/room/runtime/src/androidTest/java/android/arch/persistence/room/migration/TableInfoTest.java
index 8b7025b..d88c02f 100644
--- a/room/runtime/src/androidTest/java/android/arch/persistence/room/migration/TableInfoTest.java
+++ b/room/runtime/src/androidTest/java/android/arch/persistence/room/migration/TableInfoTest.java
@@ -37,6 +37,7 @@
import org.junit.runner.RunWith;
import java.io.IOException;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -179,6 +180,35 @@
Collections.<TableInfo.ForeignKey>emptySet())));
}
+ @Test
+ public void readIndices() {
+ mDb = createDatabase(
+ "CREATE TABLE foo (n INTEGER, indexed TEXT, unique_indexed TEXT,"
+ + "a INTEGER, b INTEGER);",
+ "CREATE INDEX foo_indexed ON foo(indexed);",
+ "CREATE UNIQUE INDEX foo_unique_indexed ON foo(unique_indexed COLLATE NOCASE"
+ + " DESC);",
+ "CREATE INDEX " + TableInfo.Index.DEFAULT_PREFIX + "foo_composite_indexed"
+ + " ON foo(a, b);"
+ );
+ TableInfo info = TableInfo.read(mDb, "foo");
+ assertThat(info, is(new TableInfo(
+ "foo",
+ toMap(new TableInfo.Column("n", "INTEGER", false, 0),
+ new TableInfo.Column("indexed", "TEXT", false, 0),
+ new TableInfo.Column("unique_indexed", "TEXT", false, 0),
+ new TableInfo.Column("a", "INTEGER", false, 0),
+ new TableInfo.Column("b", "INTEGER", false, 0)),
+ Collections.<TableInfo.ForeignKey>emptySet(),
+ toSet(new TableInfo.Index("index_foo_blahblah", false,
+ Arrays.asList("a", "b")),
+ new TableInfo.Index("foo_unique_indexed", true,
+ Arrays.asList("unique_indexed")),
+ new TableInfo.Index("foo_indexed", false,
+ Arrays.asList("indexed"))))
+ ));
+ }
+
private static Map<String, TableInfo.Column> toMap(TableInfo.Column... columns) {
Map<String, TableInfo.Column> result = new HashMap<>();
for (TableInfo.Column column : columns) {
@@ -187,6 +217,14 @@
return result;
}
+ private static <T> Set<T> toSet(T... ts) {
+ final HashSet<T> result = new HashSet<T>();
+ for (T t : ts) {
+ result.add(t);
+ }
+ return result;
+ }
+
@After
public void closeDb() throws IOException {
if (mDb != null && mDb.isOpen()) {
diff --git a/room/runtime/src/main/java/android/arch/persistence/room/util/TableInfo.java b/room/runtime/src/main/java/android/arch/persistence/room/util/TableInfo.java
index bcd2e9e..a115147 100644
--- a/room/runtime/src/main/java/android/arch/persistence/room/util/TableInfo.java
+++ b/room/runtime/src/main/java/android/arch/persistence/room/util/TableInfo.java
@@ -20,6 +20,7 @@
import android.database.Cursor;
import android.os.Build;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.annotation.RestrictTo;
import java.util.ArrayList;
@@ -29,6 +30,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
/**
* A data class that holds the information about a table.
@@ -56,11 +58,70 @@
public final Set<ForeignKey> foreignKeys;
+ /**
+ * Sometimes, Index information is not available (older versions). If so, we skip their
+ * verification.
+ */
+ @Nullable
+ public final Set<Index> indices;
+
@SuppressWarnings("unused")
- public TableInfo(String name, Map<String, Column> columns, Set<ForeignKey> foreignKeys) {
+ public TableInfo(String name, Map<String, Column> columns, Set<ForeignKey> foreignKeys,
+ Set<Index> indices) {
this.name = name;
this.columns = Collections.unmodifiableMap(columns);
this.foreignKeys = Collections.unmodifiableSet(foreignKeys);
+ this.indices = indices == null ? null : Collections.unmodifiableSet(indices);
+ }
+
+ /**
+ * For backward compatibility with dbs created with older versions.
+ */
+ @SuppressWarnings("unused")
+ public TableInfo(String name, Map<String, Column> columns, Set<ForeignKey> foreignKeys) {
+ this(name, columns, foreignKeys, Collections.<Index>emptySet());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ TableInfo tableInfo = (TableInfo) o;
+
+ if (name != null ? !name.equals(tableInfo.name) : tableInfo.name != null) return false;
+ if (columns != null ? !columns.equals(tableInfo.columns) : tableInfo.columns != null) {
+ return false;
+ }
+ if (foreignKeys != null ? !foreignKeys.equals(tableInfo.foreignKeys)
+ : tableInfo.foreignKeys != null) {
+ return false;
+ }
+ if (indices == null || tableInfo.indices == null) {
+ // if one us is missing index information, seems like we couldn't acquire the
+ // information so we better skip.
+ return true;
+ }
+ return indices.equals(tableInfo.indices);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = name != null ? name.hashCode() : 0;
+ result = 31 * result + (columns != null ? columns.hashCode() : 0);
+ result = 31 * result + (foreignKeys != null ? foreignKeys.hashCode() : 0);
+ // skip index, it is not reliable for comparison.
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "TableInfo{"
+ + "name='" + name + '\''
+ + ", columns=" + columns
+ + ", foreignKeys=" + foreignKeys
+ + ", indices=" + indices
+ + '}';
}
/**
@@ -74,7 +135,8 @@
public static TableInfo read(SupportSQLiteDatabase database, String tableName) {
Map<String, Column> columns = readColumns(database, tableName);
Set<ForeignKey> foreignKeys = readForeignKeys(database, tableName);
- return new TableInfo(tableName, columns, foreignKeys);
+ Set<Index> indices = readIndices(database, tableName);
+ return new TableInfo(tableName, columns, foreignKeys, indices);
}
private static Set<ForeignKey> readForeignKeys(SupportSQLiteDatabase database,
@@ -167,34 +229,74 @@
return columns;
}
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- TableInfo tableInfo = (TableInfo) o;
-
- if (!name.equals(tableInfo.name)) return false;
- //noinspection SimplifiableIfStatement
- if (!columns.equals(tableInfo.columns)) return false;
- return foreignKeys.equals(tableInfo.foreignKeys);
+ /**
+ * @return null if we cannot read the indices due to older sqlite implementations.
+ */
+ @Nullable
+ private static Set<Index> readIndices(SupportSQLiteDatabase database, String tableName) {
+ Cursor cursor = database.query("PRAGMA index_list(`" + tableName + "`)");
+ try {
+ final int nameColumnIndex = cursor.getColumnIndex("name");
+ final int originColumnIndex = cursor.getColumnIndex("origin");
+ final int uniqueIndex = cursor.getColumnIndex("unique");
+ if (nameColumnIndex == -1 || originColumnIndex == -1 || uniqueIndex == -1) {
+ // we cannot read them so better not validate any index.
+ return null;
+ }
+ HashSet<Index> indices = new HashSet<>();
+ while (cursor.moveToNext()) {
+ String origin = cursor.getString(originColumnIndex);
+ if (!"c".equals(origin)) {
+ // Ignore auto-created indices
+ continue;
+ }
+ String name = cursor.getString(nameColumnIndex);
+ boolean unique = cursor.getInt(uniqueIndex) == 1;
+ Index index = readIndex(database, name, unique);
+ if (index == null) {
+ // we cannot read it properly so better not read it
+ return null;
+ }
+ indices.add(index);
+ }
+ return indices;
+ } finally {
+ cursor.close();
+ }
}
- @Override
- public int hashCode() {
- int result = name.hashCode();
- result = 31 * result + columns.hashCode();
- result = 31 * result + foreignKeys.hashCode();
- return result;
- }
+ /**
+ * @return null if we cannot read the index due to older sqlite implementations.
+ */
+ @Nullable
+ private static Index readIndex(SupportSQLiteDatabase database, String name, boolean unique) {
+ Cursor cursor = database.query("PRAGMA index_xinfo(`" + name + "`)");
+ try {
+ final int seqnoColumnIndex = cursor.getColumnIndex("seqno");
+ final int cidColumnIndex = cursor.getColumnIndex("cid");
+ final int nameColumnIndex = cursor.getColumnIndex("name");
+ if (seqnoColumnIndex == -1 || cidColumnIndex == -1 || nameColumnIndex == -1) {
+ // we cannot read them so better not validate any index.
+ return null;
+ }
+ final TreeMap<Integer, String> results = new TreeMap<>();
- @Override
- public String toString() {
- return "TableInfo{"
- + "name='" + name + '\''
- + ", columns=" + columns
- + ", foreignKeys=" + foreignKeys
- + '}';
+ while (cursor.moveToNext()) {
+ int cid = cursor.getInt(cidColumnIndex);
+ if (cid < 0) {
+ // Ignore SQLite row ID
+ continue;
+ }
+ int seq = cursor.getInt(seqnoColumnIndex);
+ String columnName = cursor.getString(nameColumnIndex);
+ results.put(seq, columnName);
+ }
+ final List<String> columns = new ArrayList<>(results.size());
+ columns.addAll(results.values());
+ return new Index(name, unique, columns);
+ } finally {
+ cursor.close();
+ }
}
/**
@@ -379,4 +481,65 @@
}
}
}
+
+ /**
+ * Holds the information about an SQLite index
+ *
+ * @hide
+ */
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ public static class Index {
+ // should match the value in Index.kt
+ public static final String DEFAULT_PREFIX = "index_";
+ public final String name;
+ public final boolean unique;
+ public final List<String> columns;
+
+ public Index(String name, boolean unique, List<String> columns) {
+ this.name = name;
+ this.unique = unique;
+ this.columns = columns;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Index index = (Index) o;
+ if (unique != index.unique) {
+ return false;
+ }
+ if (!columns.equals(index.columns)) {
+ return false;
+ }
+ if (name.startsWith(Index.DEFAULT_PREFIX)) {
+ return index.name.startsWith(Index.DEFAULT_PREFIX);
+ } else {
+ return name.equals(index.name);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ if (name.startsWith(DEFAULT_PREFIX)) {
+ result = DEFAULT_PREFIX.hashCode();
+ } else {
+ result = name.hashCode();
+ }
+ result = 31 * result + (unique ? 1 : 0);
+ result = 31 * result + columns.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "Index{"
+ + "name='" + name + '\''
+ + ", unique=" + unique
+ + ", columns=" + columns
+ + '}';
+ }
+ }
}
diff --git a/room/testing/src/main/java/android/arch/persistence/room/testing/MigrationTestHelper.java b/room/testing/src/main/java/android/arch/persistence/room/testing/MigrationTestHelper.java
index a27fe0f..18e0a14 100644
--- a/room/testing/src/main/java/android/arch/persistence/room/testing/MigrationTestHelper.java
+++ b/room/testing/src/main/java/android/arch/persistence/room/testing/MigrationTestHelper.java
@@ -29,6 +29,7 @@
import android.arch.persistence.room.migration.bundle.EntityBundle;
import android.arch.persistence.room.migration.bundle.FieldBundle;
import android.arch.persistence.room.migration.bundle.ForeignKeyBundle;
+import android.arch.persistence.room.migration.bundle.IndexBundle;
import android.arch.persistence.room.migration.bundle.SchemaBundle;
import android.arch.persistence.room.util.TableInfo;
import android.content.Context;
@@ -285,7 +286,19 @@
private static TableInfo toTableInfo(EntityBundle entityBundle) {
return new TableInfo(entityBundle.getTableName(), toColumnMap(entityBundle),
- toForeignKeys(entityBundle.getForeignKeys()));
+ toForeignKeys(entityBundle.getForeignKeys()), toIndices(entityBundle.getIndices()));
+ }
+
+ private static Set<TableInfo.Index> toIndices(List<IndexBundle> indices) {
+ if (indices == null) {
+ return Collections.emptySet();
+ }
+ Set<TableInfo.Index> result = new HashSet<>();
+ for (IndexBundle bundle : indices) {
+ result.add(new TableInfo.Index(bundle.getName(), bundle.isUnique(),
+ bundle.getColumnNames()));
+ }
+ return result;
}
private static Set<TableInfo.ForeignKey> toForeignKeys(
diff --git a/samples/SupportLeanbackDemos/AndroidManifest.xml b/samples/SupportLeanbackDemos/AndroidManifest.xml
index 7b8b946..f8a1646 100644
--- a/samples/SupportLeanbackDemos/AndroidManifest.xml
+++ b/samples/SupportLeanbackDemos/AndroidManifest.xml
@@ -115,25 +115,9 @@
android:launchMode="singleTask"
android:exported="true" />
- <activity android:name="PlaybackOverlayActivity"
- android:configChanges=
- "screenSize|smallestScreenSize|screenLayout|orientation"
- android:resizeableActivity="true"
- android:supportsPictureInPicture="true"
- android:launchMode="singleTask"
- android:exported="true" />
-
- <activity android:name="PlaybackOverlaySupportActivity"
- android:configChanges=
- "screenSize|smallestScreenSize|screenLayout|orientation"
- android:resizeableActivity="true"
- android:supportsPictureInPicture="true"
- android:launchMode="singleTask"
- android:exported="true" />
-
<activity android:name="VerticalGridActivity"
- android:theme="@style/Theme.Example.Leanback.VerticalGrid"
- android:exported="true" />
+ android:theme="@style/Theme.Example.Leanback.VerticalGrid"
+ android:exported="true" />
<activity android:name="VerticalGridSupportActivity"
android:theme="@style/Theme.Example.Leanback.VerticalGrid"
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsFragment.java
index bb282f4..c8177b6 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsFragment.java
@@ -116,7 +116,7 @@
actions.clear(ACTION_RENT);
dor.setItem(mPhotoItem.getTitle() + "(Rented)");
} else if (action.getId() == ACTION_PLAY) {
- Intent intent = new Intent(context, PlaybackOverlayActivity.class);
+ Intent intent = new Intent(context, PlaybackActivity.class);
getActivity().startActivity(intent);
}
}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsSupportFragment.java
index 8e7a127..0f15590 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsSupportFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsSupportFragment.java
@@ -119,7 +119,7 @@
actions.clear(ACTION_RENT);
dor.setItem(mPhotoItem.getTitle() + "(Rented)");
} else if (action.getId() == ACTION_PLAY) {
- Intent intent = new Intent(context, PlaybackOverlaySupportActivity.class);
+ Intent intent = new Intent(context, PlaybackSupportActivity.class);
getActivity().startActivity(intent);
}
}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/MainActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/MainActivity.java
index 116003f..15a0769 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/MainActivity.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/MainActivity.java
@@ -121,10 +121,6 @@
R.string.playback_description);
addAction(actions, PlaybackTransportControlSupportActivity.class,
R.string.playback_support, R.string.playback_support_description);
- addAction(actions, PlaybackOverlayActivity.class, R.string.playbackoverlay,
- R.string.playbackoverlay_description);
- addAction(actions, PlaybackOverlaySupportActivity.class,
- R.string.playbackoverlay_support, R.string.playbackoverlay_support_description);
addAction(actions, VideoActivity.class, R.string.video_playback,
R.string.playback_description);
addAction(actions, VideoSupportActivity.class, R.string.video_playback_support,
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java
index 4d5b4cc..0afe524 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java
@@ -16,6 +16,7 @@
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -174,7 +175,7 @@
mDetailsBackground.switchToVideo();
}
} else {
- Intent intent = new Intent(context, PlaybackOverlayActivity.class);
+ Intent intent = new Intent(context, PlaybackActivity.class);
getActivity().startActivity(intent);
}
} else if (action.getId() == ACTION_RENT) {
@@ -189,14 +190,14 @@
setupMainVideo();
mDetailsBackground.switchToVideo();
} else {
- Intent intent = new Intent(context, PlaybackOverlayActivity.class);
+ Intent intent = new Intent(context, PlaybackActivity.class);
getActivity().startActivity(intent);
}
} else if (action.getId() == ACTION_PLAY) {
if (TEST_BACKGROUND_PLAYER) {
mDetailsBackground.switchToVideo();
} else {
- Intent intent = new Intent(context, PlaybackOverlayActivity.class);
+ Intent intent = new Intent(context, PlaybackActivity.class);
getActivity().startActivity(intent);
}
}
@@ -306,6 +307,10 @@
adapter.set(ACTION_BUY, mActionBuy);
break;
}
+ // one line text with icon
+ Drawable d = ResourcesCompat.getDrawable(context.getResources(),
+ R.drawable.ic_action_a, context.getTheme());
+ adapter.set(202, new Action(202, "Top", null, d));
dor.setActionsAdapter(adapter);
mRowsAdapter.add(0, dor);
setSelectedPosition(0, true);
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java
index db7d594..6002cf3 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -177,7 +178,7 @@
mDetailsBackground.switchToVideo();
}
} else {
- Intent intent = new Intent(context, PlaybackOverlaySupportActivity.class);
+ Intent intent = new Intent(context, PlaybackSupportActivity.class);
getActivity().startActivity(intent);
}
} else if (action.getId() == ACTION_RENT) {
@@ -192,14 +193,14 @@
setupMainVideo();
mDetailsBackground.switchToVideo();
} else {
- Intent intent = new Intent(context, PlaybackOverlaySupportActivity.class);
+ Intent intent = new Intent(context, PlaybackSupportActivity.class);
getActivity().startActivity(intent);
}
} else if (action.getId() == ACTION_PLAY) {
if (TEST_BACKGROUND_PLAYER) {
mDetailsBackground.switchToVideo();
} else {
- Intent intent = new Intent(context, PlaybackOverlaySupportActivity.class);
+ Intent intent = new Intent(context, PlaybackSupportActivity.class);
getActivity().startActivity(intent);
}
}
@@ -309,6 +310,10 @@
adapter.set(ACTION_BUY, mActionBuy);
break;
}
+ // one line text with icon
+ Drawable d = ResourcesCompat.getDrawable(context.getResources(),
+ R.drawable.ic_action_a, context.getTheme());
+ adapter.set(202, new Action(202, "Top", null, d));
dor.setActionsAdapter(adapter);
mRowsAdapter.add(0, dor);
setSelectedPosition(0, true);
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackControlHelper.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackControlHelper.java
deleted file mode 100644
index e0becaa..0000000
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackControlHelper.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * 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 com.example.android.leanback;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.support.v17.leanback.app.PlaybackControlGlue;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.ArrayObjectAdapter;
-import android.support.v17.leanback.widget.ControlButtonPresenterSelector;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.PresenterSelector;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.view.KeyEvent;
-import android.view.View;
-import android.widget.Toast;
-
-abstract class PlaybackControlHelper extends PlaybackControlGlue {
- /**
- * Change the location of the thumbs up/down controls
- */
- private static final boolean THUMBS_PRIMARY = true;
-
- private static final String FAUX_TITLE = "A short song of silence";
- private static final String FAUX_SUBTITLE = "2014";
- private static final int FAUX_DURATION = 33 * 1000;
-
- // These should match the playback service FF behavior
- private static int[] sFastForwardSpeeds = { 2, 3, 4, 5 };
-
- private boolean mIsPlaying;
- private int mSpeed = PlaybackControlGlue.PLAYBACK_SPEED_PAUSED;
- private long mStartTime;
- private long mStartPosition = 0;
-
- private PlaybackControlsRow.RepeatAction mRepeatAction;
- private PlaybackControlsRow.ThumbsUpAction mThumbsUpAction;
- private PlaybackControlsRow.ThumbsDownAction mThumbsDownAction;
- private PlaybackControlsRow.PictureInPictureAction mPipAction;
-
- private Handler mHandler = new Handler();
- // simulating whether the media is yet prepared and ready to play
- private boolean mInitialized = true;
-
- private final Runnable mUpdateProgressRunnable = new Runnable() {
- @Override
- public void run() {
- updateProgress();
- mHandler.postDelayed(this, getUpdatePeriod());
- }
- };
-
- PlaybackControlHelper(Context context, PlaybackOverlayFragment fragment) {
- super(context, fragment, sFastForwardSpeeds);
- mThumbsUpAction = new PlaybackControlsRow.ThumbsUpAction(context);
- mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsUpAction.INDEX_OUTLINE);
- mThumbsDownAction = new PlaybackControlsRow.ThumbsDownAction(context);
- mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsDownAction.INDEX_OUTLINE);
- mRepeatAction = new PlaybackControlsRow.RepeatAction(context);
- mPipAction = new PlaybackControlsRow.PictureInPictureAction(context);
- }
-
- @Override
- public PlaybackControlsRowPresenter createControlsRowAndPresenter() {
- PlaybackControlsRowPresenter presenter = super.createControlsRowAndPresenter();
-
- ArrayObjectAdapter adapter = new ArrayObjectAdapter(new ControlButtonPresenterSelector());
- getControlsRow().setSecondaryActionsAdapter(adapter);
- if (!THUMBS_PRIMARY) {
- adapter.add(mThumbsDownAction);
- }
- if (android.os.Build.VERSION.SDK_INT > 23) {
- adapter.add(mPipAction);
- }
- adapter.add(mRepeatAction);
- if (!THUMBS_PRIMARY) {
- adapter.add(mThumbsUpAction);
- }
-
- return presenter;
- }
-
- @Override
- protected SparseArrayObjectAdapter createPrimaryActionsAdapter(
- PresenterSelector presenterSelector) {
- SparseArrayObjectAdapter adapter = new SparseArrayObjectAdapter(presenterSelector);
- if (THUMBS_PRIMARY) {
- adapter.set(PlaybackControlGlue.ACTION_CUSTOM_LEFT_FIRST, mThumbsUpAction);
- adapter.set(PlaybackControlGlue.ACTION_CUSTOM_RIGHT_FIRST, mThumbsDownAction);
- }
- return adapter;
- }
-
- @Override
- public void onActionClicked(Action action) {
- if (shouldDispatchAction(action)) {
- dispatchAction(action);
- return;
- }
- super.onActionClicked(action);
- }
-
- @Override
- public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
- if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
- Action action = getControlsRow().getActionForKeyCode(keyEvent.getKeyCode());
- if (shouldDispatchAction(action)) {
- dispatchAction(action);
- return true;
- }
- }
- return super.onKey(view, keyCode, keyEvent);
- }
-
- private boolean shouldDispatchAction(Action action) {
- return action == mRepeatAction || action == mThumbsUpAction || action == mThumbsDownAction;
- }
-
- private void dispatchAction(Action action) {
- Toast.makeText(getContext(), action.toString(), Toast.LENGTH_SHORT).show();
- PlaybackControlsRow.MultiAction multiAction = (PlaybackControlsRow.MultiAction) action;
- multiAction.nextIndex();
- notifyActionChanged(multiAction);
- }
-
- private void notifyActionChanged(PlaybackControlsRow.MultiAction action) {
- int index;
- index = getPrimaryActionsAdapter().indexOf(action);
- if (index >= 0) {
- getPrimaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
- } else {
- index = getSecondaryActionsAdapter().indexOf(action);
- if (index >= 0) {
- getSecondaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
- }
- }
- }
-
- private SparseArrayObjectAdapter getPrimaryActionsAdapter() {
- return (SparseArrayObjectAdapter) getControlsRow().getPrimaryActionsAdapter();
- }
-
- private ArrayObjectAdapter getSecondaryActionsAdapter() {
- return (ArrayObjectAdapter) getControlsRow().getSecondaryActionsAdapter();
- }
-
- @Override
- public boolean hasValidMedia() {
- return mInitialized;
- }
-
- @Override
- public boolean isMediaPlaying() {
- return mIsPlaying;
- }
-
- @Override
- public CharSequence getMediaTitle() {
- return FAUX_TITLE;
- }
-
- @Override
- public CharSequence getMediaSubtitle() {
- return FAUX_SUBTITLE;
- }
-
- @Override
- public int getMediaDuration() {
- return mInitialized ? FAUX_DURATION : 0;
- }
-
- @Override
- public Drawable getMediaArt() {
- return null;
- }
-
- @Override
- public long getSupportedActions() {
- return PlaybackControlGlue.ACTION_PLAY_PAUSE |
- PlaybackControlGlue.ACTION_FAST_FORWARD |
- PlaybackControlGlue.ACTION_REWIND;
- }
-
- @Override
- public int getCurrentSpeedId() {
- return mSpeed;
- }
-
- @Override
- public int getCurrentPosition() {
- int speed;
- if (mSpeed == PlaybackControlGlue.PLAYBACK_SPEED_PAUSED) {
- speed = 0;
- } else if (mSpeed == PlaybackControlGlue.PLAYBACK_SPEED_NORMAL) {
- speed = 1;
- } else if (mSpeed >= PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0) {
- int index = mSpeed - PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0;
- speed = getFastForwardSpeeds()[index];
- } else if (mSpeed <= -PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0) {
- int index = -mSpeed - PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0;
- speed = -getRewindSpeeds()[index];
- } else {
- return -1;
- }
- long position = mStartPosition +
- (System.currentTimeMillis() - mStartTime) * speed;
- if (position > getMediaDuration()) {
- position = getMediaDuration();
- onPlaybackComplete(true);
- } else if (position < 0) {
- position = 0;
- onPlaybackComplete(false);
- }
- return (int) position;
- }
-
- void onPlaybackComplete(final boolean ended) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- if (mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.INDEX_NONE) {
- pausePlayback();
- } else {
- startPlayback(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL);
- }
- mStartPosition = 0;
- onStateChanged();
- }
- });
- }
-
- @Override
- protected void startPlayback(int speed) {
- if (speed == mSpeed) {
- return;
- }
- mStartPosition = getCurrentPosition();
- mSpeed = speed;
- mIsPlaying = true;
- mStartTime = System.currentTimeMillis();
- }
-
- @Override
- protected void pausePlayback() {
- if (mSpeed == PlaybackControlGlue.PLAYBACK_SPEED_PAUSED) {
- return;
- }
- mStartPosition = getCurrentPosition();
- mSpeed = PlaybackControlGlue.PLAYBACK_SPEED_PAUSED;
- mIsPlaying = false;
- }
-
- @Override
- protected void skipToNext() {
- // Not supported
- }
-
- @Override
- protected void skipToPrevious() {
- // Not supported
- }
-
- @Override
- public void enableProgressUpdating(boolean enable) {
- mHandler.removeCallbacks(mUpdateProgressRunnable);
- if (enable) {
- mUpdateProgressRunnable.run();
- }
- }
-
- public boolean isInitialized() {
- return mInitialized;
- }
-
- public void setInitialized(boolean initialized) {
- if (mInitialized != initialized) {
- mInitialized = initialized;
- onMetadataChanged();
- onStateChanged();
- }
- }
-};
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackControlSupportHelper.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackControlSupportHelper.java
deleted file mode 100644
index 4ae5b37..0000000
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackControlSupportHelper.java
+++ /dev/null
@@ -1,301 +0,0 @@
-// CHECKSTYLE:OFF Generated code
-/* This file is auto-generated from PlaybackControlHelper.java. DO NOT MODIFY. */
-
-/*
- * 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 com.example.android.leanback;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.support.v17.leanback.app.PlaybackControlSupportGlue;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.ArrayObjectAdapter;
-import android.support.v17.leanback.widget.ControlButtonPresenterSelector;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.PresenterSelector;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.view.KeyEvent;
-import android.view.View;
-import android.widget.Toast;
-
-abstract class PlaybackControlSupportHelper extends PlaybackControlSupportGlue {
- /**
- * Change the location of the thumbs up/down controls
- */
- private static final boolean THUMBS_PRIMARY = true;
-
- private static final String FAUX_TITLE = "A short song of silence";
- private static final String FAUX_SUBTITLE = "2014";
- private static final int FAUX_DURATION = 33 * 1000;
-
- // These should match the playback service FF behavior
- private static int[] sFastForwardSpeeds = { 2, 3, 4, 5 };
-
- private boolean mIsPlaying;
- private int mSpeed = PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED;
- private long mStartTime;
- private long mStartPosition = 0;
-
- private PlaybackControlsRow.RepeatAction mRepeatAction;
- private PlaybackControlsRow.ThumbsUpAction mThumbsUpAction;
- private PlaybackControlsRow.ThumbsDownAction mThumbsDownAction;
- private PlaybackControlsRow.PictureInPictureAction mPipAction;
-
- private Handler mHandler = new Handler();
- // simulating whether the media is yet prepared and ready to play
- private boolean mInitialized = true;
-
- private final Runnable mUpdateProgressRunnable = new Runnable() {
- @Override
- public void run() {
- updateProgress();
- mHandler.postDelayed(this, getUpdatePeriod());
- }
- };
-
- PlaybackControlSupportHelper(Context context, PlaybackOverlaySupportFragment fragment) {
- super(context, fragment, sFastForwardSpeeds);
- mThumbsUpAction = new PlaybackControlsRow.ThumbsUpAction(context);
- mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsUpAction.INDEX_OUTLINE);
- mThumbsDownAction = new PlaybackControlsRow.ThumbsDownAction(context);
- mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsDownAction.INDEX_OUTLINE);
- mRepeatAction = new PlaybackControlsRow.RepeatAction(context);
- mPipAction = new PlaybackControlsRow.PictureInPictureAction(context);
- }
-
- @Override
- public PlaybackControlsRowPresenter createControlsRowAndPresenter() {
- PlaybackControlsRowPresenter presenter = super.createControlsRowAndPresenter();
-
- ArrayObjectAdapter adapter = new ArrayObjectAdapter(new ControlButtonPresenterSelector());
- getControlsRow().setSecondaryActionsAdapter(adapter);
- if (!THUMBS_PRIMARY) {
- adapter.add(mThumbsDownAction);
- }
- if (android.os.Build.VERSION.SDK_INT > 23) {
- adapter.add(mPipAction);
- }
- adapter.add(mRepeatAction);
- if (!THUMBS_PRIMARY) {
- adapter.add(mThumbsUpAction);
- }
-
- return presenter;
- }
-
- @Override
- protected SparseArrayObjectAdapter createPrimaryActionsAdapter(
- PresenterSelector presenterSelector) {
- SparseArrayObjectAdapter adapter = new SparseArrayObjectAdapter(presenterSelector);
- if (THUMBS_PRIMARY) {
- adapter.set(PlaybackControlSupportGlue.ACTION_CUSTOM_LEFT_FIRST, mThumbsUpAction);
- adapter.set(PlaybackControlSupportGlue.ACTION_CUSTOM_RIGHT_FIRST, mThumbsDownAction);
- }
- return adapter;
- }
-
- @Override
- public void onActionClicked(Action action) {
- if (shouldDispatchAction(action)) {
- dispatchAction(action);
- return;
- }
- super.onActionClicked(action);
- }
-
- @Override
- public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
- if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
- Action action = getControlsRow().getActionForKeyCode(keyEvent.getKeyCode());
- if (shouldDispatchAction(action)) {
- dispatchAction(action);
- return true;
- }
- }
- return super.onKey(view, keyCode, keyEvent);
- }
-
- private boolean shouldDispatchAction(Action action) {
- return action == mRepeatAction || action == mThumbsUpAction || action == mThumbsDownAction;
- }
-
- private void dispatchAction(Action action) {
- Toast.makeText(getContext(), action.toString(), Toast.LENGTH_SHORT).show();
- PlaybackControlsRow.MultiAction multiAction = (PlaybackControlsRow.MultiAction) action;
- multiAction.nextIndex();
- notifyActionChanged(multiAction);
- }
-
- private void notifyActionChanged(PlaybackControlsRow.MultiAction action) {
- int index;
- index = getPrimaryActionsAdapter().indexOf(action);
- if (index >= 0) {
- getPrimaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
- } else {
- index = getSecondaryActionsAdapter().indexOf(action);
- if (index >= 0) {
- getSecondaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
- }
- }
- }
-
- private SparseArrayObjectAdapter getPrimaryActionsAdapter() {
- return (SparseArrayObjectAdapter) getControlsRow().getPrimaryActionsAdapter();
- }
-
- private ArrayObjectAdapter getSecondaryActionsAdapter() {
- return (ArrayObjectAdapter) getControlsRow().getSecondaryActionsAdapter();
- }
-
- @Override
- public boolean hasValidMedia() {
- return mInitialized;
- }
-
- @Override
- public boolean isMediaPlaying() {
- return mIsPlaying;
- }
-
- @Override
- public CharSequence getMediaTitle() {
- return FAUX_TITLE;
- }
-
- @Override
- public CharSequence getMediaSubtitle() {
- return FAUX_SUBTITLE;
- }
-
- @Override
- public int getMediaDuration() {
- return mInitialized ? FAUX_DURATION : 0;
- }
-
- @Override
- public Drawable getMediaArt() {
- return null;
- }
-
- @Override
- public long getSupportedActions() {
- return PlaybackControlSupportGlue.ACTION_PLAY_PAUSE |
- PlaybackControlSupportGlue.ACTION_FAST_FORWARD |
- PlaybackControlSupportGlue.ACTION_REWIND;
- }
-
- @Override
- public int getCurrentSpeedId() {
- return mSpeed;
- }
-
- @Override
- public int getCurrentPosition() {
- int speed;
- if (mSpeed == PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED) {
- speed = 0;
- } else if (mSpeed == PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL) {
- speed = 1;
- } else if (mSpeed >= PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0) {
- int index = mSpeed - PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0;
- speed = getFastForwardSpeeds()[index];
- } else if (mSpeed <= -PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0) {
- int index = -mSpeed - PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0;
- speed = -getRewindSpeeds()[index];
- } else {
- return -1;
- }
- long position = mStartPosition +
- (System.currentTimeMillis() - mStartTime) * speed;
- if (position > getMediaDuration()) {
- position = getMediaDuration();
- onPlaybackComplete(true);
- } else if (position < 0) {
- position = 0;
- onPlaybackComplete(false);
- }
- return (int) position;
- }
-
- void onPlaybackComplete(final boolean ended) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- if (mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.INDEX_NONE) {
- pausePlayback();
- } else {
- startPlayback(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL);
- }
- mStartPosition = 0;
- onStateChanged();
- }
- });
- }
-
- @Override
- protected void startPlayback(int speed) {
- if (speed == mSpeed) {
- return;
- }
- mStartPosition = getCurrentPosition();
- mSpeed = speed;
- mIsPlaying = true;
- mStartTime = System.currentTimeMillis();
- }
-
- @Override
- protected void pausePlayback() {
- if (mSpeed == PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED) {
- return;
- }
- mStartPosition = getCurrentPosition();
- mSpeed = PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED;
- mIsPlaying = false;
- }
-
- @Override
- protected void skipToNext() {
- // Not supported
- }
-
- @Override
- protected void skipToPrevious() {
- // Not supported
- }
-
- @Override
- public void enableProgressUpdating(boolean enable) {
- mHandler.removeCallbacks(mUpdateProgressRunnable);
- if (enable) {
- mUpdateProgressRunnable.run();
- }
- }
-
- public boolean isInitialized() {
- return mInitialized;
- }
-
- public void setInitialized(boolean initialized) {
- if (mInitialized != initialized) {
- mInitialized = initialized;
- onMetadataChanged();
- onStateChanged();
- }
- }
-};
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayActivity.java
deleted file mode 100644
index 764b169..0000000
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayActivity.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.example.android.leanback;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PlaybackOverlayActivity extends Activity {
- private List<PictureInPictureListener> mListeners = new ArrayList<>();
-
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.playback_controls);
- }
-
- @Override
- public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
- for (PictureInPictureListener listener : mListeners) {
- listener.onPictureInPictureModeChanged(isInPictureInPictureMode);
- }
- }
-
- public void registerPictureInPictureListener(PictureInPictureListener listener) {
- mListeners.add(listener);
- }
-
- public void unregisterPictureInPictureListener(PictureInPictureListener listener) {
- mListeners.remove(listener);
- }
-
- public interface PictureInPictureListener {
- void onPictureInPictureModeChanged(boolean isInPictureInPictureMode);
- }
-}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
deleted file mode 100644
index 369c464..0000000
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.example.android.leanback;
-
-import android.content.Context;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.ArrayObjectAdapter;
-import android.support.v17.leanback.widget.ClassPresenterSelector;
-import android.support.v17.leanback.widget.HeaderItem;
-import android.support.v17.leanback.widget.ListRow;
-import android.support.v17.leanback.widget.ListRowPresenter;
-import android.support.v17.leanback.widget.OnItemViewClickedListener;
-import android.support.v17.leanback.widget.OnItemViewSelectedListener;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.Row;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.util.Log;
-
-public class PlaybackOverlayFragment
- extends android.support.v17.leanback.app.PlaybackOverlayFragment
- implements PlaybackOverlayActivity.PictureInPictureListener {
- private static final String TAG = "leanback.PlaybackControlsFragment";
-
- /**
- * Change this to choose a different overlay background.
- */
- private static final int BACKGROUND_TYPE = PlaybackOverlayFragment.BG_LIGHT;
-
- /**
- * Change the number of related content rows.
- */
- private static final int RELATED_CONTENT_ROWS = 3;
-
- /**
- * Change this to select hidden
- */
- private static final boolean SECONDARY_HIDDEN = false;
-
- private static final int ROW_CONTROLS = 0;
-
- private PlaybackControlHelper mGlue;
- final Handler mHandler = new Handler();
-
- // Artificial delay to simulate a media being prepared. The onRowChanged callback should be
- // called and the playback row UI should be updated after this delay.
- private static final int MEDIA_PREPARATION_DELAY = 500;
-
- private OnItemViewClickedListener mOnItemViewClickedListener = new OnItemViewClickedListener() {
- @Override
- public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
- RowPresenter.ViewHolder rowViewHolder, Row row) {
- Log.i(TAG, "onItemClicked: " + item + " row " + row);
- if (item instanceof Action) {
- mGlue.onActionClicked((Action) item);
- }
- }
- };
-
- private OnItemViewSelectedListener mOnItemViewSelectedListener =
- new OnItemViewSelectedListener() {
- @Override
- public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
- RowPresenter.ViewHolder rowViewHolder, Row row) {
- Log.i(TAG, "onItemSelected: " + item + " row " + row);
- }
- };
-
- @Override
- public SparseArrayObjectAdapter getAdapter() {
- return (SparseArrayObjectAdapter) super.getAdapter();
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- Log.i(TAG, "onCreate");
- super.onCreate(savedInstanceState);
-
- setBackgroundType(BACKGROUND_TYPE);
- setOnItemViewSelectedListener(mOnItemViewSelectedListener);
-
- createComponents(getActivity());
- }
-
- private void createComponents(Context context) {
- mGlue = new PlaybackControlHelper(context, this) {
- @Override
- public int getUpdatePeriod() {
- long totalTime = getControlsRow().getDuration();
- if (getView() == null || getView().getWidth() == 0 || totalTime <= 0) {
- return 1000;
- }
- return 16;
- }
-
- @Override
- protected void onRowChanged(PlaybackControlsRow row) {
- if (getAdapter() == null) {
- return;
- }
- int index = getAdapter().indexOf(row);
- if (index >= 0) {
- getAdapter().notifyArrayItemRangeChanged(index, 1);
- }
- }
-
- @Override
- public void onActionClicked(Action action) {
- if (action.getId() == R.id.lb_control_picture_in_picture) {
- if (Build.VERSION.SDK_INT >= 24) {
- getActivity().enterPictureInPictureMode();
- }
- return;
- }
- super.onActionClicked(action);
- }
- };
-
- mGlue.setInitialized(false);
- mHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- mGlue.setInitialized(true);
- }
- }, MEDIA_PREPARATION_DELAY);
- mGlue.setOnItemViewClickedListener(mOnItemViewClickedListener);
-
- PlaybackControlsRowPresenter playbackControlsRowPresenter =
- mGlue.createControlsRowAndPresenter();
- playbackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
- ClassPresenterSelector selector = new ClassPresenterSelector();
- selector.addClassPresenter(ListRow.class, new ListRowPresenter());
- selector.addClassPresenter(PlaybackControlsRow.class, playbackControlsRowPresenter);
-
- setAdapter(new SparseArrayObjectAdapter(selector));
-
- // Add the controls row
- getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
-
- // Add related content rows
- for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
- ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new StringPresenter());
- listRowAdapter.add("Some related content");
- listRowAdapter.add("Other related content");
- HeaderItem header = new HeaderItem(i, "Row " + i);
- getAdapter().set(ROW_CONTROLS + 1 + i, new ListRow(header, listRowAdapter));
- }
-
- }
-
- @Override
- public void onStart() {
- super.onStart();
- mGlue.setFadingEnabled(true);
- mGlue.enableProgressUpdating(true);
- ((PlaybackOverlayActivity) getActivity()).registerPictureInPictureListener(this);
- }
-
- @Override
- public void onStop() {
- mGlue.enableProgressUpdating(false);
- ((PlaybackOverlayActivity) getActivity()).unregisterPictureInPictureListener(this);
- super.onStop();
- }
-
- @Override
- public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
- if (isInPictureInPictureMode) {
- // Hide the controls in picture-in-picture mode.
- setFadingEnabled(true);
- fadeOut();
- } else {
- setFadingEnabled(mGlue.isPlaying());
- }
- }
-}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportActivity.java
deleted file mode 100644
index 56f1df9..0000000
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportActivity.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// CHECKSTYLE:OFF Generated code
-/* This file is auto-generated from PlaybackOverlayActivity.java. DO NOT MODIFY. */
-
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.example.android.leanback;
-
-import android.support.v4.app.FragmentActivity;
-import android.os.Bundle;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PlaybackOverlaySupportActivity extends FragmentActivity {
- private List<PictureInPictureListener> mListeners = new ArrayList<>();
-
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.playback_controls_support);
- }
-
- @Override
- public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
- for (PictureInPictureListener listener : mListeners) {
- listener.onPictureInPictureModeChanged(isInPictureInPictureMode);
- }
- }
-
- public void registerPictureInPictureListener(PictureInPictureListener listener) {
- mListeners.add(listener);
- }
-
- public void unregisterPictureInPictureListener(PictureInPictureListener listener) {
- mListeners.remove(listener);
- }
-
- public interface PictureInPictureListener {
- void onPictureInPictureModeChanged(boolean isInPictureInPictureMode);
- }
-}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java
deleted file mode 100644
index 5642557..0000000
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java
+++ /dev/null
@@ -1,195 +0,0 @@
-// CHECKSTYLE:OFF Generated code
-/* This file is auto-generated from PlaybackOverlayFragment.java. DO NOT MODIFY. */
-
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.example.android.leanback;
-
-import android.content.Context;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.ArrayObjectAdapter;
-import android.support.v17.leanback.widget.ClassPresenterSelector;
-import android.support.v17.leanback.widget.HeaderItem;
-import android.support.v17.leanback.widget.ListRow;
-import android.support.v17.leanback.widget.ListRowPresenter;
-import android.support.v17.leanback.widget.OnItemViewClickedListener;
-import android.support.v17.leanback.widget.OnItemViewSelectedListener;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.Row;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.util.Log;
-
-public class PlaybackOverlaySupportFragment
- extends android.support.v17.leanback.app.PlaybackOverlaySupportFragment
- implements PlaybackOverlaySupportActivity.PictureInPictureListener {
- private static final String TAG = "leanback.PlaybackControlsFragment";
-
- /**
- * Change this to choose a different overlay background.
- */
- private static final int BACKGROUND_TYPE = PlaybackOverlaySupportFragment.BG_LIGHT;
-
- /**
- * Change the number of related content rows.
- */
- private static final int RELATED_CONTENT_ROWS = 3;
-
- /**
- * Change this to select hidden
- */
- private static final boolean SECONDARY_HIDDEN = false;
-
- private static final int ROW_CONTROLS = 0;
-
- private PlaybackControlSupportHelper mGlue;
- final Handler mHandler = new Handler();
-
- // Artificial delay to simulate a media being prepared. The onRowChanged callback should be
- // called and the playback row UI should be updated after this delay.
- private static final int MEDIA_PREPARATION_DELAY = 500;
-
- private OnItemViewClickedListener mOnItemViewClickedListener = new OnItemViewClickedListener() {
- @Override
- public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
- RowPresenter.ViewHolder rowViewHolder, Row row) {
- Log.i(TAG, "onItemClicked: " + item + " row " + row);
- if (item instanceof Action) {
- mGlue.onActionClicked((Action) item);
- }
- }
- };
-
- private OnItemViewSelectedListener mOnItemViewSelectedListener =
- new OnItemViewSelectedListener() {
- @Override
- public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
- RowPresenter.ViewHolder rowViewHolder, Row row) {
- Log.i(TAG, "onItemSelected: " + item + " row " + row);
- }
- };
-
- @Override
- public SparseArrayObjectAdapter getAdapter() {
- return (SparseArrayObjectAdapter) super.getAdapter();
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- Log.i(TAG, "onCreate");
- super.onCreate(savedInstanceState);
-
- setBackgroundType(BACKGROUND_TYPE);
- setOnItemViewSelectedListener(mOnItemViewSelectedListener);
-
- createComponents(getActivity());
- }
-
- private void createComponents(Context context) {
- mGlue = new PlaybackControlSupportHelper(context, this) {
- @Override
- public int getUpdatePeriod() {
- long totalTime = getControlsRow().getDuration();
- if (getView() == null || getView().getWidth() == 0 || totalTime <= 0) {
- return 1000;
- }
- return 16;
- }
-
- @Override
- protected void onRowChanged(PlaybackControlsRow row) {
- if (getAdapter() == null) {
- return;
- }
- int index = getAdapter().indexOf(row);
- if (index >= 0) {
- getAdapter().notifyArrayItemRangeChanged(index, 1);
- }
- }
-
- @Override
- public void onActionClicked(Action action) {
- if (action.getId() == R.id.lb_control_picture_in_picture) {
- if (Build.VERSION.SDK_INT >= 24) {
- getActivity().enterPictureInPictureMode();
- }
- return;
- }
- super.onActionClicked(action);
- }
- };
-
- mGlue.setInitialized(false);
- mHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- mGlue.setInitialized(true);
- }
- }, MEDIA_PREPARATION_DELAY);
- mGlue.setOnItemViewClickedListener(mOnItemViewClickedListener);
-
- PlaybackControlsRowPresenter playbackControlsRowPresenter =
- mGlue.createControlsRowAndPresenter();
- playbackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
- ClassPresenterSelector selector = new ClassPresenterSelector();
- selector.addClassPresenter(ListRow.class, new ListRowPresenter());
- selector.addClassPresenter(PlaybackControlsRow.class, playbackControlsRowPresenter);
-
- setAdapter(new SparseArrayObjectAdapter(selector));
-
- // Add the controls row
- getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
-
- // Add related content rows
- for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
- ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new StringPresenter());
- listRowAdapter.add("Some related content");
- listRowAdapter.add("Other related content");
- HeaderItem header = new HeaderItem(i, "Row " + i);
- getAdapter().set(ROW_CONTROLS + 1 + i, new ListRow(header, listRowAdapter));
- }
-
- }
-
- @Override
- public void onStart() {
- super.onStart();
- mGlue.setFadingEnabled(true);
- mGlue.enableProgressUpdating(true);
- ((PlaybackOverlaySupportActivity) getActivity()).registerPictureInPictureListener(this);
- }
-
- @Override
- public void onStop() {
- mGlue.enableProgressUpdating(false);
- ((PlaybackOverlaySupportActivity) getActivity()).unregisterPictureInPictureListener(this);
- super.onStop();
- }
-
- @Override
- public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
- if (isInPictureInPictureMode) {
- // Hide the controls in picture-in-picture mode.
- setFadingEnabled(true);
- fadeOut();
- } else {
- setFadingEnabled(mGlue.isPlaying());
- }
- }
-}
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchSupportFragment.java
index b4e9b69..b638344 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchSupportFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/SearchSupportFragment.java
@@ -73,11 +73,13 @@
diff.putLong(IMAGE, newItem.getImageResourceId());
}
- if (!oldItem.getTitle().equals(newItem.getTitle())) {
+ if (oldItem.getTitle() != null && newItem.getTitle() != null
+ && !oldItem.getTitle().equals(newItem.getTitle())) {
diff.putString(TITLE, newItem.getTitle());
}
- if (!oldItem.getContent().equals(newItem.getContent())) {
+ if (oldItem.getContent() != null && newItem.getContent() != null
+ && !oldItem.getContent().equals(newItem.getContent())) {
diff.putString(CONTENT, newItem.getContent());
}
return diff;
@@ -138,11 +140,11 @@
if (mFirstRowAdapter == null) {
mFirstRowAdapter = createFirstListRowAdapter();
} else {
- mFirstRowAdapter.setItems(createDataSetOne(), mDiffCallback);
+ mFirstRowAdapter.setItems(createDataSetOneDebug(), mDiffCallback);
}
mIsDataSetOnePresented = true;
} else {
- mFirstRowAdapter.setItems(createDataSetTwo(), mDiffCallback);
+ mFirstRowAdapter.setItems(createDataSetTwoDebug(), mDiffCallback);
mIsDataSetOnePresented = false;
}
mRowsAdapter.add(new ListRow(header, mFirstRowAdapter));
@@ -180,7 +182,7 @@
private ArrayObjectAdapter createFirstListRowAdapter() {
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter());
- listRowAdapter.setItems(createDataSetOne(), mDiffCallback);
+ listRowAdapter.setItems(createDataSetOneDebug(), mDiffCallback);
mIsDataSetOnePresented = true;
return listRowAdapter;
}
@@ -322,4 +324,31 @@
return photoItems;
}
+
+ private ArrayList<PhotoItem> createDataSetOneDebug() {
+ ArrayList<PhotoItem> photoItems = new ArrayList<>();
+ photoItems.add(new PhotoItem(
+ "Hello world",
+ R.drawable.gallery_photo_1,
+ 1));
+ return photoItems;
+ }
+
+ /**
+ * Create a new data set (data set one) for the last row of this browse fragment. It will be
+ * changed by another set of data when user click one of the photo items in the list.
+ * Different with other rows in the browsing fragment, the photo item in last row all have been
+ * allocated with a unique id. And the id will be used to jduge if two photo items are the same
+ * or not.
+ *
+ * @return List of photoItem
+ */
+ private ArrayList<PhotoItem> createDataSetTwoDebug() {
+ ArrayList<PhotoItem> photoItems = new ArrayList<>();
+ photoItems.add(new PhotoItem(
+ "Hello world Hello world",
+ R.drawable.gallery_photo_1,
+ 1));
+ return photoItems;
+ }
}
diff --git a/samples/SupportWearDemos/AndroidManifest.xml b/samples/SupportWearDemos/AndroidManifest.xml
index e1309ae9..957a539 100644
--- a/samples/SupportWearDemos/AndroidManifest.xml
+++ b/samples/SupportWearDemos/AndroidManifest.xml
@@ -18,6 +18,9 @@
package="com.example.android.support.wear" >
<uses-feature android:name="android.hardware.type.watch" />
+ <!-- Required for ambient mode support. -->
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+
<application android:icon="@drawable/app_sample_code" android:label="SupportWearDemos"
android:theme="@android:style/Theme.DeviceDefault">
<activity android:name=".app.SimpleWearableRecyclerViewDemo" />
@@ -25,12 +28,15 @@
<activity android:name=".app.CircularProgressLayoutDemo" />
<activity android:name=".app.RoundedDrawableDemo" />
<activity android:name=".app.drawers.WearableDrawersDemo" android:exported="true" />
+ <activity android:name=".app.AmbientModeDemo" />
<activity android:name=".app.MainDemoActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+
+ <uses-library android:name="com.google.android.wearable" android:required="true" />
</application>
</manifest>
diff --git a/samples/SupportWearDemos/res/layout/ambient_demo.xml b/samples/SupportWearDemos/res/layout/ambient_demo.xml
new file mode 100644
index 0000000..ed7c01f
--- /dev/null
+++ b/samples/SupportWearDemos/res/layout/ambient_demo.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2017 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.
+ -->
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+ <TextView
+ android:id="@+id/ambient_text"
+ android:layout_gravity="center"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:textColor="@android:color/holo_orange_dark"
+ android:text="hello world!!"/>
+</merge>
diff --git a/samples/SupportWearDemos/src/com/example/android/support/wear/app/AmbientModeDemo.java b/samples/SupportWearDemos/src/com/example/android/support/wear/app/AmbientModeDemo.java
new file mode 100644
index 0000000..70270d2
--- /dev/null
+++ b/samples/SupportWearDemos/src/com/example/android/support/wear/app/AmbientModeDemo.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.support.wear.app;
+
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.support.wear.ambient.AmbientMode;
+import android.widget.TextView;
+
+import com.example.android.support.wear.R;
+
+/**
+ * Main activity for the AmbientMode demo.
+ */
+public class AmbientModeDemo extends FragmentActivity implements
+ AmbientMode.AmbientCallbackProvider {
+ private TextView mStateTextView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.ambient_demo);
+ mStateTextView = findViewById(R.id.ambient_text);
+ AmbientMode.AmbientController controller = AmbientMode.attachAmbientSupport(this);
+ controller.setAutoResumeEnabled(true);
+ }
+
+ @Override
+ public AmbientMode.AmbientCallback getAmbientCallback() {
+ return new MyAmbientCallback();
+ }
+
+ private class MyAmbientCallback extends AmbientMode.AmbientCallback {
+
+ @Override
+ public void onEnterAmbient(Bundle ambientDetails) {
+ // Handle entering ambient mode
+ mStateTextView.setText("Ambient");
+ mStateTextView.setTextColor(Color.WHITE);
+ mStateTextView.getPaint().setAntiAlias(false);
+ }
+
+ @Override
+ public void onExitAmbient() {
+ // Handle exiting ambient mode
+ mStateTextView.setText("Interactive");
+ mStateTextView.setTextColor(Color.GREEN);
+ mStateTextView.getPaint().setAntiAlias(true);
+ }
+ }
+}
diff --git a/samples/SupportWearDemos/src/com/example/android/support/wear/app/MainDemoActivity.java b/samples/SupportWearDemos/src/com/example/android/support/wear/app/MainDemoActivity.java
index 398adc1..0227559 100644
--- a/samples/SupportWearDemos/src/com/example/android/support/wear/app/MainDemoActivity.java
+++ b/samples/SupportWearDemos/src/com/example/android/support/wear/app/MainDemoActivity.java
@@ -62,6 +62,8 @@
this, WearableDrawersDemo.class));
contentMap.put("Rounded Drawable", new Intent(
this, RoundedDrawableDemo.class));
+ contentMap.put("Ambient Fragment", new Intent(
+ this, AmbientModeDemo.class));
return contentMap;
}
diff --git a/tv-provider/Android.mk b/tv-provider/Android.mk
index 4fa8af4..9427d0d 100644
--- a/tv-provider/Android.mk
+++ b/tv-provider/Android.mk
@@ -23,7 +23,7 @@
LOCAL_USE_AAPT2 := true
LOCAL_MODULE := android-support-tv-provider
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES := $(call all-java-files-under, src/main/java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
diff --git a/tv-provider/build.gradle b/tv-provider/build.gradle
index 42d2d90..0545458 100644
--- a/tv-provider/build.gradle
+++ b/tv-provider/build.gradle
@@ -11,11 +11,6 @@
defaultConfig {
minSdkVersion 21
}
-
- sourceSets {
- main.java.srcDirs = ['src']
- main.res.srcDir 'res'
- }
}
supportLibrary {
diff --git a/tv-provider/lint-baseline.xml b/tv-provider/lint-baseline.xml
index d5fde3a..9814796 100644
--- a/tv-provider/lint-baseline.xml
+++ b/tv-provider/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="4" by="lint 3.0.0-alpha9">
+<issues format="4" by="lint 3.0.0-beta6">
<issue
id="WrongConstant"
@@ -7,8 +7,8 @@
errorLine1=" return i == null ? INVALID_INT_VALUE : i;"
errorLine2=" ~~~~~~~~~~~~~~~~~">
<location
- file="src/android/support/media/tv/BasePreviewProgram.java"
- line="129"
+ file="src/main/java/android/support/media/tv/BasePreviewProgram.java"
+ line="130"
column="28"/>
</issue>
@@ -18,8 +18,8 @@
errorLine1=" return i == null ? INVALID_INT_VALUE : i;"
errorLine2=" ~~~~~~~~~~~~~~~~~">
<location
- file="src/android/support/media/tv/BasePreviewProgram.java"
- line="139"
+ file="src/main/java/android/support/media/tv/BasePreviewProgram.java"
+ line="140"
column="28"/>
</issue>
@@ -29,8 +29,8 @@
errorLine1=" return i == null ? INVALID_INT_VALUE : i;"
errorLine2=" ~~~~~~~~~~~~~~~~~">
<location
- file="src/android/support/media/tv/BasePreviewProgram.java"
- line="149"
+ file="src/main/java/android/support/media/tv/BasePreviewProgram.java"
+ line="150"
column="28"/>
</issue>
@@ -40,8 +40,8 @@
errorLine1=" return i == null ? INVALID_INT_VALUE : i;"
errorLine2=" ~~~~~~~~~~~~~~~~~">
<location
- file="src/android/support/media/tv/BasePreviewProgram.java"
- line="167"
+ file="src/main/java/android/support/media/tv/BasePreviewProgram.java"
+ line="168"
column="28"/>
</issue>
@@ -51,8 +51,8 @@
errorLine1=" return i == null ? INVALID_INT_VALUE : i;"
errorLine2=" ~~~~~~~~~~~~~~~~~">
<location
- file="src/android/support/media/tv/BasePreviewProgram.java"
- line="218"
+ file="src/main/java/android/support/media/tv/BasePreviewProgram.java"
+ line="219"
column="28"/>
</issue>
@@ -62,7 +62,7 @@
errorLine1=" return i == null ? INVALID_INT_VALUE : i;"
errorLine2=" ~~~~~~~~~~~~~~~~~">
<location
- file="src/android/support/media/tv/BaseProgram.java"
+ file="src/main/java/android/support/media/tv/BaseProgram.java"
line="257"
column="28"/>
</issue>
@@ -73,7 +73,7 @@
errorLine1=" mValues.put(Programs.COLUMN_BROADCAST_GENRE, Programs.Genres.encode(genres));"
errorLine2=" ~~~~~~">
<location
- file="src/android/support/media/tv/Program.java"
+ file="src/main/java/android/support/media/tv/Program.java"
line="286"
column="81"/>
</issue>
@@ -84,7 +84,7 @@
errorLine1=" return i == null ? INVALID_INT_VALUE : i;"
errorLine2=" ~~~~~~~~~~~~~~~~~">
<location
- file="src/android/support/media/tv/WatchNextProgram.java"
+ file="src/main/java/android/support/media/tv/WatchNextProgram.java"
line="99"
column="28"/>
</issue>
diff --git a/tv-provider/src/android/support/media/tv/BasePreviewProgram.java b/tv-provider/src/main/java/android/support/media/tv/BasePreviewProgram.java
similarity index 100%
rename from tv-provider/src/android/support/media/tv/BasePreviewProgram.java
rename to tv-provider/src/main/java/android/support/media/tv/BasePreviewProgram.java
diff --git a/tv-provider/src/android/support/media/tv/BaseProgram.java b/tv-provider/src/main/java/android/support/media/tv/BaseProgram.java
similarity index 100%
rename from tv-provider/src/android/support/media/tv/BaseProgram.java
rename to tv-provider/src/main/java/android/support/media/tv/BaseProgram.java
diff --git a/tv-provider/src/android/support/media/tv/Channel.java b/tv-provider/src/main/java/android/support/media/tv/Channel.java
similarity index 100%
rename from tv-provider/src/android/support/media/tv/Channel.java
rename to tv-provider/src/main/java/android/support/media/tv/Channel.java
diff --git a/tv-provider/src/android/support/media/tv/ChannelLogoUtils.java b/tv-provider/src/main/java/android/support/media/tv/ChannelLogoUtils.java
similarity index 100%
rename from tv-provider/src/android/support/media/tv/ChannelLogoUtils.java
rename to tv-provider/src/main/java/android/support/media/tv/ChannelLogoUtils.java
diff --git a/tv-provider/src/android/support/media/tv/CollectionUtils.java b/tv-provider/src/main/java/android/support/media/tv/CollectionUtils.java
similarity index 100%
rename from tv-provider/src/android/support/media/tv/CollectionUtils.java
rename to tv-provider/src/main/java/android/support/media/tv/CollectionUtils.java
diff --git a/tv-provider/src/android/support/media/tv/PreviewProgram.java b/tv-provider/src/main/java/android/support/media/tv/PreviewProgram.java
similarity index 100%
rename from tv-provider/src/android/support/media/tv/PreviewProgram.java
rename to tv-provider/src/main/java/android/support/media/tv/PreviewProgram.java
diff --git a/tv-provider/src/android/support/media/tv/Program.java b/tv-provider/src/main/java/android/support/media/tv/Program.java
similarity index 100%
rename from tv-provider/src/android/support/media/tv/Program.java
rename to tv-provider/src/main/java/android/support/media/tv/Program.java
diff --git a/tv-provider/src/android/support/media/tv/TvContractCompat.java b/tv-provider/src/main/java/android/support/media/tv/TvContractCompat.java
similarity index 100%
rename from tv-provider/src/android/support/media/tv/TvContractCompat.java
rename to tv-provider/src/main/java/android/support/media/tv/TvContractCompat.java
diff --git a/tv-provider/src/android/support/media/tv/TvContractUtils.java b/tv-provider/src/main/java/android/support/media/tv/TvContractUtils.java
similarity index 100%
rename from tv-provider/src/android/support/media/tv/TvContractUtils.java
rename to tv-provider/src/main/java/android/support/media/tv/TvContractUtils.java
diff --git a/tv-provider/src/android/support/media/tv/WatchNextProgram.java b/tv-provider/src/main/java/android/support/media/tv/WatchNextProgram.java
similarity index 100%
rename from tv-provider/src/android/support/media/tv/WatchNextProgram.java
rename to tv-provider/src/main/java/android/support/media/tv/WatchNextProgram.java
diff --git a/v17/leanback/api/26.0.0.ignore b/v17/leanback/api/26.0.0.ignore
new file mode 100644
index 0000000..81d1fe5
--- /dev/null
+++ b/v17/leanback/api/26.0.0.ignore
@@ -0,0 +1,2 @@
+036d6d4
+07abbac
diff --git a/v17/leanback/api/current.txt b/v17/leanback/api/current.txt
index 00e764b..4ee4d94 100644
--- a/v17/leanback/api/current.txt
+++ b/v17/leanback/api/current.txt
@@ -658,53 +658,6 @@
method protected final void startEnterAnimation(boolean);
}
- public abstract deprecated class PlaybackControlGlue extends android.support.v17.leanback.media.PlaybackControlGlue {
- ctor public PlaybackControlGlue(android.content.Context, int[]);
- ctor public PlaybackControlGlue(android.content.Context, int[], int[]);
- ctor public PlaybackControlGlue(android.content.Context, android.support.v17.leanback.app.PlaybackOverlayFragment, int[]);
- ctor public PlaybackControlGlue(android.content.Context, android.support.v17.leanback.app.PlaybackOverlayFragment, int[], int[]);
- method public android.support.v17.leanback.widget.PlaybackControlsRowPresenter createControlsRowAndPresenter();
- method protected android.support.v17.leanback.widget.SparseArrayObjectAdapter createPrimaryActionsAdapter(android.support.v17.leanback.widget.PresenterSelector);
- method public android.support.v17.leanback.app.PlaybackOverlayFragment getFragment();
- method public deprecated android.support.v17.leanback.widget.OnItemViewClickedListener getOnItemViewClickedListener();
- method public final void next();
- method protected void onRowChanged(android.support.v17.leanback.widget.PlaybackControlsRow);
- method public final void pause();
- method protected deprecated void pausePlayback();
- method public final void play(int);
- method public final void previous();
- method public deprecated void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
- method protected deprecated void skipToNext();
- method protected deprecated void skipToPrevious();
- method protected deprecated void startPlayback(int);
- }
-
- public static abstract deprecated interface PlaybackControlGlue.InputEventHandler {
- method public abstract boolean handleInputEvent(android.view.InputEvent);
- }
-
- public abstract deprecated class PlaybackControlSupportGlue extends android.support.v17.leanback.app.PlaybackControlGlue {
- ctor public PlaybackControlSupportGlue(android.content.Context, int[]);
- ctor public PlaybackControlSupportGlue(android.content.Context, int[], int[]);
- ctor public PlaybackControlSupportGlue(android.content.Context, android.support.v17.leanback.app.PlaybackOverlaySupportFragment, int[]);
- ctor public PlaybackControlSupportGlue(android.content.Context, android.support.v17.leanback.app.PlaybackOverlaySupportFragment, int[], int[]);
- field public static final int ACTION_CUSTOM_LEFT_FIRST = 1; // 0x1
- field public static final int ACTION_CUSTOM_RIGHT_FIRST = 4096; // 0x1000
- field public static final int ACTION_FAST_FORWARD = 128; // 0x80
- field public static final int ACTION_PLAY_PAUSE = 64; // 0x40
- field public static final int ACTION_REWIND = 32; // 0x20
- field public static final int ACTION_SKIP_TO_NEXT = 256; // 0x100
- field public static final int ACTION_SKIP_TO_PREVIOUS = 16; // 0x10
- field public static final int PLAYBACK_SPEED_FAST_L0 = 10; // 0xa
- field public static final int PLAYBACK_SPEED_FAST_L1 = 11; // 0xb
- field public static final int PLAYBACK_SPEED_FAST_L2 = 12; // 0xc
- field public static final int PLAYBACK_SPEED_FAST_L3 = 13; // 0xd
- field public static final int PLAYBACK_SPEED_FAST_L4 = 14; // 0xe
- field public static final int PLAYBACK_SPEED_INVALID = -1; // 0xffffffff
- field public static final int PLAYBACK_SPEED_NORMAL = 1; // 0x1
- field public static final int PLAYBACK_SPEED_PAUSED = 0; // 0x0
- }
-
public class PlaybackFragment extends android.app.Fragment {
ctor public PlaybackFragment();
method public deprecated void fadeOut();
@@ -746,62 +699,6 @@
method public void setPlaybackSeekUiClient(android.support.v17.leanback.widget.PlaybackSeekUi.Client);
}
- public deprecated class PlaybackOverlayFragment extends android.support.v17.leanback.app.DetailsFragment {
- ctor public PlaybackOverlayFragment();
- method public void fadeOut();
- method public int getBackgroundType();
- method public final android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler getEventHandler();
- method public android.support.v17.leanback.app.PlaybackOverlayFragment.OnFadeCompleteListener getFadeCompleteListener();
- method public final deprecated android.support.v17.leanback.app.PlaybackOverlayFragment.InputEventHandler getInputEventHandler();
- method public boolean isFadingEnabled();
- method public void setBackgroundType(int);
- method public final void setEventHandler(android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler);
- method public void setFadeCompleteListener(android.support.v17.leanback.app.PlaybackOverlayFragment.OnFadeCompleteListener);
- method public void setFadingEnabled(boolean);
- method public final deprecated void setInputEventHandler(android.support.v17.leanback.app.PlaybackOverlayFragment.InputEventHandler);
- method public void tickle();
- field public static final int BG_DARK = 1; // 0x1
- field public static final int BG_LIGHT = 2; // 0x2
- field public static final int BG_NONE = 0; // 0x0
- }
-
- public static abstract deprecated interface PlaybackOverlayFragment.InputEventHandler implements android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler {
- }
-
- public static class PlaybackOverlayFragment.OnFadeCompleteListener {
- ctor public PlaybackOverlayFragment.OnFadeCompleteListener();
- method public void onFadeInComplete();
- method public void onFadeOutComplete();
- }
-
- public deprecated class PlaybackOverlaySupportFragment extends android.support.v17.leanback.app.DetailsSupportFragment {
- ctor public PlaybackOverlaySupportFragment();
- method public void fadeOut();
- method public int getBackgroundType();
- method public final android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler getEventHandler();
- method public android.support.v17.leanback.app.PlaybackOverlaySupportFragment.OnFadeCompleteListener getFadeCompleteListener();
- method public final deprecated android.support.v17.leanback.app.PlaybackOverlaySupportFragment.InputEventHandler getInputEventHandler();
- method public boolean isFadingEnabled();
- method public void setBackgroundType(int);
- method public final void setEventHandler(android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler);
- method public void setFadeCompleteListener(android.support.v17.leanback.app.PlaybackOverlaySupportFragment.OnFadeCompleteListener);
- method public void setFadingEnabled(boolean);
- method public final deprecated void setInputEventHandler(android.support.v17.leanback.app.PlaybackOverlaySupportFragment.InputEventHandler);
- method public void tickle();
- field public static final int BG_DARK = 1; // 0x1
- field public static final int BG_LIGHT = 2; // 0x2
- field public static final int BG_NONE = 0; // 0x0
- }
-
- public static abstract deprecated interface PlaybackOverlaySupportFragment.InputEventHandler implements android.support.v17.leanback.app.PlaybackControlGlue.InputEventHandler {
- }
-
- public static class PlaybackOverlaySupportFragment.OnFadeCompleteListener {
- ctor public PlaybackOverlaySupportFragment.OnFadeCompleteListener();
- method public void onFadeInComplete();
- method public void onFadeOutComplete();
- }
-
public class PlaybackSupportFragment extends android.support.v4.app.Fragment {
ctor public PlaybackSupportFragment();
method public deprecated void fadeOut();
@@ -926,7 +823,7 @@
method public void setSearchQuery(java.lang.String, boolean);
method public void setSearchQuery(android.content.Intent, boolean);
method public void setSearchResultProvider(android.support.v17.leanback.app.SearchFragment.SearchResultProvider);
- method public void setSpeechRecognitionCallback(android.support.v17.leanback.widget.SpeechRecognitionCallback);
+ method public deprecated void setSpeechRecognitionCallback(android.support.v17.leanback.widget.SpeechRecognitionCallback);
method public void setTitle(java.lang.String);
method public void startRecognition();
}
@@ -956,7 +853,7 @@
method public void setSearchQuery(java.lang.String, boolean);
method public void setSearchQuery(android.content.Intent, boolean);
method public void setSearchResultProvider(android.support.v17.leanback.app.SearchSupportFragment.SearchResultProvider);
- method public void setSpeechRecognitionCallback(android.support.v17.leanback.widget.SpeechRecognitionCallback);
+ method public deprecated void setSpeechRecognitionCallback(android.support.v17.leanback.widget.SpeechRecognitionCallback);
method public void setTitle(java.lang.String);
method public void startRecognition();
}
@@ -2903,7 +2800,7 @@
method public void setSearchAffordanceColorsInListening(android.support.v17.leanback.widget.SearchOrbView.Colors);
method public void setSearchBarListener(android.support.v17.leanback.widget.SearchBar.SearchBarListener);
method public void setSearchQuery(java.lang.String);
- method public void setSpeechRecognitionCallback(android.support.v17.leanback.widget.SpeechRecognitionCallback);
+ method public deprecated void setSpeechRecognitionCallback(android.support.v17.leanback.widget.SpeechRecognitionCallback);
method public void setSpeechRecognizer(android.speech.SpeechRecognizer);
method public void setTitle(java.lang.String);
method public void startRecognition();
@@ -3059,7 +2956,7 @@
method public void showNotListening();
}
- public abstract interface SpeechRecognitionCallback {
+ public abstract deprecated interface SpeechRecognitionCallback {
method public abstract void recognizeSpeech();
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java
index 278c1ac..bdb213f 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java
@@ -18,6 +18,8 @@
import android.annotation.SuppressLint;
import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.v17.leanback.transition.TransitionHelper;
import android.support.v17.leanback.transition.TransitionListener;
import android.support.v17.leanback.util.StateMachine;
@@ -180,7 +182,7 @@
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mStateMachine.fireEvent(EVT_ON_CREATEVIEW);
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BaseRowFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BaseRowFragment.java
index ac67d2b..2d79f3e 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BaseRowFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BaseRowFragment.java
@@ -17,6 +17,8 @@
package android.support.v17.leanback.app;
import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.v17.leanback.widget.ItemBridgeAdapter;
import android.support.v17.leanback.widget.ListRow;
import android.support.v17.leanback.widget.ObjectAdapter;
@@ -78,7 +80,7 @@
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
if (savedInstanceState != null) {
mSelectedPosition = savedInstanceState.getInt(CURRENT_SELECTED_POSITION, -1);
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BrandedFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BrandedFragment.java
index b80bd7c..1f6ad29 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrandedFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrandedFragment.java
@@ -18,6 +18,8 @@
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.v17.leanback.R;
import android.support.v17.leanback.widget.SearchOrbView;
import android.support.v17.leanback.widget.TitleHelper;
@@ -146,7 +148,7 @@
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (savedInstanceState != null) {
mShowingTitle = savedInstanceState.getBoolean(TITLE_SHOW);
diff --git a/v17/leanback/src/android/support/v17/leanback/app/HeadersFragment.java b/v17/leanback/src/android/support/v17/leanback/app/HeadersFragment.java
index 12cdcd7..dd037d2 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/HeadersFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/HeadersFragment.java
@@ -23,6 +23,8 @@
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.v17.leanback.R;
import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.support.v17.leanback.widget.DividerPresenter;
@@ -163,7 +165,7 @@
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final VerticalGridView listView = getVerticalGridView();
if (listView == null) {
diff --git a/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java b/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java
index 74affd6..b69d5a7 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java
@@ -29,6 +29,7 @@
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.ColorInt;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v17.leanback.R;
import android.support.v17.leanback.widget.PagingIndicator;
@@ -353,7 +354,7 @@
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (savedInstanceState == null) {
mCurrentPageIndex = 0;
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlGlue.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlGlue.java
deleted file mode 100644
index d74fd11..0000000
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlGlue.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright (C) 2016 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.v17.leanback.app;
-
-import android.content.Context;
-import android.support.v17.leanback.media.PlaybackGlueHost;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.OnActionClickedListener;
-import android.support.v17.leanback.widget.OnItemViewClickedListener;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.PlaybackRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.PresenterSelector;
-import android.support.v17.leanback.widget.Row;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.view.InputEvent;
-import android.view.KeyEvent;
-import android.view.View;
-
-/**
- * A helper class for managing a {@link android.support.v17.leanback.widget.PlaybackControlsRow}
- * and {@link PlaybackGlueHost} that implements a
- * recommended approach to handling standard playback control actions such as play/pause,
- * fast forward/rewind at progressive speed levels, and skip to next/previous. This helper class
- * is a glue layer in that manages the configuration of and interaction between the
- * leanback UI components by defining a functional interface to the media player.
- *
- * <p>You can instantiate a concrete subclass such as MediaPlayerGlue or you must
- * subclass this abstract helper. To create a subclass you must implement all of the
- * abstract methods and the subclass must invoke {@link #onMetadataChanged()} and
- * {@link #onStateChanged()} appropriately.
- * </p>
- *
- * <p>To use an instance of the glue layer, first construct an instance. Constructor parameters
- * inform the glue what speed levels are supported for fast forward/rewind.
- * </p>
- *
- * <p>If you have your own controls row you must pass it to {@link #setControlsRow}.
- * The row will be updated by the glue layer based on the media metadata and playback state.
- * Alternatively, you may call {@link #createControlsRowAndPresenter()} which will set a controls
- * row and return a row presenter you can use to present the row.
- * </p>
- *
- * <p>The helper sets a {@link android.support.v17.leanback.widget.SparseArrayObjectAdapter}
- * on the controls row as the primary actions adapter, and adds actions to it. You can provide
- * additional actions by overriding {@link #createPrimaryActionsAdapter}. This helper does not
- * deal in secondary actions so those you may add separately.
- * </p>
- *
- * <p>Provide a click listener on your fragment and if an action is clicked, call
- * {@link #onActionClicked}. If you set a listener by calling {@link #setOnItemViewClickedListener},
- * your listener will be called for all unhandled actions.
- * </p>
- *
- * <p>This helper implements a key event handler. If you pass a
- * {@link PlaybackOverlayFragment}, it will configure its
- * fragment to intercept all key events. Otherwise, you should set the glue object as key event
- * handler to the ViewHolder when bound by your row presenter; see
- * {@link RowPresenter.ViewHolder#setOnKeyListener(android.view.View.OnKeyListener)}.
- * </p>
- *
- * <p>To update the controls row progress during playback, override {@link #enableProgressUpdating}
- * to manage the lifecycle of a periodic callback to {@link #updateProgress()}.
- * {@link #getUpdatePeriod()} provides a recommended update period.
- * </p>
- * @deprecated Use {@link android.support.v17.leanback.media.PlaybackControlGlue}
- */
-@Deprecated
-public abstract class PlaybackControlGlue extends
- android.support.v17.leanback.media.PlaybackControlGlue {
-
- OnItemViewClickedListener mExternalOnItemViewClickedListener;
-
- /**
- * Constructor for the glue.
- *
- * @param context
- * @param seekSpeeds Array of seek speeds for fast forward and rewind.
- */
- public PlaybackControlGlue(Context context, int[] seekSpeeds) {
- super(context, seekSpeeds, seekSpeeds);
- }
-
- /**
- * Constructor for the glue.
- *
- * @param context
- * @param fastForwardSpeeds Array of seek speeds for fast forward.
- * @param rewindSpeeds Array of seek speeds for rewind.
- */
- public PlaybackControlGlue(Context context,
- int[] fastForwardSpeeds,
- int[] rewindSpeeds) {
- super(context, fastForwardSpeeds, rewindSpeeds);
- }
-
- /**
- * Constructor for the glue.
- *
- * @param context
- * @param fragment Optional; if using a {@link PlaybackOverlayFragment}, pass it in.
- * @param seekSpeeds Array of seek speeds for fast forward and rewind.
- */
- public PlaybackControlGlue(Context context,
- PlaybackOverlayFragment fragment,
- int[] seekSpeeds) {
- this(context, fragment, seekSpeeds, seekSpeeds);
- }
-
- /**
- * Constructor for the glue.
- *
- * @param context
- * @param fragment Optional; if using a {@link PlaybackOverlayFragment}, pass it in.
- * @param fastForwardSpeeds Array of seek speeds for fast forward.
- * @param rewindSpeeds Array of seek speeds for rewind.
- */
- public PlaybackControlGlue(Context context,
- PlaybackOverlayFragment fragment,
- int[] fastForwardSpeeds,
- int[] rewindSpeeds) {
- super(context, fastForwardSpeeds, rewindSpeeds);
- setHost(fragment == null ? (PlaybackGlueHost) null : new PlaybackGlueHostOld(fragment));
- }
-
- @Override
- protected void onAttachedToHost(PlaybackGlueHost host) {
- super.onAttachedToHost(host);
- if (host instanceof PlaybackGlueHostOld) {
- ((PlaybackGlueHostOld) host).mGlue = this;
- }
- }
-
- /**
- * Returns the fragment.
- */
- public PlaybackOverlayFragment getFragment() {
- if (getHost() instanceof PlaybackGlueHostOld) {
- return ((PlaybackGlueHostOld)getHost()).mFragment;
- }
- return null;
- }
-
- /**
- * Start playback at the given speed.
- * @deprecated use {@link #play()} instead.
- *
- * @param speed The desired playback speed. For normal playback this will be
- * {@link #PLAYBACK_SPEED_NORMAL}; higher positive values for fast forward,
- * and negative values for rewind.
- */
- @Deprecated
- protected void startPlayback(int speed) {}
-
- /**
- * Pause playback.
- * @deprecated use {@link #pause()} instead.
- */
- @Deprecated
- protected void pausePlayback() {}
-
- /**
- * Skip to the next track.
- * @deprecated use {@link #next()} instead.
- */
- @Deprecated
- protected void skipToNext() {}
-
- /**
- * Skip to the previous track.
- * @deprecated use {@link #previous()} instead.
- */
- @Deprecated
- protected void skipToPrevious() {}
-
- @Override
- public final void next() {
- skipToNext();
- }
-
- @Override
- public final void previous() {
- skipToPrevious();
- }
-
- @Override
- public final void play(int speed) {
- startPlayback(speed);
- }
-
- @Override
- public final void pause() {
- pausePlayback();
- }
-
- /**
- * This method invoked when the playback controls row has changed. The adapter
- * containing this row should be notified.
- */
- protected void onRowChanged(PlaybackControlsRow row) {
- }
-
- /**
- * Set the {@link OnItemViewClickedListener} to be called if the click event
- * is not handled internally.
- * @param listener
- * @deprecated Don't call this. Instead use the listener on the fragment yourself.
- */
- @Deprecated
- public void setOnItemViewClickedListener(OnItemViewClickedListener listener) {
- mExternalOnItemViewClickedListener = listener;
- }
-
- /**
- * Returns the {@link OnItemViewClickedListener}.
- * @deprecated Don't call this. Instead use the listener on the fragment yourself.
- */
- @Deprecated
- public OnItemViewClickedListener getOnItemViewClickedListener() {
- return mExternalOnItemViewClickedListener;
- }
-
- @Override
- protected void onCreateControlsRowAndPresenter() {
- // backward compatible, we dont create row / presenter by default.
- // User is expected to call createControlsRowAndPresenter() or setControlsRow()
- // explicitly.
- }
-
- /**
- * Helper method for instantiating a
- * {@link android.support.v17.leanback.widget.PlaybackControlsRow} and corresponding
- * {@link android.support.v17.leanback.widget.PlaybackControlsRowPresenter}.
- */
- public PlaybackControlsRowPresenter createControlsRowAndPresenter() {
- super.onCreateControlsRowAndPresenter();
- return getControlsRowPresenter();
- }
-
- @Override
- protected SparseArrayObjectAdapter createPrimaryActionsAdapter(
- PresenterSelector presenterSelector) {
- return super.createPrimaryActionsAdapter(presenterSelector);
- }
-
- /**
- * Interface allowing the application to handle input events.
- * @deprecated Use
- * {@link PlaybackGlueHost#setOnKeyInterceptListener(View.OnKeyListener)}.
- */
- @Deprecated
- public interface InputEventHandler {
- /**
- * Called when an {@link InputEvent} is received.
- *
- * @return If the event should be consumed, return true. To allow the event to
- * continue on to the next handler, return false.
- */
- boolean handleInputEvent(InputEvent event);
- }
-
- static final class PlaybackGlueHostOld extends PlaybackGlueHost {
- final PlaybackOverlayFragment mFragment;
- PlaybackControlGlue mGlue;
- OnActionClickedListener mActionClickedListener;
-
- public PlaybackGlueHostOld(PlaybackOverlayFragment fragment) {
- mFragment = fragment;
- mFragment.setOnItemViewClickedListener(new OnItemViewClickedListener() {
- @Override
- public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
- RowPresenter.ViewHolder rowViewHolder, Row row) {
- if (item instanceof Action
- && rowViewHolder instanceof PlaybackRowPresenter.ViewHolder
- && mActionClickedListener != null) {
- mActionClickedListener.onActionClicked((Action) item);
- } else if (mGlue != null && mGlue.getOnItemViewClickedListener() != null) {
- mGlue.getOnItemViewClickedListener().onItemClicked(itemViewHolder,
- item, rowViewHolder, row);
- }
- }
- });
- }
-
- @Override
- public void setFadingEnabled(boolean enable) {
- mFragment.setFadingEnabled(enable);
- }
-
- @Override
- public void setOnKeyInterceptListener(final View.OnKeyListener onKeyListener) {
- mFragment.setEventHandler( new InputEventHandler() {
- @Override
- public boolean handleInputEvent(InputEvent event) {
- if (event instanceof KeyEvent) {
- KeyEvent keyEvent = (KeyEvent) event;
- return onKeyListener.onKey(null, keyEvent.getKeyCode(), keyEvent);
- }
- return false;
- }
- });
- }
-
- @Override
- public void setOnActionClickedListener(final OnActionClickedListener listener) {
- mActionClickedListener = listener;
- }
-
- @Override
- public void setHostCallback(HostCallback callback) {
- mFragment.setHostCallback(callback);
- }
-
- @Override
- public void fadeOut() {
- mFragment.fadeOut();
- }
-
- @Override
- public void notifyPlaybackRowChanged() {
- mGlue.onRowChanged(mGlue.getControlsRow());
- }
- }
-}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlSupportGlue.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlSupportGlue.java
deleted file mode 100644
index b3d19ae..0000000
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlSupportGlue.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/* This file is auto-generated from PlaybackControlGlue.java. DO NOT MODIFY. */
-
-package android.support.v17.leanback.app;
-
-import android.content.Context;
-import android.support.v17.leanback.media.PlaybackGlueHost;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.OnActionClickedListener;
-import android.support.v17.leanback.widget.OnItemViewClickedListener;
-import android.support.v17.leanback.widget.PlaybackRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.Row;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.view.InputEvent;
-import android.view.KeyEvent;
-import android.view.View;
-
-/**
- * @deprecated Use {@link android.support.v17.leanback.media.PlaybackControlGlue} and
- * {@link PlaybackSupportFragmentGlueHost} for {@link PlaybackSupportFragment}.
- */
-@Deprecated
-public abstract class PlaybackControlSupportGlue extends PlaybackControlGlue {
- /**
- * The adapter key for the first custom control on the left side
- * of the predefined primary controls.
- */
- public static final int ACTION_CUSTOM_LEFT_FIRST = PlaybackControlGlue.ACTION_CUSTOM_LEFT_FIRST;
-
- /**
- * The adapter key for the skip to previous control.
- */
- public static final int ACTION_SKIP_TO_PREVIOUS = PlaybackControlGlue.ACTION_SKIP_TO_PREVIOUS;
-
- /**
- * The adapter key for the rewind control.
- */
- public static final int ACTION_REWIND = PlaybackControlGlue.ACTION_REWIND;
-
- /**
- * The adapter key for the play/pause control.
- */
- public static final int ACTION_PLAY_PAUSE = PlaybackControlGlue.ACTION_PLAY_PAUSE;
-
- /**
- * The adapter key for the fast forward control.
- */
- public static final int ACTION_FAST_FORWARD = PlaybackControlGlue.ACTION_FAST_FORWARD;
-
- /**
- * The adapter key for the skip to next control.
- */
- public static final int ACTION_SKIP_TO_NEXT = PlaybackControlGlue.ACTION_SKIP_TO_NEXT;
-
- /**
- * The adapter key for the first custom control on the right side
- * of the predefined primary controls.
- */
- public static final int ACTION_CUSTOM_RIGHT_FIRST =
- PlaybackControlGlue.ACTION_CUSTOM_RIGHT_FIRST;
-
- /**
- * Invalid playback speed.
- */
- public static final int PLAYBACK_SPEED_INVALID = PlaybackControlGlue.PLAYBACK_SPEED_INVALID;
-
- /**
- * Speed representing playback state that is paused.
- */
- public static final int PLAYBACK_SPEED_PAUSED = PlaybackControlGlue.PLAYBACK_SPEED_PAUSED;
-
- /**
- * Speed representing playback state that is playing normally.
- */
- public static final int PLAYBACK_SPEED_NORMAL = PlaybackControlGlue.PLAYBACK_SPEED_NORMAL;
-
- /**
- * The initial (level 0) fast forward playback speed.
- * The negative of this value is for rewind at the same speed.
- */
- public static final int PLAYBACK_SPEED_FAST_L0 = PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0;
-
- /**
- * The level 1 fast forward playback speed.
- * The negative of this value is for rewind at the same speed.
- */
- public static final int PLAYBACK_SPEED_FAST_L1 = PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1;
-
- /**
- * The level 2 fast forward playback speed.
- * The negative of this value is for rewind at the same speed.
- */
- public static final int PLAYBACK_SPEED_FAST_L2 = PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2;
-
- /**
- * The level 3 fast forward playback speed.
- * The negative of this value is for rewind at the same speed.
- */
- public static final int PLAYBACK_SPEED_FAST_L3 = PlaybackControlGlue.PLAYBACK_SPEED_FAST_L3;
-
- /**
- * The level 4 fast forward playback speed.
- * The negative of this value is for rewind at the same speed.
- */
- public static final int PLAYBACK_SPEED_FAST_L4 = PlaybackControlGlue.PLAYBACK_SPEED_FAST_L4;
-
- public PlaybackControlSupportGlue(Context context, int[] seekSpeeds) {
- this(context, null, seekSpeeds, seekSpeeds);
- }
-
- public PlaybackControlSupportGlue(
- Context context, int[] fastForwardSpeeds, int[] rewindSpeeds) {
- this(context, null, fastForwardSpeeds, rewindSpeeds);
- }
-
- public PlaybackControlSupportGlue(
- Context context,
- PlaybackOverlaySupportFragment fragment,
- int[] seekSpeeds) {
- this(context, fragment, seekSpeeds, seekSpeeds);
- }
-
- public PlaybackControlSupportGlue(
- Context context,
- PlaybackOverlaySupportFragment fragment,
- int[] fastForwardSpeeds,
- int[] rewindSpeeds) {
- super(context, fastForwardSpeeds, rewindSpeeds);
- setHost(fragment == null ? null : new PlaybackSupportGlueHostOld(fragment));
- }
-
- @Override
- protected void onAttachedToHost(PlaybackGlueHost host) {
- super.onAttachedToHost(host);
- if (host instanceof PlaybackSupportGlueHostOld) {
- ((PlaybackSupportGlueHostOld) host).mGlue = this;
- }
- }
-
- static final class PlaybackSupportGlueHostOld extends PlaybackGlueHost {
- final PlaybackOverlaySupportFragment mFragment;
- PlaybackControlSupportGlue mGlue;
- OnActionClickedListener mActionClickedListener;
-
- public PlaybackSupportGlueHostOld(PlaybackOverlaySupportFragment fragment) {
- mFragment = fragment;
- mFragment.setOnItemViewClickedListener(new OnItemViewClickedListener() {
- @Override
- public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
- RowPresenter.ViewHolder rowViewHolder, Row row) {
- if (item instanceof Action
- && rowViewHolder instanceof PlaybackRowPresenter.ViewHolder
- && mActionClickedListener != null) {
- mActionClickedListener.onActionClicked((Action) item);
- } else if (mGlue != null && mGlue.getOnItemViewClickedListener() != null) {
- mGlue.getOnItemViewClickedListener().onItemClicked(itemViewHolder,
- item, rowViewHolder, row);
- }
- }
- });
- }
-
- @Override
- public void setFadingEnabled(boolean enable) {
- mFragment.setFadingEnabled(enable);
- }
-
- @Override
- public void setOnKeyInterceptListener(final View.OnKeyListener onKeyListenerr) {
- mFragment.setEventHandler( new InputEventHandler() {
- @Override
- public boolean handleInputEvent(InputEvent event) {
- if (event instanceof KeyEvent) {
- KeyEvent keyEvent = (KeyEvent) event;
- return onKeyListenerr.onKey(null, keyEvent.getKeyCode(), keyEvent);
- }
- return false;
- }
- });
- }
-
- @Override
- public void setOnActionClickedListener(final OnActionClickedListener listener) {
- mActionClickedListener = listener;
- }
-
- @Override
- public void setHostCallback(HostCallback callback) {
- mFragment.setHostCallback(callback);
- }
-
- @Override
- public void fadeOut() {
- mFragment.fadeOut();
- }
-
- @Override
- public void notifyPlaybackRowChanged() {
- mGlue.onRowChanged(mGlue.getControlsRow());
- }
- }
-}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackFragment.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackFragment.java
index 1279521..33e787c 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackFragment.java
@@ -27,6 +27,8 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.v17.leanback.R;
import android.support.v17.leanback.animation.LogAccelerateInterpolator;
import android.support.v17.leanback.animation.LogDecelerateInterpolator;
@@ -450,7 +452,7 @@
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// controls view are initially visible, make it invisible
// if app has called hideControlsOverlay() before view created.
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
deleted file mode 100644
index d4b532b..0000000
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
+++ /dev/null
@@ -1,863 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package android.support.v17.leanback.app;
-
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.animation.TimeInterpolator;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.content.Context;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.support.v17.leanback.R;
-import android.support.v17.leanback.animation.LogAccelerateInterpolator;
-import android.support.v17.leanback.animation.LogDecelerateInterpolator;
-import android.support.v17.leanback.media.PlaybackGlueHost;
-import android.support.v17.leanback.widget.ItemAlignmentFacet;
-import android.support.v17.leanback.widget.ItemBridgeAdapter;
-import android.support.v17.leanback.widget.ObjectAdapter;
-import android.support.v17.leanback.widget.ObjectAdapter.DataObserver;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.PlaybackRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.PresenterSelector;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.support.v17.leanback.widget.VerticalGridView;
-import android.support.v7.widget.RecyclerView;
-import android.util.Log;
-import android.view.InputEvent;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AccelerateInterpolator;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-
-/**
- * A fragment for displaying playback controls and related content.
- * <p>
- * A PlaybackOverlayFragment renders the elements of its {@link ObjectAdapter} as a set
- * of rows in a vertical list. The Adapter's {@link PresenterSelector} must maintain subclasses
- * of {@link RowPresenter}.
- * </p>
- * <p>
- * An instance of {@link android.support.v17.leanback.widget.PlaybackControlsRow} is expected to be
- * at position 0 in the adapter.
- * </p>
- * <p>
- * This class is now deprecated, please us
- * </p>
- * @deprecated Use {@link PlaybackFragment}.
- */
-@Deprecated
-public class PlaybackOverlayFragment extends DetailsFragment {
-
- /**
- * No background.
- */
- public static final int BG_NONE = 0;
-
- /**
- * A dark translucent background.
- */
- public static final int BG_DARK = 1;
-
- /**
- * A light translucent background.
- */
- public static final int BG_LIGHT = 2;
-
- /**
- * Listener allowing the application to receive notification of fade in and/or fade out
- * completion events.
- */
- public static class OnFadeCompleteListener {
- public void onFadeInComplete() {
- }
- public void onFadeOutComplete() {
- }
- }
-
- static final String TAG = "PlaybackOF";
- static final boolean DEBUG = false;
- private static final int ANIMATION_MULTIPLIER = 1;
-
- static int START_FADE_OUT = 1;
-
- // Fading status
- static final int IDLE = 0;
- private static final int IN = 1;
- static final int OUT = 2;
-
- private int mOtherRowsCenterToBottom;
- private int mPaddingBottom;
- private View mRootView;
- private int mBackgroundType = BG_DARK;
- private int mBgDarkColor;
- private int mBgLightColor;
- private int mShowTimeMs;
- private int mMajorFadeTranslateY, mMinorFadeTranslateY;
- int mAnimationTranslateY;
- OnFadeCompleteListener mFadeCompleteListener;
- private PlaybackControlGlue.InputEventHandler mInputEventHandler;
- boolean mFadingEnabled = true;
- int mFadingStatus = IDLE;
- int mBgAlpha;
- private ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator;
- private ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator;
- private ValueAnimator mDescriptionFadeInAnimator, mDescriptionFadeOutAnimator;
- private ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator;
- boolean mResetControlsToPrimaryActionsPending;
- PlaybackGlueHost.HostCallback mHostCallback;
-
- private final Animator.AnimatorListener mFadeListener =
- new Animator.AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {
- enableVerticalGridAnimations(false);
- }
- @Override
- public void onAnimationRepeat(Animator animation) {
- }
- @Override
- public void onAnimationCancel(Animator animation) {
- }
- @Override
- public void onAnimationEnd(Animator animation) {
- if (DEBUG) Log.v(TAG, "onAnimationEnd " + mBgAlpha);
- if (mBgAlpha > 0) {
- enableVerticalGridAnimations(true);
- startFadeTimer();
- if (mFadeCompleteListener != null) {
- mFadeCompleteListener.onFadeInComplete();
- }
- } else {
- VerticalGridView verticalView = getVerticalGridView();
- // reset focus to the primary actions only if the selected row was the controls row
- if (verticalView != null && verticalView.getSelectedPosition() == 0) {
- resetControlsToPrimaryActions(null);
- }
- if (mFadeCompleteListener != null) {
- mFadeCompleteListener.onFadeOutComplete();
- }
- }
- mFadingStatus = IDLE;
- }
- };
-
- static class FadeHandler extends Handler {
- @Override
- public void handleMessage(Message message) {
- PlaybackOverlayFragment fragment;
- if (message.what == START_FADE_OUT) {
- fragment = ((WeakReference<PlaybackOverlayFragment>) message.obj).get();
- if (fragment != null && fragment.mFadingEnabled) {
- fragment.fade(false);
- }
- }
- }
- }
-
- static final Handler sHandler = new FadeHandler();
-
- final WeakReference<PlaybackOverlayFragment> mFragmentReference = new WeakReference(this);
-
- private final VerticalGridView.OnTouchInterceptListener mOnTouchInterceptListener =
- new VerticalGridView.OnTouchInterceptListener() {
- @Override
- public boolean onInterceptTouchEvent(MotionEvent event) {
- return onInterceptInputEvent(event);
- }
- };
-
- private final VerticalGridView.OnKeyInterceptListener mOnKeyInterceptListener =
- new VerticalGridView.OnKeyInterceptListener() {
- @Override
- public boolean onInterceptKeyEvent(KeyEvent event) {
- return onInterceptInputEvent(event);
- }
- };
-
- void setBgAlpha(int alpha) {
- mBgAlpha = alpha;
- if (mRootView != null) {
- mRootView.getBackground().setAlpha(alpha);
- }
- }
-
- void enableVerticalGridAnimations(boolean enable) {
- if (getVerticalGridView() != null) {
- getVerticalGridView().setAnimateChildLayout(enable);
- }
- }
-
- void resetControlsToPrimaryActions(ItemBridgeAdapter.ViewHolder vh) {
- if (vh == null && getVerticalGridView() != null) {
- vh = (ItemBridgeAdapter.ViewHolder) getVerticalGridView().findViewHolderForPosition(0);
- }
- if (vh == null) {
- mResetControlsToPrimaryActionsPending = true;
- } else if (vh.getPresenter() instanceof PlaybackControlsRowPresenter) {
- mResetControlsToPrimaryActionsPending = false;
- ((PlaybackControlsRowPresenter) vh.getPresenter()).showPrimaryActions(
- (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder());
- }
- }
-
- /**
- * Enables or disables view fading. If enabled,
- * the view will be faded in when the fragment starts,
- * and will fade out after a time period. The timeout
- * period is reset each time {@link #tickle} is called.
- *
- */
- public void setFadingEnabled(boolean enabled) {
- if (DEBUG) Log.v(TAG, "setFadingEnabled " + enabled);
- if (enabled != mFadingEnabled) {
- mFadingEnabled = enabled;
- if (mFadingEnabled) {
- if (isResumed() && mFadingStatus == IDLE
- && !sHandler.hasMessages(START_FADE_OUT, mFragmentReference)) {
- startFadeTimer();
- }
- } else {
- // Ensure fully opaque
- sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
- fade(true);
- }
- }
- }
-
- /**
- * Returns true if view fading is enabled.
- */
- public boolean isFadingEnabled() {
- return mFadingEnabled;
- }
-
- /**
- * Sets the listener to be called when fade in or out has completed.
- */
- public void setFadeCompleteListener(OnFadeCompleteListener listener) {
- mFadeCompleteListener = listener;
- }
-
- /**
- * Returns the listener to be called when fade in or out has completed.
- */
- public OnFadeCompleteListener getFadeCompleteListener() {
- return mFadeCompleteListener;
- }
-
- @Deprecated
- public interface InputEventHandler extends PlaybackControlGlue.InputEventHandler {
- }
-
- /**
- * Sets the input event handler.
- */
- @Deprecated
- public final void setInputEventHandler(InputEventHandler handler) {
- mInputEventHandler = handler;
- }
-
- /**
- * Returns the input event handler.
- */
- @Deprecated
- public final InputEventHandler getInputEventHandler() {
- return (InputEventHandler)mInputEventHandler;
- }
-
- /**
- * Sets the input event handler.
- */
- public final void setEventHandler(PlaybackControlGlue.InputEventHandler handler) {
- mInputEventHandler = handler;
- }
-
- /**
- * Returns the input event handler.
- */
- public final PlaybackControlGlue.InputEventHandler getEventHandler() {
- return mInputEventHandler;
- }
-
- /**
- * Tickles the playback controls. Fades in the view if it was faded out,
- * otherwise resets the fade out timer. Tickling on input events is handled
- * by the fragment.
- */
- public void tickle() {
- if (DEBUG) Log.v(TAG, "tickle enabled " + mFadingEnabled + " isResumed " + isResumed());
- if (!mFadingEnabled || !isResumed()) {
- return;
- }
- if (sHandler.hasMessages(START_FADE_OUT, mFragmentReference)) {
- // Restart the timer
- startFadeTimer();
- } else {
- fade(true);
- }
- }
-
- /**
- * Fades out the playback overlay immediately.
- */
- public void fadeOut() {
- sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
- fade(false);
- }
-
- /**
- * Sets the {@link PlaybackGlueHost.HostCallback}. Implementor of this interface will
- * take appropriate actions to take action when the hosting fragment starts/stops processing.
- */
- void setHostCallback(PlaybackGlueHost.HostCallback hostCallback) {
- this.mHostCallback = hostCallback;
- }
-
- @Override
- public void onStop() {
- if (mHostCallback != null) {
- mHostCallback.onHostStop();
- }
- super.onStop();
- }
-
- @Override
- public void onPause() {
- if (mHostCallback != null) {
- mHostCallback.onHostPause();
- }
- super.onPause();
- }
-
- private boolean areControlsHidden() {
- return mFadingStatus == IDLE && mBgAlpha == 0;
- }
-
- boolean onInterceptInputEvent(InputEvent event) {
- final boolean controlsHidden = areControlsHidden();
- if (DEBUG) Log.v(TAG, "onInterceptInputEvent hidden " + controlsHidden + " " + event);
- boolean consumeEvent = false;
- int keyCode = KeyEvent.KEYCODE_UNKNOWN;
-
- if (mInputEventHandler != null) {
- consumeEvent = mInputEventHandler.handleInputEvent(event);
- }
- if (event instanceof KeyEvent) {
- keyCode = ((KeyEvent) event).getKeyCode();
- }
-
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_CENTER:
- case KeyEvent.KEYCODE_DPAD_DOWN:
- case KeyEvent.KEYCODE_DPAD_UP:
- case KeyEvent.KEYCODE_DPAD_LEFT:
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- // Event may be consumed; regardless, if controls are hidden then these keys will
- // bring up the controls.
- if (controlsHidden) {
- consumeEvent = true;
- }
- tickle();
- break;
- case KeyEvent.KEYCODE_BACK:
- case KeyEvent.KEYCODE_ESCAPE:
- // If fading enabled and controls are not hidden, back will be consumed to fade
- // them out (even if the key was consumed by the handler).
- if (mFadingEnabled && !controlsHidden) {
- consumeEvent = true;
- sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
- fade(false);
- } else if (consumeEvent) {
- tickle();
- }
- break;
- default:
- if (consumeEvent) {
- tickle();
- }
- }
- return consumeEvent;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (mFadingEnabled) {
- setBgAlpha(0);
- fade(true);
- }
- getVerticalGridView().setOnTouchInterceptListener(mOnTouchInterceptListener);
- getVerticalGridView().setOnKeyInterceptListener(mOnKeyInterceptListener);
- if (mHostCallback != null) {
- mHostCallback.onHostResume();
- }
- }
-
- void startFadeTimer() {
- sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
- sHandler.sendMessageDelayed(sHandler.obtainMessage(START_FADE_OUT, mFragmentReference),
- mShowTimeMs);
- }
-
- private static ValueAnimator loadAnimator(Context context, int resId) {
- ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(context, resId);
- animator.setDuration(animator.getDuration() * ANIMATION_MULTIPLIER);
- return animator;
- }
-
- private void loadBgAnimator() {
- AnimatorUpdateListener listener = new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator arg0) {
- setBgAlpha((Integer) arg0.getAnimatedValue());
- }
- };
-
- Context context = FragmentUtil.getContext(this);
- mBgFadeInAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_in);
- mBgFadeInAnimator.addUpdateListener(listener);
- mBgFadeInAnimator.addListener(mFadeListener);
-
- mBgFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_out);
- mBgFadeOutAnimator.addUpdateListener(listener);
- mBgFadeOutAnimator.addListener(mFadeListener);
- }
-
- private TimeInterpolator mLogDecelerateInterpolator = new LogDecelerateInterpolator(100,0);
- private TimeInterpolator mLogAccelerateInterpolator = new LogAccelerateInterpolator(100,0);
-
- View getControlRowView() {
- if (getVerticalGridView() == null) {
- return null;
- }
- RecyclerView.ViewHolder vh = getVerticalGridView().findViewHolderForPosition(0);
- if (vh == null) {
- return null;
- }
- return vh.itemView;
- }
-
- private void loadControlRowAnimator() {
- final AnimatorListener listener = new AnimatorListener() {
- @Override
- void getViews(ArrayList<View> views) {
- View view = getControlRowView();
- if (view != null) {
- views.add(view);
- }
- }
- };
- final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator arg0) {
- View view = getControlRowView();
- if (view != null) {
- final float fraction = (Float) arg0.getAnimatedValue();
- if (DEBUG) Log.v(TAG, "fraction " + fraction);
- view.setAlpha(fraction);
- view.setTranslationY((float) mAnimationTranslateY * (1f - fraction));
- }
- }
- };
-
- Context context = FragmentUtil.getContext(this);
- mControlRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
- mControlRowFadeInAnimator.addUpdateListener(updateListener);
- mControlRowFadeInAnimator.addListener(listener);
- mControlRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
-
- mControlRowFadeOutAnimator = loadAnimator(context,
- R.animator.lb_playback_controls_fade_out);
- mControlRowFadeOutAnimator.addUpdateListener(updateListener);
- mControlRowFadeOutAnimator.addListener(listener);
- mControlRowFadeOutAnimator.setInterpolator(mLogAccelerateInterpolator);
- }
-
- private void loadOtherRowAnimator() {
- final AnimatorListener listener = new AnimatorListener() {
- @Override
- void getViews(ArrayList<View> views) {
- if (getVerticalGridView() == null) {
- return;
- }
- final int count = getVerticalGridView().getChildCount();
- for (int i = 0; i < count; i++) {
- View view = getVerticalGridView().getChildAt(i);
- if (view != null) {
- views.add(view);
- }
- }
- }
- };
- final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator arg0) {
- if (getVerticalGridView() == null) {
- return;
- }
- final float fraction = (Float) arg0.getAnimatedValue();
- for (View view : listener.mViews) {
- if (getVerticalGridView().getChildPosition(view) > 0) {
- view.setAlpha(fraction);
- view.setTranslationY((float) mAnimationTranslateY * (1f - fraction));
- }
- }
- }
- };
-
- Context context = FragmentUtil.getContext(this);
- mOtherRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
- mOtherRowFadeInAnimator.addListener(listener);
- mOtherRowFadeInAnimator.addUpdateListener(updateListener);
- mOtherRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
-
- mOtherRowFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_out);
- mOtherRowFadeOutAnimator.addListener(listener);
- mOtherRowFadeOutAnimator.addUpdateListener(updateListener);
- mOtherRowFadeOutAnimator.setInterpolator(new AccelerateInterpolator());
- }
-
- private void loadDescriptionAnimator() {
- AnimatorUpdateListener listener = new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator arg0) {
- if (getVerticalGridView() == null) {
- return;
- }
- ItemBridgeAdapter.ViewHolder adapterVh = (ItemBridgeAdapter.ViewHolder)
- getVerticalGridView().findViewHolderForPosition(0);
- if (adapterVh != null && adapterVh.getViewHolder()
- instanceof PlaybackControlsRowPresenter.ViewHolder) {
- final Presenter.ViewHolder vh = ((PlaybackControlsRowPresenter.ViewHolder)
- adapterVh.getViewHolder()).mDescriptionViewHolder;
- if (vh != null) {
- vh.view.setAlpha((Float) arg0.getAnimatedValue());
- }
- }
- }
- };
-
- Context context = FragmentUtil.getContext(this);
- mDescriptionFadeInAnimator = loadAnimator(context,
- R.animator.lb_playback_description_fade_in);
- mDescriptionFadeInAnimator.addUpdateListener(listener);
- mDescriptionFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
-
- mDescriptionFadeOutAnimator = loadAnimator(context,
- R.animator.lb_playback_description_fade_out);
- mDescriptionFadeOutAnimator.addUpdateListener(listener);
- }
-
- void fade(boolean fadeIn) {
- if (DEBUG) Log.v(TAG, "fade " + fadeIn);
- if (getView() == null) {
- return;
- }
- if ((fadeIn && mFadingStatus == IN) || (!fadeIn && mFadingStatus == OUT)) {
- if (DEBUG) Log.v(TAG, "requested fade in progress");
- return;
- }
- if ((fadeIn && mBgAlpha == 255) || (!fadeIn && mBgAlpha == 0)) {
- if (DEBUG) Log.v(TAG, "fade is no-op");
- return;
- }
-
- mAnimationTranslateY = getVerticalGridView().getSelectedPosition() == 0
- ? mMajorFadeTranslateY : mMinorFadeTranslateY;
-
- if (mFadingStatus == IDLE) {
- if (fadeIn) {
- mBgFadeInAnimator.start();
- mControlRowFadeInAnimator.start();
- mOtherRowFadeInAnimator.start();
- mDescriptionFadeInAnimator.start();
- } else {
- mBgFadeOutAnimator.start();
- mControlRowFadeOutAnimator.start();
- mOtherRowFadeOutAnimator.start();
- mDescriptionFadeOutAnimator.start();
- }
- } else {
- if (fadeIn) {
- mBgFadeOutAnimator.reverse();
- mControlRowFadeOutAnimator.reverse();
- mOtherRowFadeOutAnimator.reverse();
- mDescriptionFadeOutAnimator.reverse();
- } else {
- mBgFadeInAnimator.reverse();
- mControlRowFadeInAnimator.reverse();
- mOtherRowFadeInAnimator.reverse();
- mDescriptionFadeInAnimator.reverse();
- }
- }
- getView().announceForAccessibility(getString(fadeIn ? R.string.lb_playback_controls_shown
- : R.string.lb_playback_controls_hidden));
-
- // If fading in while control row is focused, set initial translationY so
- // views slide in from below.
- if (fadeIn && mFadingStatus == IDLE) {
- final int count = getVerticalGridView().getChildCount();
- for (int i = 0; i < count; i++) {
- getVerticalGridView().getChildAt(i).setTranslationY(mAnimationTranslateY);
- }
- }
-
- mFadingStatus = fadeIn ? IN : OUT;
- }
-
- /**
- * Sets the list of rows for the fragment.
- */
- @Override
- public void setAdapter(ObjectAdapter adapter) {
- if (getAdapter() != null) {
- getAdapter().unregisterObserver(mObserver);
- }
- super.setAdapter(adapter);
- if (adapter != null) {
- adapter.registerObserver(mObserver);
- }
- }
-
- @Override
- protected void setupPresenter(Presenter rowPresenter) {
- if (rowPresenter instanceof PlaybackRowPresenter) {
- if (rowPresenter.getFacet(ItemAlignmentFacet.class) == null) {
- ItemAlignmentFacet itemAlignment = new ItemAlignmentFacet();
- ItemAlignmentFacet.ItemAlignmentDef def =
- new ItemAlignmentFacet.ItemAlignmentDef();
- def.setItemAlignmentOffset(0);
- def.setItemAlignmentOffsetPercent(100);
- itemAlignment.setAlignmentDefs(new ItemAlignmentFacet.ItemAlignmentDef[]
- {def});
- rowPresenter.setFacet(ItemAlignmentFacet.class, itemAlignment);
- }
- } else {
- super.setupPresenter(rowPresenter);
- }
- }
-
- @Override
- void setVerticalGridViewLayout(VerticalGridView listview) {
- if (listview == null) {
- return;
- }
-
- // we set the base line of alignment to -paddingBottom
- listview.setWindowAlignmentOffset(-mPaddingBottom);
- listview.setWindowAlignmentOffsetPercent(
- VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
-
- // align other rows that arent the last to center of screen, since our baseline is
- // -mPaddingBottom, we need subtract that from mOtherRowsCenterToBottom.
- listview.setItemAlignmentOffset(mOtherRowsCenterToBottom - mPaddingBottom);
- listview.setItemAlignmentOffsetPercent(50);
-
- // Push last row to the bottom padding
- // Padding affects alignment when last row is focused
- listview.setPadding(listview.getPaddingLeft(), listview.getPaddingTop(),
- listview.getPaddingRight(), mPaddingBottom);
- listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_HIGH_EDGE);
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- mOtherRowsCenterToBottom = getResources()
- .getDimensionPixelSize(R.dimen.lb_playback_other_rows_center_to_bottom);
- mPaddingBottom =
- getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom);
- mBgDarkColor =
- getResources().getColor(R.color.lb_playback_controls_background_dark);
- mBgLightColor =
- getResources().getColor(R.color.lb_playback_controls_background_light);
- mShowTimeMs =
- getResources().getInteger(R.integer.lb_playback_controls_show_time_ms);
- mMajorFadeTranslateY =
- getResources().getDimensionPixelSize(R.dimen.lb_playback_major_fade_translate_y);
- mMinorFadeTranslateY =
- getResources().getDimensionPixelSize(R.dimen.lb_playback_minor_fade_translate_y);
-
- loadBgAnimator();
- loadControlRowAnimator();
- loadOtherRowAnimator();
- loadDescriptionAnimator();
- }
-
- /**
- * Sets the background type.
- *
- * @param type One of BG_LIGHT, BG_DARK, or BG_NONE.
- */
- public void setBackgroundType(int type) {
- switch (type) {
- case BG_LIGHT:
- case BG_DARK:
- case BG_NONE:
- if (type != mBackgroundType) {
- mBackgroundType = type;
- updateBackground();
- }
- break;
- default:
- throw new IllegalArgumentException("Invalid background type");
- }
- }
-
- /**
- * Returns the background type.
- */
- public int getBackgroundType() {
- return mBackgroundType;
- }
-
- private void updateBackground() {
- if (mRootView != null) {
- int color = mBgDarkColor;
- switch (mBackgroundType) {
- case BG_DARK: break;
- case BG_LIGHT: color = mBgLightColor; break;
- case BG_NONE: color = Color.TRANSPARENT; break;
- }
- mRootView.setBackground(new ColorDrawable(color));
- }
- }
-
- void updateControlsBottomSpace(ItemBridgeAdapter.ViewHolder vh) {
- // Add extra space between rows 0 and 1
- if (vh == null && getVerticalGridView() != null) {
- vh = (ItemBridgeAdapter.ViewHolder)
- getVerticalGridView().findViewHolderForPosition(0);
- }
- if (vh != null && vh.getPresenter() instanceof PlaybackControlsRowPresenter) {
- final int adapterSize = getAdapter() == null ? 0 : getAdapter().size();
- ((PlaybackControlsRowPresenter) vh.getPresenter()).showBottomSpace(
- (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder(),
- adapterSize > 1);
- }
- }
-
- private final ItemBridgeAdapter.AdapterListener mAdapterListener =
- new ItemBridgeAdapter.AdapterListener() {
- @Override
- public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder vh) {
- if (DEBUG) Log.v(TAG, "onAttachedToWindow " + vh.getViewHolder().view);
- if ((mFadingStatus == IDLE && mBgAlpha == 0) || mFadingStatus == OUT) {
- if (DEBUG) Log.v(TAG, "setting alpha to 0");
- vh.getViewHolder().view.setAlpha(0);
- }
- if (vh.getPosition() == 0 && mResetControlsToPrimaryActionsPending) {
- resetControlsToPrimaryActions(vh);
- }
- }
- @Override
- public void onDetachedFromWindow(ItemBridgeAdapter.ViewHolder vh) {
- if (DEBUG) Log.v(TAG, "onDetachedFromWindow " + vh.getViewHolder().view);
- // Reset animation state
- vh.getViewHolder().view.setAlpha(1f);
- vh.getViewHolder().view.setTranslationY(0);
- if (vh.getViewHolder() instanceof PlaybackControlsRowPresenter.ViewHolder) {
- Presenter.ViewHolder descriptionVh = ((PlaybackControlsRowPresenter.ViewHolder)
- vh.getViewHolder()).mDescriptionViewHolder;
- if (descriptionVh != null) {
- descriptionVh.view.setAlpha(1f);
- }
- }
- }
- @Override
- public void onBind(ItemBridgeAdapter.ViewHolder vh) {
- if (vh.getPosition() == 0) {
- updateControlsBottomSpace(vh);
- }
- }
- };
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- mRootView = super.onCreateView(inflater, container, savedInstanceState);
- mBgAlpha = 255;
- updateBackground();
- getRowsFragment().setExternalAdapterListener(mAdapterListener);
- return mRootView;
- }
-
- @Override
- public void onDestroyView() {
- mRootView = null;
- if (mHostCallback != null) {
- mHostCallback.onHostDestroy();
- }
- super.onDestroyView();
- }
-
- @Override
- public void onStart() {
- super.onStart();
- // Workaround problem VideoView forcing itself to focused, let controls take focus.
- getRowsFragment().getView().requestFocus();
- if (mHostCallback != null) {
- mHostCallback.onHostStart();
- }
- }
-
- private final DataObserver mObserver = new DataObserver() {
- @Override
- public void onChanged() {
- updateControlsBottomSpace(null);
- }
- };
-
- static abstract class AnimatorListener implements Animator.AnimatorListener {
- ArrayList<View> mViews = new ArrayList<View>();
- ArrayList<Integer> mLayerType = new ArrayList<Integer>();
-
- @Override
- public void onAnimationCancel(Animator animation) {
- }
- @Override
- public void onAnimationRepeat(Animator animation) {
- }
- @Override
- public void onAnimationStart(Animator animation) {
- getViews(mViews);
- for (View view : mViews) {
- mLayerType.add(view.getLayerType());
- view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- }
- }
- @Override
- public void onAnimationEnd(Animator animation) {
- for (int i = 0; i < mViews.size(); i++) {
- mViews.get(i).setLayerType(mLayerType.get(i), null);
- }
- mLayerType.clear();
- mViews.clear();
- }
- abstract void getViews(ArrayList<View> views);
-
- };
-}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
deleted file mode 100644
index d751320..0000000
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
+++ /dev/null
@@ -1,866 +0,0 @@
-// CHECKSTYLE:OFF Generated code
-/* This file is auto-generated from PlaybackOverlayFragment.java. DO NOT MODIFY. */
-
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package android.support.v17.leanback.app;
-
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.animation.TimeInterpolator;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.content.Context;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.support.v17.leanback.R;
-import android.support.v17.leanback.animation.LogAccelerateInterpolator;
-import android.support.v17.leanback.animation.LogDecelerateInterpolator;
-import android.support.v17.leanback.media.PlaybackGlueHost;
-import android.support.v17.leanback.widget.ItemAlignmentFacet;
-import android.support.v17.leanback.widget.ItemBridgeAdapter;
-import android.support.v17.leanback.widget.ObjectAdapter;
-import android.support.v17.leanback.widget.ObjectAdapter.DataObserver;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.PlaybackRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.PresenterSelector;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.support.v17.leanback.widget.VerticalGridView;
-import android.support.v7.widget.RecyclerView;
-import android.util.Log;
-import android.view.InputEvent;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AccelerateInterpolator;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-
-/**
- * A fragment for displaying playback controls and related content.
- * <p>
- * A PlaybackOverlaySupportFragment renders the elements of its {@link ObjectAdapter} as a set
- * of rows in a vertical list. The Adapter's {@link PresenterSelector} must maintain subclasses
- * of {@link RowPresenter}.
- * </p>
- * <p>
- * An instance of {@link android.support.v17.leanback.widget.PlaybackControlsRow} is expected to be
- * at position 0 in the adapter.
- * </p>
- * <p>
- * This class is now deprecated, please us
- * </p>
- * @deprecated Use {@link PlaybackSupportFragment}.
- */
-@Deprecated
-public class PlaybackOverlaySupportFragment extends DetailsSupportFragment {
-
- /**
- * No background.
- */
- public static final int BG_NONE = 0;
-
- /**
- * A dark translucent background.
- */
- public static final int BG_DARK = 1;
-
- /**
- * A light translucent background.
- */
- public static final int BG_LIGHT = 2;
-
- /**
- * Listener allowing the application to receive notification of fade in and/or fade out
- * completion events.
- */
- public static class OnFadeCompleteListener {
- public void onFadeInComplete() {
- }
- public void onFadeOutComplete() {
- }
- }
-
- static final String TAG = "PlaybackOF";
- static final boolean DEBUG = false;
- private static final int ANIMATION_MULTIPLIER = 1;
-
- static int START_FADE_OUT = 1;
-
- // Fading status
- static final int IDLE = 0;
- private static final int IN = 1;
- static final int OUT = 2;
-
- private int mOtherRowsCenterToBottom;
- private int mPaddingBottom;
- private View mRootView;
- private int mBackgroundType = BG_DARK;
- private int mBgDarkColor;
- private int mBgLightColor;
- private int mShowTimeMs;
- private int mMajorFadeTranslateY, mMinorFadeTranslateY;
- int mAnimationTranslateY;
- OnFadeCompleteListener mFadeCompleteListener;
- private PlaybackControlGlue.InputEventHandler mInputEventHandler;
- boolean mFadingEnabled = true;
- int mFadingStatus = IDLE;
- int mBgAlpha;
- private ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator;
- private ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator;
- private ValueAnimator mDescriptionFadeInAnimator, mDescriptionFadeOutAnimator;
- private ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator;
- boolean mResetControlsToPrimaryActionsPending;
- PlaybackGlueHost.HostCallback mHostCallback;
-
- private final Animator.AnimatorListener mFadeListener =
- new Animator.AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {
- enableVerticalGridAnimations(false);
- }
- @Override
- public void onAnimationRepeat(Animator animation) {
- }
- @Override
- public void onAnimationCancel(Animator animation) {
- }
- @Override
- public void onAnimationEnd(Animator animation) {
- if (DEBUG) Log.v(TAG, "onAnimationEnd " + mBgAlpha);
- if (mBgAlpha > 0) {
- enableVerticalGridAnimations(true);
- startFadeTimer();
- if (mFadeCompleteListener != null) {
- mFadeCompleteListener.onFadeInComplete();
- }
- } else {
- VerticalGridView verticalView = getVerticalGridView();
- // reset focus to the primary actions only if the selected row was the controls row
- if (verticalView != null && verticalView.getSelectedPosition() == 0) {
- resetControlsToPrimaryActions(null);
- }
- if (mFadeCompleteListener != null) {
- mFadeCompleteListener.onFadeOutComplete();
- }
- }
- mFadingStatus = IDLE;
- }
- };
-
- static class FadeHandler extends Handler {
- @Override
- public void handleMessage(Message message) {
- PlaybackOverlaySupportFragment fragment;
- if (message.what == START_FADE_OUT) {
- fragment = ((WeakReference<PlaybackOverlaySupportFragment>) message.obj).get();
- if (fragment != null && fragment.mFadingEnabled) {
- fragment.fade(false);
- }
- }
- }
- }
-
- static final Handler sHandler = new FadeHandler();
-
- final WeakReference<PlaybackOverlaySupportFragment> mFragmentReference = new WeakReference(this);
-
- private final VerticalGridView.OnTouchInterceptListener mOnTouchInterceptListener =
- new VerticalGridView.OnTouchInterceptListener() {
- @Override
- public boolean onInterceptTouchEvent(MotionEvent event) {
- return onInterceptInputEvent(event);
- }
- };
-
- private final VerticalGridView.OnKeyInterceptListener mOnKeyInterceptListener =
- new VerticalGridView.OnKeyInterceptListener() {
- @Override
- public boolean onInterceptKeyEvent(KeyEvent event) {
- return onInterceptInputEvent(event);
- }
- };
-
- void setBgAlpha(int alpha) {
- mBgAlpha = alpha;
- if (mRootView != null) {
- mRootView.getBackground().setAlpha(alpha);
- }
- }
-
- void enableVerticalGridAnimations(boolean enable) {
- if (getVerticalGridView() != null) {
- getVerticalGridView().setAnimateChildLayout(enable);
- }
- }
-
- void resetControlsToPrimaryActions(ItemBridgeAdapter.ViewHolder vh) {
- if (vh == null && getVerticalGridView() != null) {
- vh = (ItemBridgeAdapter.ViewHolder) getVerticalGridView().findViewHolderForPosition(0);
- }
- if (vh == null) {
- mResetControlsToPrimaryActionsPending = true;
- } else if (vh.getPresenter() instanceof PlaybackControlsRowPresenter) {
- mResetControlsToPrimaryActionsPending = false;
- ((PlaybackControlsRowPresenter) vh.getPresenter()).showPrimaryActions(
- (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder());
- }
- }
-
- /**
- * Enables or disables view fading. If enabled,
- * the view will be faded in when the fragment starts,
- * and will fade out after a time period. The timeout
- * period is reset each time {@link #tickle} is called.
- *
- */
- public void setFadingEnabled(boolean enabled) {
- if (DEBUG) Log.v(TAG, "setFadingEnabled " + enabled);
- if (enabled != mFadingEnabled) {
- mFadingEnabled = enabled;
- if (mFadingEnabled) {
- if (isResumed() && mFadingStatus == IDLE
- && !sHandler.hasMessages(START_FADE_OUT, mFragmentReference)) {
- startFadeTimer();
- }
- } else {
- // Ensure fully opaque
- sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
- fade(true);
- }
- }
- }
-
- /**
- * Returns true if view fading is enabled.
- */
- public boolean isFadingEnabled() {
- return mFadingEnabled;
- }
-
- /**
- * Sets the listener to be called when fade in or out has completed.
- */
- public void setFadeCompleteListener(OnFadeCompleteListener listener) {
- mFadeCompleteListener = listener;
- }
-
- /**
- * Returns the listener to be called when fade in or out has completed.
- */
- public OnFadeCompleteListener getFadeCompleteListener() {
- return mFadeCompleteListener;
- }
-
- @Deprecated
- public interface InputEventHandler extends PlaybackControlGlue.InputEventHandler {
- }
-
- /**
- * Sets the input event handler.
- */
- @Deprecated
- public final void setInputEventHandler(InputEventHandler handler) {
- mInputEventHandler = handler;
- }
-
- /**
- * Returns the input event handler.
- */
- @Deprecated
- public final InputEventHandler getInputEventHandler() {
- return (InputEventHandler)mInputEventHandler;
- }
-
- /**
- * Sets the input event handler.
- */
- public final void setEventHandler(PlaybackControlGlue.InputEventHandler handler) {
- mInputEventHandler = handler;
- }
-
- /**
- * Returns the input event handler.
- */
- public final PlaybackControlGlue.InputEventHandler getEventHandler() {
- return mInputEventHandler;
- }
-
- /**
- * Tickles the playback controls. Fades in the view if it was faded out,
- * otherwise resets the fade out timer. Tickling on input events is handled
- * by the fragment.
- */
- public void tickle() {
- if (DEBUG) Log.v(TAG, "tickle enabled " + mFadingEnabled + " isResumed " + isResumed());
- if (!mFadingEnabled || !isResumed()) {
- return;
- }
- if (sHandler.hasMessages(START_FADE_OUT, mFragmentReference)) {
- // Restart the timer
- startFadeTimer();
- } else {
- fade(true);
- }
- }
-
- /**
- * Fades out the playback overlay immediately.
- */
- public void fadeOut() {
- sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
- fade(false);
- }
-
- /**
- * Sets the {@link PlaybackGlueHost.HostCallback}. Implementor of this interface will
- * take appropriate actions to take action when the hosting fragment starts/stops processing.
- */
- void setHostCallback(PlaybackGlueHost.HostCallback hostCallback) {
- this.mHostCallback = hostCallback;
- }
-
- @Override
- public void onStop() {
- if (mHostCallback != null) {
- mHostCallback.onHostStop();
- }
- super.onStop();
- }
-
- @Override
- public void onPause() {
- if (mHostCallback != null) {
- mHostCallback.onHostPause();
- }
- super.onPause();
- }
-
- private boolean areControlsHidden() {
- return mFadingStatus == IDLE && mBgAlpha == 0;
- }
-
- boolean onInterceptInputEvent(InputEvent event) {
- final boolean controlsHidden = areControlsHidden();
- if (DEBUG) Log.v(TAG, "onInterceptInputEvent hidden " + controlsHidden + " " + event);
- boolean consumeEvent = false;
- int keyCode = KeyEvent.KEYCODE_UNKNOWN;
-
- if (mInputEventHandler != null) {
- consumeEvent = mInputEventHandler.handleInputEvent(event);
- }
- if (event instanceof KeyEvent) {
- keyCode = ((KeyEvent) event).getKeyCode();
- }
-
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_CENTER:
- case KeyEvent.KEYCODE_DPAD_DOWN:
- case KeyEvent.KEYCODE_DPAD_UP:
- case KeyEvent.KEYCODE_DPAD_LEFT:
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- // Event may be consumed; regardless, if controls are hidden then these keys will
- // bring up the controls.
- if (controlsHidden) {
- consumeEvent = true;
- }
- tickle();
- break;
- case KeyEvent.KEYCODE_BACK:
- case KeyEvent.KEYCODE_ESCAPE:
- // If fading enabled and controls are not hidden, back will be consumed to fade
- // them out (even if the key was consumed by the handler).
- if (mFadingEnabled && !controlsHidden) {
- consumeEvent = true;
- sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
- fade(false);
- } else if (consumeEvent) {
- tickle();
- }
- break;
- default:
- if (consumeEvent) {
- tickle();
- }
- }
- return consumeEvent;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (mFadingEnabled) {
- setBgAlpha(0);
- fade(true);
- }
- getVerticalGridView().setOnTouchInterceptListener(mOnTouchInterceptListener);
- getVerticalGridView().setOnKeyInterceptListener(mOnKeyInterceptListener);
- if (mHostCallback != null) {
- mHostCallback.onHostResume();
- }
- }
-
- void startFadeTimer() {
- sHandler.removeMessages(START_FADE_OUT, mFragmentReference);
- sHandler.sendMessageDelayed(sHandler.obtainMessage(START_FADE_OUT, mFragmentReference),
- mShowTimeMs);
- }
-
- private static ValueAnimator loadAnimator(Context context, int resId) {
- ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(context, resId);
- animator.setDuration(animator.getDuration() * ANIMATION_MULTIPLIER);
- return animator;
- }
-
- private void loadBgAnimator() {
- AnimatorUpdateListener listener = new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator arg0) {
- setBgAlpha((Integer) arg0.getAnimatedValue());
- }
- };
-
- Context context = getContext();
- mBgFadeInAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_in);
- mBgFadeInAnimator.addUpdateListener(listener);
- mBgFadeInAnimator.addListener(mFadeListener);
-
- mBgFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_bg_fade_out);
- mBgFadeOutAnimator.addUpdateListener(listener);
- mBgFadeOutAnimator.addListener(mFadeListener);
- }
-
- private TimeInterpolator mLogDecelerateInterpolator = new LogDecelerateInterpolator(100,0);
- private TimeInterpolator mLogAccelerateInterpolator = new LogAccelerateInterpolator(100,0);
-
- View getControlRowView() {
- if (getVerticalGridView() == null) {
- return null;
- }
- RecyclerView.ViewHolder vh = getVerticalGridView().findViewHolderForPosition(0);
- if (vh == null) {
- return null;
- }
- return vh.itemView;
- }
-
- private void loadControlRowAnimator() {
- final AnimatorListener listener = new AnimatorListener() {
- @Override
- void getViews(ArrayList<View> views) {
- View view = getControlRowView();
- if (view != null) {
- views.add(view);
- }
- }
- };
- final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator arg0) {
- View view = getControlRowView();
- if (view != null) {
- final float fraction = (Float) arg0.getAnimatedValue();
- if (DEBUG) Log.v(TAG, "fraction " + fraction);
- view.setAlpha(fraction);
- view.setTranslationY((float) mAnimationTranslateY * (1f - fraction));
- }
- }
- };
-
- Context context = getContext();
- mControlRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
- mControlRowFadeInAnimator.addUpdateListener(updateListener);
- mControlRowFadeInAnimator.addListener(listener);
- mControlRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
-
- mControlRowFadeOutAnimator = loadAnimator(context,
- R.animator.lb_playback_controls_fade_out);
- mControlRowFadeOutAnimator.addUpdateListener(updateListener);
- mControlRowFadeOutAnimator.addListener(listener);
- mControlRowFadeOutAnimator.setInterpolator(mLogAccelerateInterpolator);
- }
-
- private void loadOtherRowAnimator() {
- final AnimatorListener listener = new AnimatorListener() {
- @Override
- void getViews(ArrayList<View> views) {
- if (getVerticalGridView() == null) {
- return;
- }
- final int count = getVerticalGridView().getChildCount();
- for (int i = 0; i < count; i++) {
- View view = getVerticalGridView().getChildAt(i);
- if (view != null) {
- views.add(view);
- }
- }
- }
- };
- final AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator arg0) {
- if (getVerticalGridView() == null) {
- return;
- }
- final float fraction = (Float) arg0.getAnimatedValue();
- for (View view : listener.mViews) {
- if (getVerticalGridView().getChildPosition(view) > 0) {
- view.setAlpha(fraction);
- view.setTranslationY((float) mAnimationTranslateY * (1f - fraction));
- }
- }
- }
- };
-
- Context context = getContext();
- mOtherRowFadeInAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_in);
- mOtherRowFadeInAnimator.addListener(listener);
- mOtherRowFadeInAnimator.addUpdateListener(updateListener);
- mOtherRowFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
-
- mOtherRowFadeOutAnimator = loadAnimator(context, R.animator.lb_playback_controls_fade_out);
- mOtherRowFadeOutAnimator.addListener(listener);
- mOtherRowFadeOutAnimator.addUpdateListener(updateListener);
- mOtherRowFadeOutAnimator.setInterpolator(new AccelerateInterpolator());
- }
-
- private void loadDescriptionAnimator() {
- AnimatorUpdateListener listener = new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator arg0) {
- if (getVerticalGridView() == null) {
- return;
- }
- ItemBridgeAdapter.ViewHolder adapterVh = (ItemBridgeAdapter.ViewHolder)
- getVerticalGridView().findViewHolderForPosition(0);
- if (adapterVh != null && adapterVh.getViewHolder()
- instanceof PlaybackControlsRowPresenter.ViewHolder) {
- final Presenter.ViewHolder vh = ((PlaybackControlsRowPresenter.ViewHolder)
- adapterVh.getViewHolder()).mDescriptionViewHolder;
- if (vh != null) {
- vh.view.setAlpha((Float) arg0.getAnimatedValue());
- }
- }
- }
- };
-
- Context context = getContext();
- mDescriptionFadeInAnimator = loadAnimator(context,
- R.animator.lb_playback_description_fade_in);
- mDescriptionFadeInAnimator.addUpdateListener(listener);
- mDescriptionFadeInAnimator.setInterpolator(mLogDecelerateInterpolator);
-
- mDescriptionFadeOutAnimator = loadAnimator(context,
- R.animator.lb_playback_description_fade_out);
- mDescriptionFadeOutAnimator.addUpdateListener(listener);
- }
-
- void fade(boolean fadeIn) {
- if (DEBUG) Log.v(TAG, "fade " + fadeIn);
- if (getView() == null) {
- return;
- }
- if ((fadeIn && mFadingStatus == IN) || (!fadeIn && mFadingStatus == OUT)) {
- if (DEBUG) Log.v(TAG, "requested fade in progress");
- return;
- }
- if ((fadeIn && mBgAlpha == 255) || (!fadeIn && mBgAlpha == 0)) {
- if (DEBUG) Log.v(TAG, "fade is no-op");
- return;
- }
-
- mAnimationTranslateY = getVerticalGridView().getSelectedPosition() == 0
- ? mMajorFadeTranslateY : mMinorFadeTranslateY;
-
- if (mFadingStatus == IDLE) {
- if (fadeIn) {
- mBgFadeInAnimator.start();
- mControlRowFadeInAnimator.start();
- mOtherRowFadeInAnimator.start();
- mDescriptionFadeInAnimator.start();
- } else {
- mBgFadeOutAnimator.start();
- mControlRowFadeOutAnimator.start();
- mOtherRowFadeOutAnimator.start();
- mDescriptionFadeOutAnimator.start();
- }
- } else {
- if (fadeIn) {
- mBgFadeOutAnimator.reverse();
- mControlRowFadeOutAnimator.reverse();
- mOtherRowFadeOutAnimator.reverse();
- mDescriptionFadeOutAnimator.reverse();
- } else {
- mBgFadeInAnimator.reverse();
- mControlRowFadeInAnimator.reverse();
- mOtherRowFadeInAnimator.reverse();
- mDescriptionFadeInAnimator.reverse();
- }
- }
- getView().announceForAccessibility(getString(fadeIn ? R.string.lb_playback_controls_shown
- : R.string.lb_playback_controls_hidden));
-
- // If fading in while control row is focused, set initial translationY so
- // views slide in from below.
- if (fadeIn && mFadingStatus == IDLE) {
- final int count = getVerticalGridView().getChildCount();
- for (int i = 0; i < count; i++) {
- getVerticalGridView().getChildAt(i).setTranslationY(mAnimationTranslateY);
- }
- }
-
- mFadingStatus = fadeIn ? IN : OUT;
- }
-
- /**
- * Sets the list of rows for the fragment.
- */
- @Override
- public void setAdapter(ObjectAdapter adapter) {
- if (getAdapter() != null) {
- getAdapter().unregisterObserver(mObserver);
- }
- super.setAdapter(adapter);
- if (adapter != null) {
- adapter.registerObserver(mObserver);
- }
- }
-
- @Override
- protected void setupPresenter(Presenter rowPresenter) {
- if (rowPresenter instanceof PlaybackRowPresenter) {
- if (rowPresenter.getFacet(ItemAlignmentFacet.class) == null) {
- ItemAlignmentFacet itemAlignment = new ItemAlignmentFacet();
- ItemAlignmentFacet.ItemAlignmentDef def =
- new ItemAlignmentFacet.ItemAlignmentDef();
- def.setItemAlignmentOffset(0);
- def.setItemAlignmentOffsetPercent(100);
- itemAlignment.setAlignmentDefs(new ItemAlignmentFacet.ItemAlignmentDef[]
- {def});
- rowPresenter.setFacet(ItemAlignmentFacet.class, itemAlignment);
- }
- } else {
- super.setupPresenter(rowPresenter);
- }
- }
-
- @Override
- void setVerticalGridViewLayout(VerticalGridView listview) {
- if (listview == null) {
- return;
- }
-
- // we set the base line of alignment to -paddingBottom
- listview.setWindowAlignmentOffset(-mPaddingBottom);
- listview.setWindowAlignmentOffsetPercent(
- VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
-
- // align other rows that arent the last to center of screen, since our baseline is
- // -mPaddingBottom, we need subtract that from mOtherRowsCenterToBottom.
- listview.setItemAlignmentOffset(mOtherRowsCenterToBottom - mPaddingBottom);
- listview.setItemAlignmentOffsetPercent(50);
-
- // Push last row to the bottom padding
- // Padding affects alignment when last row is focused
- listview.setPadding(listview.getPaddingLeft(), listview.getPaddingTop(),
- listview.getPaddingRight(), mPaddingBottom);
- listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_HIGH_EDGE);
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- mOtherRowsCenterToBottom = getResources()
- .getDimensionPixelSize(R.dimen.lb_playback_other_rows_center_to_bottom);
- mPaddingBottom =
- getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom);
- mBgDarkColor =
- getResources().getColor(R.color.lb_playback_controls_background_dark);
- mBgLightColor =
- getResources().getColor(R.color.lb_playback_controls_background_light);
- mShowTimeMs =
- getResources().getInteger(R.integer.lb_playback_controls_show_time_ms);
- mMajorFadeTranslateY =
- getResources().getDimensionPixelSize(R.dimen.lb_playback_major_fade_translate_y);
- mMinorFadeTranslateY =
- getResources().getDimensionPixelSize(R.dimen.lb_playback_minor_fade_translate_y);
-
- loadBgAnimator();
- loadControlRowAnimator();
- loadOtherRowAnimator();
- loadDescriptionAnimator();
- }
-
- /**
- * Sets the background type.
- *
- * @param type One of BG_LIGHT, BG_DARK, or BG_NONE.
- */
- public void setBackgroundType(int type) {
- switch (type) {
- case BG_LIGHT:
- case BG_DARK:
- case BG_NONE:
- if (type != mBackgroundType) {
- mBackgroundType = type;
- updateBackground();
- }
- break;
- default:
- throw new IllegalArgumentException("Invalid background type");
- }
- }
-
- /**
- * Returns the background type.
- */
- public int getBackgroundType() {
- return mBackgroundType;
- }
-
- private void updateBackground() {
- if (mRootView != null) {
- int color = mBgDarkColor;
- switch (mBackgroundType) {
- case BG_DARK: break;
- case BG_LIGHT: color = mBgLightColor; break;
- case BG_NONE: color = Color.TRANSPARENT; break;
- }
- mRootView.setBackground(new ColorDrawable(color));
- }
- }
-
- void updateControlsBottomSpace(ItemBridgeAdapter.ViewHolder vh) {
- // Add extra space between rows 0 and 1
- if (vh == null && getVerticalGridView() != null) {
- vh = (ItemBridgeAdapter.ViewHolder)
- getVerticalGridView().findViewHolderForPosition(0);
- }
- if (vh != null && vh.getPresenter() instanceof PlaybackControlsRowPresenter) {
- final int adapterSize = getAdapter() == null ? 0 : getAdapter().size();
- ((PlaybackControlsRowPresenter) vh.getPresenter()).showBottomSpace(
- (PlaybackControlsRowPresenter.ViewHolder) vh.getViewHolder(),
- adapterSize > 1);
- }
- }
-
- private final ItemBridgeAdapter.AdapterListener mAdapterListener =
- new ItemBridgeAdapter.AdapterListener() {
- @Override
- public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder vh) {
- if (DEBUG) Log.v(TAG, "onAttachedToWindow " + vh.getViewHolder().view);
- if ((mFadingStatus == IDLE && mBgAlpha == 0) || mFadingStatus == OUT) {
- if (DEBUG) Log.v(TAG, "setting alpha to 0");
- vh.getViewHolder().view.setAlpha(0);
- }
- if (vh.getPosition() == 0 && mResetControlsToPrimaryActionsPending) {
- resetControlsToPrimaryActions(vh);
- }
- }
- @Override
- public void onDetachedFromWindow(ItemBridgeAdapter.ViewHolder vh) {
- if (DEBUG) Log.v(TAG, "onDetachedFromWindow " + vh.getViewHolder().view);
- // Reset animation state
- vh.getViewHolder().view.setAlpha(1f);
- vh.getViewHolder().view.setTranslationY(0);
- if (vh.getViewHolder() instanceof PlaybackControlsRowPresenter.ViewHolder) {
- Presenter.ViewHolder descriptionVh = ((PlaybackControlsRowPresenter.ViewHolder)
- vh.getViewHolder()).mDescriptionViewHolder;
- if (descriptionVh != null) {
- descriptionVh.view.setAlpha(1f);
- }
- }
- }
- @Override
- public void onBind(ItemBridgeAdapter.ViewHolder vh) {
- if (vh.getPosition() == 0) {
- updateControlsBottomSpace(vh);
- }
- }
- };
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- mRootView = super.onCreateView(inflater, container, savedInstanceState);
- mBgAlpha = 255;
- updateBackground();
- getRowsSupportFragment().setExternalAdapterListener(mAdapterListener);
- return mRootView;
- }
-
- @Override
- public void onDestroyView() {
- mRootView = null;
- if (mHostCallback != null) {
- mHostCallback.onHostDestroy();
- }
- super.onDestroyView();
- }
-
- @Override
- public void onStart() {
- super.onStart();
- // Workaround problem VideoView forcing itself to focused, let controls take focus.
- getRowsSupportFragment().getView().requestFocus();
- if (mHostCallback != null) {
- mHostCallback.onHostStart();
- }
- }
-
- private final DataObserver mObserver = new DataObserver() {
- @Override
- public void onChanged() {
- updateControlsBottomSpace(null);
- }
- };
-
- static abstract class AnimatorListener implements Animator.AnimatorListener {
- ArrayList<View> mViews = new ArrayList<View>();
- ArrayList<Integer> mLayerType = new ArrayList<Integer>();
-
- @Override
- public void onAnimationCancel(Animator animation) {
- }
- @Override
- public void onAnimationRepeat(Animator animation) {
- }
- @Override
- public void onAnimationStart(Animator animation) {
- getViews(mViews);
- for (View view : mViews) {
- mLayerType.add(view.getLayerType());
- view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- }
- }
- @Override
- public void onAnimationEnd(Animator animation) {
- for (int i = 0; i < mViews.size(); i++) {
- mViews.get(i).setLayerType(mLayerType.get(i), null);
- }
- mLayerType.clear();
- mViews.clear();
- }
- abstract void getViews(ArrayList<View> views);
-
- };
-}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/RowsFragment.java b/v17/leanback/src/android/support/v17/leanback/app/RowsFragment.java
index 46ad417..a008ad6 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/RowsFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/RowsFragment.java
@@ -19,6 +19,8 @@
import android.animation.TimeAnimator;
import android.animation.TimeAnimator.TimeListener;
import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.v17.leanback.R;
import android.support.v17.leanback.widget.BaseOnItemViewClickedListener;
import android.support.v17.leanback.widget.BaseOnItemViewSelectedListener;
@@ -288,7 +290,7 @@
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
if (DEBUG) Log.v(TAG, "onViewCreated");
super.onViewCreated(view, savedInstanceState);
// Align the top edge of child with id row_content.
diff --git a/v17/leanback/src/android/support/v17/leanback/app/SearchFragment.java b/v17/leanback/src/android/support/v17/leanback/app/SearchFragment.java
index 8e99bd3..2154ff2 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/SearchFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/SearchFragment.java
@@ -55,12 +55,11 @@
* into a {@link RowsFragment}, in the same way that they are in a {@link
* BrowseFragment}.
*
- * <p>If you do not supply a callback via
- * {@link #setSpeechRecognitionCallback(SpeechRecognitionCallback)}, an internal speech
- * recognizer will be used for which your application will need to declare
+ * <p>A SpeechRecognizer object will be created for which your application will need to declare
* android.permission.RECORD_AUDIO in AndroidManifest file. If app's target version is >= 23 and
* the device version is >= 23, a permission dialog will show first time using speech recognition.
* 0 will be used as requestCode in requestPermissions() call.
+ * {@link #setSpeechRecognitionCallback(SpeechRecognitionCallback)} is deprecated.
* </p>
* <p>
* Speech recognition is automatically started when fragment is created, but
@@ -579,8 +578,11 @@
/**
* Sets this callback to have the fragment pass speech recognition requests
- * to the activity rather than using an internal recognizer.
+ * to the activity rather than using a SpeechRecognizer object.
+ * @deprecated Launching voice recognition activity is no longer supported. App should declare
+ * android.permission.RECORD_AUDIO in AndroidManifest file.
*/
+ @Deprecated
public void setSpeechRecognitionCallback(SpeechRecognitionCallback callback) {
mSpeechRecognitionCallback = callback;
if (mSearchBar != null) {
diff --git a/v17/leanback/src/android/support/v17/leanback/app/SearchSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/SearchSupportFragment.java
index e26f5ba..ed2a679 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/SearchSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/SearchSupportFragment.java
@@ -52,12 +52,11 @@
* into a {@link RowsSupportFragment}, in the same way that they are in a {@link
* BrowseSupportFragment}.
*
- * <p>If you do not supply a callback via
- * {@link #setSpeechRecognitionCallback(SpeechRecognitionCallback)}, an internal speech
- * recognizer will be used for which your application will need to declare
+ * <p>A SpeechRecognizer object will be created for which your application will need to declare
* android.permission.RECORD_AUDIO in AndroidManifest file. If app's target version is >= 23 and
* the device version is >= 23, a permission dialog will show first time using speech recognition.
* 0 will be used as requestCode in requestPermissions() call.
+ * {@link #setSpeechRecognitionCallback(SpeechRecognitionCallback)} is deprecated.
* </p>
* <p>
* Speech recognition is automatically started when fragment is created, but
@@ -576,8 +575,11 @@
/**
* Sets this callback to have the fragment pass speech recognition requests
- * to the activity rather than using an internal recognizer.
+ * to the activity rather than using a SpeechRecognizer object.
+ * @deprecated Launching voice recognition activity is no longer supported. App should declare
+ * android.permission.RECORD_AUDIO in AndroidManifest file.
*/
+ @Deprecated
public void setSpeechRecognitionCallback(SpeechRecognitionCallback callback) {
mSpeechRecognitionCallback = callback;
if (mSearchBar != null) {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ActionPresenterSelector.java b/v17/leanback/src/android/support/v17/leanback/widget/ActionPresenterSelector.java
index 1ced4d4..a018c2e 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ActionPresenterSelector.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ActionPresenterSelector.java
@@ -55,43 +55,13 @@
}
}
- static class OneLineActionPresenter extends Presenter {
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent) {
- View v = LayoutInflater.from(parent.getContext())
- .inflate(R.layout.lb_action_1_line, parent, false);
- return new ActionViewHolder(v, parent.getLayoutDirection());
- }
-
+ abstract static class ActionPresenter extends Presenter {
@Override
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
Action action = (Action) item;
ActionViewHolder vh = (ActionViewHolder) viewHolder;
vh.mAction = action;
- vh.mButton.setText(action.getLabel1());
- }
-
- @Override
- public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
- ((ActionViewHolder) viewHolder).mAction = null;
- }
- }
-
- static class TwoLineActionPresenter extends Presenter {
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent) {
- View v = LayoutInflater.from(parent.getContext())
- .inflate(R.layout.lb_action_2_lines, parent, false);
- return new ActionViewHolder(v, parent.getLayoutDirection());
- }
-
- @Override
- public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
- Action action = (Action) item;
- ActionViewHolder vh = (ActionViewHolder) viewHolder;
Drawable icon = action.getIcon();
- vh.mAction = action;
-
if (icon != null) {
final int startPadding = vh.view.getResources()
.getDimensionPixelSize(R.dimen.lb_action_with_icon_padding_start);
@@ -108,6 +78,47 @@
} else {
vh.mButton.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
}
+ }
+
+ @Override
+ public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
+ ActionViewHolder vh = (ActionViewHolder) viewHolder;
+ vh.mButton.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
+ vh.view.setPadding(0, 0, 0, 0);
+ vh.mAction = null;
+ }
+ }
+
+ static class OneLineActionPresenter extends ActionPresenter {
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent) {
+ View v = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.lb_action_1_line, parent, false);
+ return new ActionViewHolder(v, parent.getLayoutDirection());
+ }
+
+ @Override
+ public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
+ super.onBindViewHolder(viewHolder, item);
+ ActionViewHolder vh = ((ActionViewHolder) viewHolder);
+ Action action = (Action) item;
+ vh.mButton.setText(action.getLabel1());
+ }
+ }
+
+ static class TwoLineActionPresenter extends ActionPresenter {
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent) {
+ View v = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.lb_action_2_lines, parent, false);
+ return new ActionViewHolder(v, parent.getLayoutDirection());
+ }
+
+ @Override
+ public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
+ super.onBindViewHolder(viewHolder, item);
+ Action action = (Action) item;
+ ActionViewHolder vh = (ActionViewHolder) viewHolder;
CharSequence line1 = action.getLabel1();
CharSequence line2 = action.getLabel2();
@@ -119,13 +130,5 @@
vh.mButton.setText(line1 + "\n" + line2);
}
}
-
- @Override
- public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
- ActionViewHolder vh = (ActionViewHolder) viewHolder;
- vh.mButton.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
- vh.view.setPadding(0, 0, 0, 0);
- vh.mAction = null;
- }
}
}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowPresenter.java
index 82cfa79..000db3c 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowPresenter.java
@@ -32,7 +32,7 @@
/**
* A PlaybackControlsRowPresenter renders a {@link PlaybackControlsRow} to display a
* series of playback control buttons. Typically this row will be the first row in a fragment
- * such as the {@link android.support.v17.leanback.app.PlaybackOverlayFragment}.
+ * such as the {@link android.support.v17.leanback.app.PlaybackFragment}.
*
* <p>The detailed description is rendered using a {@link Presenter} passed in
* {@link #PlaybackControlsRowPresenter(Presenter)}. Typically this will be an instance of
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/SearchBar.java b/v17/leanback/src/android/support/v17/leanback/widget/SearchBar.java
index 18f608e..9849341 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/SearchBar.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/SearchBar.java
@@ -495,7 +495,12 @@
/**
* Sets the speech recognition callback.
+ *
+ * @deprecated Launching voice recognition activity is no longer supported. App should declare
+ * android.permission.RECORD_AUDIO in AndroidManifest file. See details in
+ * {@link android.support.v17.leanback.app.SearchSupportFragment}.
*/
+ @Deprecated
public void setSpeechRecognitionCallback(SpeechRecognitionCallback request) {
mSpeechRecognitionCallback = request;
if (mSpeechRecognitionCallback != null && mSpeechRecognizer != null) {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/SpeechRecognitionCallback.java b/v17/leanback/src/android/support/v17/leanback/widget/SpeechRecognitionCallback.java
index 02b0990..173444d 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/SpeechRecognitionCallback.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/SpeechRecognitionCallback.java
@@ -15,7 +15,12 @@
/**
* Interface for receiving notification that speech recognition should be initiated.
+ *
+ * @deprecated Launching voice recognition activity is no longer supported. App should declare
+ * android.permission.RECORD_AUDIO in AndroidManifest file. See details in
+ * {@link android.support.v17.leanback.app.SearchSupportFragment}.
*/
+@Deprecated
public interface SpeechRecognitionCallback {
/**
* Method invoked when speech recognition should be initiated.
diff --git a/v17/leanback/tests/generatev4.py b/v17/leanback/tests/generatev4.py
index 9e4f935..d87ff6f 100755
--- a/v17/leanback/tests/generatev4.py
+++ b/v17/leanback/tests/generatev4.py
@@ -166,18 +166,3 @@
file.close()
outfile.close()
-####### generate glue support test #######
-
-print "copy PlaybackControlGlueTest to PlaybackControlSupportGlueTest"
-file = open('java/android/support/v17/leanback/app/PlaybackControlGlueTest.java', 'r')
-outfile = open('java/android/support/v17/leanback/app/PlaybackControlSupportGlueTest.java', 'w')
-outfile.write("// CHECKSTYLE:OFF Generated code\n")
-outfile.write("/* This file is auto-generated from PlaybackControlGlueTest.java. DO NOT MODIFY. */\n\n")
-for line in file:
- line = line.replace('PlaybackControlGlue', 'PlaybackControlSupportGlue')
- line = line.replace('PlaybackOverlayFragment', 'PlaybackOverlaySupportFragment')
- line = line.replace('PlaybackGlueHostOld', 'PlaybackSupportGlueHostOld')
- outfile.write(line)
-file.close()
-outfile.close()
-
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlGlueTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlGlueTest.java
deleted file mode 100644
index 70c8795..0000000
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlGlueTest.java
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
- * Copyright (C) 2016 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.v17.leanback.app;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.v17.leanback.widget.OnItemViewClickedListener;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.Row;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.view.KeyEvent;
-import android.view.View;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-
-@RunWith(AndroidJUnit4.class)
-@MediumTest
-public class PlaybackControlGlueTest {
-
-
- static class PlayControlGlueImpl extends PlaybackControlGlue {
- int mSpeedId = PLAYBACK_SPEED_PAUSED;
- // number of times onRowChanged callback is called
- int mOnRowChangedCallCount = 0;
-
- PlayControlGlueImpl(Context context, int[] seekSpeeds) {
- super(context, seekSpeeds);
- }
-
- PlayControlGlueImpl(Context context, int[] ffSpeeds, int[] rwSpeeds) {
- super(context, ffSpeeds, rwSpeeds);
- }
-
- PlayControlGlueImpl(Context context, PlaybackOverlayFragment fragment,
- int[] seekSpeeds) {
- super(context, fragment, seekSpeeds);
- }
-
- @Override
- public boolean hasValidMedia() {
- return true;
- }
-
- @Override
- public boolean isMediaPlaying() {
- return mSpeedId == PLAYBACK_SPEED_NORMAL;
- }
-
- @Override
- public CharSequence getMediaTitle() {
- return "DUMP TITLE";
- }
-
- @Override
- public CharSequence getMediaSubtitle() {
- return "DUMP SUBTITLE";
- }
-
- @Override
- public int getMediaDuration() {
- return 50000;
- }
-
- @Override
- public Drawable getMediaArt() {
- return null;
- }
-
- @Override
- public long getSupportedActions() {
- return ACTION_REWIND | ACTION_FAST_FORWARD | ACTION_PLAY_PAUSE;
- }
-
- @Override
- public int getCurrentSpeedId() {
- return mSpeedId;
- }
-
- @Override
- public int getCurrentPosition() {
- return 5000;
- }
-
- @Override
- protected void startPlayback(int speed) {
- mSpeedId = speed;
- }
-
- @Override
- protected void pausePlayback() {
- mSpeedId = PLAYBACK_SPEED_PAUSED;
- }
-
- @Override
- protected void skipToNext() {
- }
-
- @Override
- protected void skipToPrevious() {
- }
-
- @Override
- protected void onRowChanged(PlaybackControlsRow row) {
- mOnRowChangedCallCount++;
- }
-
- public void notifyMetaDataChanged() {
- onMetadataChanged();
- onStateChanged();
- }
-
- public int getOnRowChangedCallCount() {
- return mOnRowChangedCallCount;
- }
- }
-
- Context context;
- PlaybackControlGlue glue;
-
- @Before
- public void setUp() {
- context = InstrumentationRegistry.getInstrumentation().getTargetContext();
- try {
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- glue = new PlayControlGlueImpl(context, new int[]{
- PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0,
- PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1,
- PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2
- });
- }
- });
- } catch (Throwable throwable) {
- Assert.fail(throwable.getMessage());
- }
- }
-
- @Test
- public void testFastForwardToMaxThenReset() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
- PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_FAST_FORWARD);
- PlaybackControlsRow.MultiAction rewind = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_REWIND);
-
- assertFalse(glue.isMediaPlaying());
- glue.onActionClicked(playPause);
- assertTrue(glue.isMediaPlaying());
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
-
- // click multiple times to reach PLAYBACK_SPEED_FAST_L2
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- assertEquals(1, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1, glue.getCurrentSpeedId());
- assertEquals(2, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2, glue.getCurrentSpeedId());
- assertEquals(3, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2, glue.getCurrentSpeedId());
- assertEquals(3, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
-
- // press playPause again put it back to play
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- }
-
- @Test
- public void testFastRewindToMaxThenReset() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
- PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_FAST_FORWARD);
- PlaybackControlsRow.MultiAction rewind = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_REWIND);
-
- assertFalse(glue.isMediaPlaying());
- glue.onActionClicked(playPause);
- assertTrue(glue.isMediaPlaying());
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
-
- // click multiple times to reach PLAYBACK_SPEED_FAST_L2
- glue.onActionClicked(rewind);
- assertEquals(-PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(1, rewind.getIndex());
- glue.onActionClicked(rewind);
- assertEquals(-PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(2, rewind.getIndex());
- glue.onActionClicked(rewind);
- assertEquals(-PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(3, rewind.getIndex());
- glue.onActionClicked(rewind);
- assertEquals(-PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(3, rewind.getIndex());
-
- // press playPause again put it back to play
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- }
-
- @Test
- public void testFastForwardAbortKeyCodes() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
- PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_FAST_FORWARD);
- PlaybackControlsRow.MultiAction rewind = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_REWIND);
-
- glue.onActionClicked(playPause);
- assertTrue(glue.isMediaPlaying());
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
-
- // Testing keycodes that will not abort seek
- final int[] noAbortSeekKeyCodes = new int[] {
- KeyEvent.KEYCODE_DPAD_CENTER,
- KeyEvent.KEYCODE_ENTER
- };
- for (int i = 0; i < noAbortSeekKeyCodes.length; i++) {
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- assertEquals(1, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- KeyEvent kv = new KeyEvent(KeyEvent.ACTION_DOWN, noAbortSeekKeyCodes[i]);
- glue.onKey(null, noAbortSeekKeyCodes[i], kv);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- }
-
- // Testing abortSeekKeyCodes
- final int[] abortSeekKeyCodes = new int[] {
- KeyEvent.KEYCODE_DPAD_UP,
- KeyEvent.KEYCODE_DPAD_DOWN,
- KeyEvent.KEYCODE_DPAD_RIGHT,
- KeyEvent.KEYCODE_DPAD_LEFT,
- KeyEvent.KEYCODE_BACK,
- KeyEvent.KEYCODE_ESCAPE
- };
- for (int i = 0; i < abortSeekKeyCodes.length; i++) {
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- assertEquals(1, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- KeyEvent kv = new KeyEvent(KeyEvent.ACTION_DOWN, abortSeekKeyCodes[i]);
- glue.onKey(null, abortSeekKeyCodes[i], kv);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- }
- }
-
- @Test
- public void testRewindAbortKeyCodes() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
- PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_FAST_FORWARD);
- PlaybackControlsRow.MultiAction rewind = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_REWIND);
-
- glue.onActionClicked(playPause);
- assertTrue(glue.isMediaPlaying());
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
-
- // Testing keycodes that will not abort seek
- final int[] noAbortSeekKeyCodes = new int[] {
- KeyEvent.KEYCODE_DPAD_CENTER,
- KeyEvent.KEYCODE_ENTER
- };
- for (int i = 0; i < noAbortSeekKeyCodes.length; i++) {
- glue.onActionClicked(rewind);
- assertEquals(-PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(1, rewind.getIndex());
- KeyEvent kv = new KeyEvent(KeyEvent.ACTION_DOWN, noAbortSeekKeyCodes[i]);
- glue.onKey(null, noAbortSeekKeyCodes[i], kv);
- assertEquals(-PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- }
-
- // Testing abortSeekKeyCodes
- final int[] abortSeekKeyCodes = new int[] {
- KeyEvent.KEYCODE_DPAD_UP,
- KeyEvent.KEYCODE_DPAD_DOWN,
- KeyEvent.KEYCODE_DPAD_RIGHT,
- KeyEvent.KEYCODE_DPAD_LEFT,
- KeyEvent.KEYCODE_BACK,
- KeyEvent.KEYCODE_ESCAPE
- };
- for (int i = 0; i < abortSeekKeyCodes.length; i++) {
- glue.onActionClicked(rewind);
- assertEquals(-PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(1, rewind.getIndex());
- KeyEvent kv = new KeyEvent(KeyEvent.ACTION_DOWN, abortSeekKeyCodes[i]);
- glue.onKey(null, abortSeekKeyCodes[i], kv);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- }
- }
-
- @Test
- public void testMediaPauseButtonOnFF() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
- PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_FAST_FORWARD);
-
- glue.onActionClicked(playPause);
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PAUSE));
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testMediaPauseButtonOnPlay() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PAUSE));
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testMediaPauseButtonOnPause() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-
- glue.onActionClicked(playPause);
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PAUSE));
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testMediaPlayButtonOnFF() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
- PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_FAST_FORWARD);
-
- glue.onActionClicked(playPause);
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PLAY));
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testMediaPlayButtonOnPlay() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PLAY));
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testMediaPlayButtonOnPause() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-
- glue.onActionClicked(playPause);
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PLAY));
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testMediaPlayPauseButtonOnFF() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
- PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_FAST_FORWARD);
-
- glue.onActionClicked(playPause);
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testMediaPlayPauseButtonOnPlay() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testMediaPlayPauseButtonOnPause() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
-
- glue.onActionClicked(playPause);
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testOnItemClickedListener() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- final PlaybackOverlayFragment[] fragmentResult = new PlaybackOverlayFragment[1];
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- fragmentResult[0] = new PlaybackOverlayFragment();
- }
- });
- PlaybackOverlayFragment fragment = fragmentResult[0];
- glue.setHost(new PlaybackControlGlue.PlaybackGlueHostOld(fragment));
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlGlue.ACTION_PLAY_PAUSE);
- OnItemViewClickedListener listener = Mockito.mock(OnItemViewClickedListener.class);
- glue.setOnItemViewClickedListener(listener);
-
- // create fake row ViewHolder and fade item ViewHolder
- View rowView = new View(context);
- View view = new View(context);
- PlaybackRowPresenter.ViewHolder rowVh = new PlaybackRowPresenter.ViewHolder(rowView);
- Presenter.ViewHolder vh = new Presenter.ViewHolder(view);
-
- // Initially media is paused
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-
- // simulate a click inside PlaybackOverlayFragment's PlaybackRow.
- fragment.getOnItemViewClickedListener().onItemClicked(vh, playPause, rowVh, row);
- verify(listener, times(0)).onItemClicked(vh, playPause, rowVh, row);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-
- // simulate a click on object other than PlaybackRow.
- Object regularItem = new Object();
- Row regularRow = new Row();
- RowPresenter.ViewHolder regularRowViewHolder = new RowPresenter.ViewHolder(rowView);
- Presenter.ViewHolder regularViewHOlder = new Presenter.ViewHolder(view);
- fragment.getOnItemViewClickedListener().onItemClicked(regularViewHOlder, regularItem,
- regularRowViewHolder, regularRow);
- verify(listener, times(1)).onItemClicked(regularViewHOlder, regularItem,
- regularRowViewHolder, regularRow);
- assertEquals(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testOnRowChangedCallback() throws Exception {
- final PlaybackOverlayFragment[] fragmentResult = new
- PlaybackOverlayFragment[1];
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- fragmentResult[0] = new PlaybackOverlayFragment();
- }
- });
- PlaybackOverlayFragment fragment = fragmentResult[0];
- PlayControlGlueImpl playbackGlue = new PlayControlGlueImpl(context, fragment,
- new int[]{
- PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0,
- PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1,
- PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2
- });
-
- // before any controls row is created the count is zero
- assertEquals(playbackGlue.getOnRowChangedCallCount(), 0);
- playbackGlue.createControlsRowAndPresenter();
- // after a controls row is created, onRowChanged() call back is called once
- assertEquals(playbackGlue.getOnRowChangedCallCount(), 1);
- assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
- playbackGlue.notifyMetaDataChanged();
- // onMetaDataChanged() calls updateRowMetadata which ends up calling
- // notifyPlaybackRowChanged on the old host and finally onRowChanged on the glue.
- assertEquals(playbackGlue.getOnRowChangedCallCount(), 2);
- assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
- }
-
-
- @Test
- public void testWithoutValidMedia() throws Exception {
- final PlaybackOverlayFragment[] fragmentResult = new
- PlaybackOverlayFragment[1];
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- fragmentResult[0] = new PlaybackOverlayFragment();
- }
- });
- final boolean[] hasValidMedia = new boolean[] {false};
- PlaybackOverlayFragment fragment = fragmentResult[0];
- PlayControlGlueImpl playbackGlue = new PlayControlGlueImpl(context, fragment,
- new int[]{
- PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0,
- PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1,
- PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2
- }) {
- @Override
- public boolean hasValidMedia() {
- return hasValidMedia[0];
- }
- };
-
- // before any controls row is created the count is zero
- assertEquals(playbackGlue.getOnRowChangedCallCount(), 0);
- playbackGlue.createControlsRowAndPresenter();
- // after a controls row is created, onRowChanged() call back is called once
- assertEquals(playbackGlue.getOnRowChangedCallCount(), 1);
- // enven hasValidMedia() is false, we should still have three buttons.
- assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
-
- hasValidMedia[0] = true;
- playbackGlue.notifyMetaDataChanged();
- // onMetaDataChanged() calls updateRowMetadata which ends up calling
- // notifyPlaybackRowChanged on the old host and finally onRowChanged on the glue.
- assertEquals(playbackGlue.getOnRowChangedCallCount(), 2);
- assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
- }
-
-}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlSupportGlueTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlSupportGlueTest.java
deleted file mode 100644
index 37f5754..0000000
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlSupportGlueTest.java
+++ /dev/null
@@ -1,652 +0,0 @@
-// CHECKSTYLE:OFF Generated code
-/* This file is auto-generated from PlaybackControlGlueTest.java. DO NOT MODIFY. */
-
-/*
- * Copyright (C) 2016 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.v17.leanback.app;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.v17.leanback.widget.OnItemViewClickedListener;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.Row;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.view.KeyEvent;
-import android.view.View;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-
-@RunWith(AndroidJUnit4.class)
-@MediumTest
-public class PlaybackControlSupportGlueTest {
-
-
- static class PlayControlGlueImpl extends PlaybackControlSupportGlue {
- int mSpeedId = PLAYBACK_SPEED_PAUSED;
- // number of times onRowChanged callback is called
- int mOnRowChangedCallCount = 0;
-
- PlayControlGlueImpl(Context context, int[] seekSpeeds) {
- super(context, seekSpeeds);
- }
-
- PlayControlGlueImpl(Context context, int[] ffSpeeds, int[] rwSpeeds) {
- super(context, ffSpeeds, rwSpeeds);
- }
-
- PlayControlGlueImpl(Context context, PlaybackOverlaySupportFragment fragment,
- int[] seekSpeeds) {
- super(context, fragment, seekSpeeds);
- }
-
- @Override
- public boolean hasValidMedia() {
- return true;
- }
-
- @Override
- public boolean isMediaPlaying() {
- return mSpeedId == PLAYBACK_SPEED_NORMAL;
- }
-
- @Override
- public CharSequence getMediaTitle() {
- return "DUMP TITLE";
- }
-
- @Override
- public CharSequence getMediaSubtitle() {
- return "DUMP SUBTITLE";
- }
-
- @Override
- public int getMediaDuration() {
- return 50000;
- }
-
- @Override
- public Drawable getMediaArt() {
- return null;
- }
-
- @Override
- public long getSupportedActions() {
- return ACTION_REWIND | ACTION_FAST_FORWARD | ACTION_PLAY_PAUSE;
- }
-
- @Override
- public int getCurrentSpeedId() {
- return mSpeedId;
- }
-
- @Override
- public int getCurrentPosition() {
- return 5000;
- }
-
- @Override
- protected void startPlayback(int speed) {
- mSpeedId = speed;
- }
-
- @Override
- protected void pausePlayback() {
- mSpeedId = PLAYBACK_SPEED_PAUSED;
- }
-
- @Override
- protected void skipToNext() {
- }
-
- @Override
- protected void skipToPrevious() {
- }
-
- @Override
- protected void onRowChanged(PlaybackControlsRow row) {
- mOnRowChangedCallCount++;
- }
-
- public void notifyMetaDataChanged() {
- onMetadataChanged();
- onStateChanged();
- }
-
- public int getOnRowChangedCallCount() {
- return mOnRowChangedCallCount;
- }
- }
-
- Context context;
- PlaybackControlSupportGlue glue;
-
- @Before
- public void setUp() {
- context = InstrumentationRegistry.getInstrumentation().getTargetContext();
- try {
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- glue = new PlayControlGlueImpl(context, new int[]{
- PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0,
- PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L1,
- PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L2
- });
- }
- });
- } catch (Throwable throwable) {
- Assert.fail(throwable.getMessage());
- }
- }
-
- @Test
- public void testFastForwardToMaxThenReset() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
- PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_FAST_FORWARD);
- PlaybackControlsRow.MultiAction rewind = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_REWIND);
-
- assertFalse(glue.isMediaPlaying());
- glue.onActionClicked(playPause);
- assertTrue(glue.isMediaPlaying());
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
-
- // click multiple times to reach PLAYBACK_SPEED_FAST_L2
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- assertEquals(1, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L1, glue.getCurrentSpeedId());
- assertEquals(2, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L2, glue.getCurrentSpeedId());
- assertEquals(3, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L2, glue.getCurrentSpeedId());
- assertEquals(3, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
-
- // press playPause again put it back to play
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- }
-
- @Test
- public void testFastRewindToMaxThenReset() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
- PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_FAST_FORWARD);
- PlaybackControlsRow.MultiAction rewind = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_REWIND);
-
- assertFalse(glue.isMediaPlaying());
- glue.onActionClicked(playPause);
- assertTrue(glue.isMediaPlaying());
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
-
- // click multiple times to reach PLAYBACK_SPEED_FAST_L2
- glue.onActionClicked(rewind);
- assertEquals(-PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(1, rewind.getIndex());
- glue.onActionClicked(rewind);
- assertEquals(-PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L1, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(2, rewind.getIndex());
- glue.onActionClicked(rewind);
- assertEquals(-PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L2, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(3, rewind.getIndex());
- glue.onActionClicked(rewind);
- assertEquals(-PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L2, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(3, rewind.getIndex());
-
- // press playPause again put it back to play
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- }
-
- @Test
- public void testFastForwardAbortKeyCodes() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
- PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_FAST_FORWARD);
- PlaybackControlsRow.MultiAction rewind = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_REWIND);
-
- glue.onActionClicked(playPause);
- assertTrue(glue.isMediaPlaying());
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
-
- // Testing keycodes that will not abort seek
- final int[] noAbortSeekKeyCodes = new int[] {
- KeyEvent.KEYCODE_DPAD_CENTER,
- KeyEvent.KEYCODE_ENTER
- };
- for (int i = 0; i < noAbortSeekKeyCodes.length; i++) {
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- assertEquals(1, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- KeyEvent kv = new KeyEvent(KeyEvent.ACTION_DOWN, noAbortSeekKeyCodes[i]);
- glue.onKey(null, noAbortSeekKeyCodes[i], kv);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- }
-
- // Testing abortSeekKeyCodes
- final int[] abortSeekKeyCodes = new int[] {
- KeyEvent.KEYCODE_DPAD_UP,
- KeyEvent.KEYCODE_DPAD_DOWN,
- KeyEvent.KEYCODE_DPAD_RIGHT,
- KeyEvent.KEYCODE_DPAD_LEFT,
- KeyEvent.KEYCODE_BACK,
- KeyEvent.KEYCODE_ESCAPE
- };
- for (int i = 0; i < abortSeekKeyCodes.length; i++) {
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- assertEquals(1, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- KeyEvent kv = new KeyEvent(KeyEvent.ACTION_DOWN, abortSeekKeyCodes[i]);
- glue.onKey(null, abortSeekKeyCodes[i], kv);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- }
- }
-
- @Test
- public void testRewindAbortKeyCodes() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
- PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_FAST_FORWARD);
- PlaybackControlsRow.MultiAction rewind = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_REWIND);
-
- glue.onActionClicked(playPause);
- assertTrue(glue.isMediaPlaying());
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
-
- // Testing keycodes that will not abort seek
- final int[] noAbortSeekKeyCodes = new int[] {
- KeyEvent.KEYCODE_DPAD_CENTER,
- KeyEvent.KEYCODE_ENTER
- };
- for (int i = 0; i < noAbortSeekKeyCodes.length; i++) {
- glue.onActionClicked(rewind);
- assertEquals(-PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(1, rewind.getIndex());
- KeyEvent kv = new KeyEvent(KeyEvent.ACTION_DOWN, noAbortSeekKeyCodes[i]);
- glue.onKey(null, noAbortSeekKeyCodes[i], kv);
- assertEquals(-PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- }
-
- // Testing abortSeekKeyCodes
- final int[] abortSeekKeyCodes = new int[] {
- KeyEvent.KEYCODE_DPAD_UP,
- KeyEvent.KEYCODE_DPAD_DOWN,
- KeyEvent.KEYCODE_DPAD_RIGHT,
- KeyEvent.KEYCODE_DPAD_LEFT,
- KeyEvent.KEYCODE_BACK,
- KeyEvent.KEYCODE_ESCAPE
- };
- for (int i = 0; i < abortSeekKeyCodes.length; i++) {
- glue.onActionClicked(rewind);
- assertEquals(-PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(1, rewind.getIndex());
- KeyEvent kv = new KeyEvent(KeyEvent.ACTION_DOWN, abortSeekKeyCodes[i]);
- glue.onKey(null, abortSeekKeyCodes[i], kv);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- assertEquals(0, fastForward.getIndex());
- assertEquals(0, rewind.getIndex());
- }
- }
-
- @Test
- public void testMediaPauseButtonOnFF() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
- PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_FAST_FORWARD);
-
- glue.onActionClicked(playPause);
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PAUSE));
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testMediaPauseButtonOnPlay() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PAUSE));
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testMediaPauseButtonOnPause() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-
- glue.onActionClicked(playPause);
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PAUSE));
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testMediaPlayButtonOnFF() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
- PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_FAST_FORWARD);
-
- glue.onActionClicked(playPause);
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PLAY));
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testMediaPlayButtonOnPlay() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PLAY));
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testMediaPlayButtonOnPause() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-
- glue.onActionClicked(playPause);
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PLAY));
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testMediaPlayPauseButtonOnFF() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
- PlaybackControlsRow.MultiAction fastForward = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_FAST_FORWARD);
-
- glue.onActionClicked(playPause);
- glue.onActionClicked(fastForward);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testMediaPlayPauseButtonOnPlay() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testMediaPlayPauseButtonOnPause() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
-
- glue.onActionClicked(playPause);
- glue.onActionClicked(playPause);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
- glue.onKey(null, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, new KeyEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testOnItemClickedListener() {
- PlaybackControlsRow row = new PlaybackControlsRow();
- final PlaybackOverlaySupportFragment[] fragmentResult = new PlaybackOverlaySupportFragment[1];
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- fragmentResult[0] = new PlaybackOverlaySupportFragment();
- }
- });
- PlaybackOverlaySupportFragment fragment = fragmentResult[0];
- glue.setHost(new PlaybackControlSupportGlue.PlaybackSupportGlueHostOld(fragment));
- glue.setControlsRow(row);
- SparseArrayObjectAdapter adapter = (SparseArrayObjectAdapter)
- row.getPrimaryActionsAdapter();
- PlaybackControlsRow.MultiAction playPause = (PlaybackControlsRow.MultiAction) adapter
- .lookup(PlaybackControlSupportGlue.ACTION_PLAY_PAUSE);
- OnItemViewClickedListener listener = Mockito.mock(OnItemViewClickedListener.class);
- glue.setOnItemViewClickedListener(listener);
-
- // create fake row ViewHolder and fade item ViewHolder
- View rowView = new View(context);
- View view = new View(context);
- PlaybackRowPresenter.ViewHolder rowVh = new PlaybackRowPresenter.ViewHolder(rowView);
- Presenter.ViewHolder vh = new Presenter.ViewHolder(view);
-
- // Initially media is paused
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_PAUSED, glue.getCurrentSpeedId());
-
- // simulate a click inside PlaybackOverlaySupportFragment's PlaybackRow.
- fragment.getOnItemViewClickedListener().onItemClicked(vh, playPause, rowVh, row);
- verify(listener, times(0)).onItemClicked(vh, playPause, rowVh, row);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
-
- // simulate a click on object other than PlaybackRow.
- Object regularItem = new Object();
- Row regularRow = new Row();
- RowPresenter.ViewHolder regularRowViewHolder = new RowPresenter.ViewHolder(rowView);
- Presenter.ViewHolder regularViewHOlder = new Presenter.ViewHolder(view);
- fragment.getOnItemViewClickedListener().onItemClicked(regularViewHOlder, regularItem,
- regularRowViewHolder, regularRow);
- verify(listener, times(1)).onItemClicked(regularViewHOlder, regularItem,
- regularRowViewHolder, regularRow);
- assertEquals(PlaybackControlSupportGlue.PLAYBACK_SPEED_NORMAL, glue.getCurrentSpeedId());
- }
-
- @Test
- public void testOnRowChangedCallback() throws Exception {
- final PlaybackOverlaySupportFragment[] fragmentResult = new
- PlaybackOverlaySupportFragment[1];
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- fragmentResult[0] = new PlaybackOverlaySupportFragment();
- }
- });
- PlaybackOverlaySupportFragment fragment = fragmentResult[0];
- PlayControlGlueImpl playbackGlue = new PlayControlGlueImpl(context, fragment,
- new int[]{
- PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0,
- PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L1,
- PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L2
- });
-
- // before any controls row is created the count is zero
- assertEquals(playbackGlue.getOnRowChangedCallCount(), 0);
- playbackGlue.createControlsRowAndPresenter();
- // after a controls row is created, onRowChanged() call back is called once
- assertEquals(playbackGlue.getOnRowChangedCallCount(), 1);
- assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
- playbackGlue.notifyMetaDataChanged();
- // onMetaDataChanged() calls updateRowMetadata which ends up calling
- // notifyPlaybackRowChanged on the old host and finally onRowChanged on the glue.
- assertEquals(playbackGlue.getOnRowChangedCallCount(), 2);
- assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
- }
-
-
- @Test
- public void testWithoutValidMedia() throws Exception {
- final PlaybackOverlaySupportFragment[] fragmentResult = new
- PlaybackOverlaySupportFragment[1];
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- fragmentResult[0] = new PlaybackOverlaySupportFragment();
- }
- });
- final boolean[] hasValidMedia = new boolean[] {false};
- PlaybackOverlaySupportFragment fragment = fragmentResult[0];
- PlayControlGlueImpl playbackGlue = new PlayControlGlueImpl(context, fragment,
- new int[]{
- PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0,
- PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L1,
- PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L2
- }) {
- @Override
- public boolean hasValidMedia() {
- return hasValidMedia[0];
- }
- };
-
- // before any controls row is created the count is zero
- assertEquals(playbackGlue.getOnRowChangedCallCount(), 0);
- playbackGlue.createControlsRowAndPresenter();
- // after a controls row is created, onRowChanged() call back is called once
- assertEquals(playbackGlue.getOnRowChangedCallCount(), 1);
- // enven hasValidMedia() is false, we should still have three buttons.
- assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
-
- hasValidMedia[0] = true;
- playbackGlue.notifyMetaDataChanged();
- // onMetaDataChanged() calls updateRowMetadata which ends up calling
- // notifyPlaybackRowChanged on the old host and finally onRowChanged on the glue.
- assertEquals(playbackGlue.getOnRowChangedCallCount(), 2);
- assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
- }
-
-}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayFragmentTest.java
deleted file mode 100644
index f21bd04..0000000
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayFragmentTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2016 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.v17.leanback.app;
-
-import static junit.framework.Assert.assertEquals;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.support.test.filters.FlakyTest;
-import android.support.test.filters.MediumTest;
-import android.support.test.filters.Suppress;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.v17.leanback.test.R;
-import android.view.View;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-public class PlaybackOverlayFragmentTest extends SingleFragmentTestBase {
-
- @Test
- public void workaroundVideoViewStealFocus() {
- SingleFragmentTestActivity activity =
- launchAndWaitActivity(PlaybackOverlayTestFragment.class,
- new Options().activityLayoutId(R.layout.playback_controls_with_video), 0);
- PlaybackOverlayTestFragment fragment = (PlaybackOverlayTestFragment)
- activity.getTestFragment();
-
- assertFalse(activity.findViewById(R.id.videoView).hasFocus());
- assertTrue(fragment.getView().hasFocus());
- }
-
- @FlakyTest
- @Suppress
- @Test
- public void alignmentRowToBottom() throws Throwable {
- SingleFragmentTestActivity activity =
- launchAndWaitActivity(PlaybackOverlayTestFragment.class,
- new Options().activityLayoutId(R.layout.playback_controls_with_video), 0);
- final PlaybackOverlayTestFragment fragment = (PlaybackOverlayTestFragment)
- activity.getTestFragment();
-
- assertTrue(fragment.getAdapter().size() > 2);
-
- View playRow = fragment.getVerticalGridView().getChildAt(0);
- assertTrue(playRow.hasFocus());
- assertEquals(playRow.getResources().getDimensionPixelSize(
- R.dimen.lb_playback_controls_padding_bottom),
- fragment.getVerticalGridView().getHeight() - playRow.getBottom());
-
- activityTestRule.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- fragment.getVerticalGridView().setSelectedPositionSmooth(
- fragment.getAdapter().size() - 1);
- }
- });
- waitForScrollIdle(fragment.getVerticalGridView());
-
- View lastRow = fragment.getVerticalGridView().getChildAt(
- fragment.getVerticalGridView().getChildCount() - 1);
- assertEquals(fragment.getAdapter().size() - 1,
- fragment.getVerticalGridView().getChildAdapterPosition(lastRow));
- assertTrue(lastRow.hasFocus());
- assertEquals(lastRow.getResources().getDimensionPixelSize(
- R.dimen.lb_playback_controls_padding_bottom),
- fragment.getVerticalGridView().getHeight() - lastRow.getBottom());
- }
-
-}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayTestFragment.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayTestFragment.java
deleted file mode 100644
index 82e37d3..0000000
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayTestFragment.java
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (C) 2016 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.v17.leanback.app;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v17.leanback.test.R;
-import android.support.v17.leanback.widget.Action;
-import android.support.v17.leanback.widget.ArrayObjectAdapter;
-import android.support.v17.leanback.widget.ClassPresenterSelector;
-import android.support.v17.leanback.widget.ControlButtonPresenterSelector;
-import android.support.v17.leanback.widget.HeaderItem;
-import android.support.v17.leanback.widget.ListRow;
-import android.support.v17.leanback.widget.ListRowPresenter;
-import android.support.v17.leanback.widget.OnItemViewClickedListener;
-import android.support.v17.leanback.widget.OnItemViewSelectedListener;
-import android.support.v17.leanback.widget.PlaybackControlsRow;
-import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.PresenterSelector;
-import android.support.v17.leanback.widget.Row;
-import android.support.v17.leanback.widget.RowPresenter;
-import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.widget.Toast;
-
-public class PlaybackOverlayTestFragment extends PlaybackOverlayFragment {
- private static final String TAG = "leanback.PlaybackControlsFragment";
-
- /**
- * Change this to choose a different overlay background.
- */
- private static final int BACKGROUND_TYPE = PlaybackOverlayFragment.BG_LIGHT;
-
- /**
- * Change the number of related content rows.
- */
- private static final int RELATED_CONTENT_ROWS = 3;
-
- /**
- * Change this to select hidden
- */
- private static final boolean SECONDARY_HIDDEN = false;
-
- private static final int ROW_CONTROLS = 0;
-
- private PlaybackControlHelper mGlue;
- private PlaybackControlsRowPresenter mPlaybackControlsRowPresenter;
-
- private OnItemViewClickedListener mOnItemViewClickedListener = new OnItemViewClickedListener() {
- @Override
- public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
- RowPresenter.ViewHolder rowViewHolder, Row row) {
- Log.i(TAG, "onItemClicked: " + item + " row " + row);
- if (item instanceof Action) {
- mGlue.onActionClicked((Action) item);
- }
- }
- };
-
- private OnItemViewSelectedListener mOnItemViewSelectedListener =
- new OnItemViewSelectedListener() {
- @Override
- public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
- RowPresenter.ViewHolder rowViewHolder, Row row) {
- Log.i(TAG, "onItemSelected: " + item + " row " + row);
- }
- };
-
- @Override
- public SparseArrayObjectAdapter getAdapter() {
- return (SparseArrayObjectAdapter) super.getAdapter();
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- Log.i(TAG, "onCreate");
- super.onCreate(savedInstanceState);
-
- setBackgroundType(BACKGROUND_TYPE);
- setOnItemViewSelectedListener(mOnItemViewSelectedListener);
-
- createComponents(getActivity());
- }
-
- private void createComponents(Context context) {
- mGlue = new PlaybackControlHelper(context, this) {
- @Override
- public int getUpdatePeriod() {
- long totalTime = getControlsRow().getDuration();
- if (getView() == null || getView().getWidth() == 0 || totalTime <= 0) {
- return 1000;
- }
- return 16;
- }
-
- @Override
- protected void onRowChanged(PlaybackControlsRow row) {
- if (getAdapter() == null) {
- return;
- }
- int index = getAdapter().indexOf(row);
- if (index >= 0) {
- getAdapter().notifyArrayItemRangeChanged(index, 1);
- }
- }
-
- @Override
- public void onActionClicked(Action action) {
- if (action.getId() == R.id.lb_control_picture_in_picture) {
- getActivity().enterPictureInPictureMode();
- return;
- }
- super.onActionClicked(action);
- }
- };
-
- mGlue.setOnItemViewClickedListener(mOnItemViewClickedListener);
-
- mPlaybackControlsRowPresenter = mGlue.createControlsRowAndPresenter();
- mPlaybackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
- ClassPresenterSelector selector = new ClassPresenterSelector();
- selector.addClassPresenter(ListRow.class, new ListRowPresenter());
- selector.addClassPresenter(PlaybackControlsRow.class, mPlaybackControlsRowPresenter);
-
- setAdapter(new SparseArrayObjectAdapter(selector));
-
- // Add the controls row
- getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
-
- // Add related content rows
- for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
- ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new StringPresenter());
- listRowAdapter.add("Some related content");
- listRowAdapter.add("Other related content");
- HeaderItem header = new HeaderItem(i, "Row " + i);
- getAdapter().set(ROW_CONTROLS + 1 + i, new ListRow(header, listRowAdapter));
- }
-
- }
-
- @Override
- public void onStart() {
- super.onStart();
- mGlue.setFadingEnabled(true);
- }
-
- abstract static class PlaybackControlHelper extends PlaybackControlGlue {
- /**
- * Change the location of the thumbs up/down controls
- */
- private static final boolean THUMBS_PRIMARY = true;
-
- private static final String FAUX_TITLE = "A short song of silence";
- private static final String FAUX_SUBTITLE = "2014";
- private static final int FAUX_DURATION = 33 * 1000;
-
- // These should match the playback service FF behavior
- private static int[] sFastForwardSpeeds = { 2, 3, 4, 5 };
-
- private boolean mIsPlaying;
- private int mSpeed = PlaybackControlGlue.PLAYBACK_SPEED_PAUSED;
- private long mStartTime;
- private long mStartPosition = 0;
-
- private PlaybackControlsRow.RepeatAction mRepeatAction;
- private PlaybackControlsRow.ThumbsUpAction mThumbsUpAction;
- private PlaybackControlsRow.ThumbsDownAction mThumbsDownAction;
- private PlaybackControlsRow.PictureInPictureAction mPipAction;
- private static Handler mHandler = new Handler();
-
- private final Runnable mUpdateProgressRunnable = new Runnable() {
- @Override
- public void run() {
- updateProgress();
- mHandler.postDelayed(this, getUpdatePeriod());
- }
- };
-
- PlaybackControlHelper(Context context, PlaybackOverlayFragment fragment) {
- super(context, fragment, sFastForwardSpeeds);
- mThumbsUpAction = new PlaybackControlsRow.ThumbsUpAction(context);
- mThumbsUpAction.setIndex(PlaybackControlsRow.ThumbsUpAction.INDEX_OUTLINE);
- mThumbsDownAction = new PlaybackControlsRow.ThumbsDownAction(context);
- mThumbsDownAction.setIndex(PlaybackControlsRow.ThumbsDownAction.INDEX_OUTLINE);
- mRepeatAction = new PlaybackControlsRow.RepeatAction(context);
- mPipAction = new PlaybackControlsRow.PictureInPictureAction(context);
- }
-
- @Override
- public PlaybackControlsRowPresenter createControlsRowAndPresenter() {
- PlaybackControlsRowPresenter presenter = super.createControlsRowAndPresenter();
-
- ArrayObjectAdapter adapter = new ArrayObjectAdapter(
- new ControlButtonPresenterSelector());
- getControlsRow().setSecondaryActionsAdapter(adapter);
- if (!THUMBS_PRIMARY) {
- adapter.add(mThumbsDownAction);
- }
- if (android.os.Build.VERSION.SDK_INT > 23) {
- adapter.add(mPipAction);
- }
- adapter.add(mRepeatAction);
- if (!THUMBS_PRIMARY) {
- adapter.add(mThumbsUpAction);
- }
-
- return presenter;
- }
-
- @Override
- protected SparseArrayObjectAdapter createPrimaryActionsAdapter(
- PresenterSelector presenterSelector) {
- SparseArrayObjectAdapter adapter = new SparseArrayObjectAdapter(presenterSelector);
- if (THUMBS_PRIMARY) {
- adapter.set(PlaybackControlGlue.ACTION_CUSTOM_LEFT_FIRST, mThumbsUpAction);
- adapter.set(PlaybackControlGlue.ACTION_CUSTOM_RIGHT_FIRST, mThumbsDownAction);
- }
- return adapter;
- }
-
- @Override
- public void onActionClicked(Action action) {
- if (shouldDispatchAction(action)) {
- dispatchAction(action);
- return;
- }
- super.onActionClicked(action);
- }
-
- @Override
- public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
- if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
- Action action = getControlsRow().getActionForKeyCode(keyEvent.getKeyCode());
- if (shouldDispatchAction(action)) {
- dispatchAction(action);
- return true;
- }
- }
- return super.onKey(view, keyCode, keyEvent);
- }
-
- private boolean shouldDispatchAction(Action action) {
- return action == mRepeatAction || action == mThumbsUpAction
- || action == mThumbsDownAction;
- }
-
- private void dispatchAction(Action action) {
- Toast.makeText(getContext(), action.toString(), Toast.LENGTH_SHORT).show();
- PlaybackControlsRow.MultiAction multiAction = (PlaybackControlsRow.MultiAction) action;
- multiAction.nextIndex();
- notifyActionChanged(multiAction);
- }
-
- private void notifyActionChanged(PlaybackControlsRow.MultiAction action) {
- int index;
- index = getPrimaryActionsAdapter().indexOf(action);
- if (index >= 0) {
- getPrimaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
- } else {
- index = getSecondaryActionsAdapter().indexOf(action);
- if (index >= 0) {
- getSecondaryActionsAdapter().notifyArrayItemRangeChanged(index, 1);
- }
- }
- }
-
- private SparseArrayObjectAdapter getPrimaryActionsAdapter() {
- return (SparseArrayObjectAdapter) getControlsRow().getPrimaryActionsAdapter();
- }
-
- private ArrayObjectAdapter getSecondaryActionsAdapter() {
- return (ArrayObjectAdapter) getControlsRow().getSecondaryActionsAdapter();
- }
-
- @Override
- public boolean hasValidMedia() {
- return true;
- }
-
- @Override
- public boolean isMediaPlaying() {
- return mIsPlaying;
- }
-
- @Override
- public CharSequence getMediaTitle() {
- return FAUX_TITLE;
- }
-
- @Override
- public CharSequence getMediaSubtitle() {
- return FAUX_SUBTITLE;
- }
-
- @Override
- public int getMediaDuration() {
- return FAUX_DURATION;
- }
-
- @Override
- public Drawable getMediaArt() {
- return null;
- }
-
- @Override
- public long getSupportedActions() {
- return PlaybackControlGlue.ACTION_PLAY_PAUSE
- | PlaybackControlGlue.ACTION_FAST_FORWARD
- | PlaybackControlGlue.ACTION_REWIND;
- }
-
- @Override
- public int getCurrentSpeedId() {
- return mSpeed;
- }
-
- @Override
- public int getCurrentPosition() {
- int speed;
- if (mSpeed == PlaybackControlGlue.PLAYBACK_SPEED_PAUSED) {
- speed = 0;
- } else if (mSpeed == PlaybackControlGlue.PLAYBACK_SPEED_NORMAL) {
- speed = 1;
- } else if (mSpeed >= PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0) {
- int index = mSpeed - PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0;
- speed = getFastForwardSpeeds()[index];
- } else if (mSpeed <= -PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0) {
- int index = -mSpeed - PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0;
- speed = -getRewindSpeeds()[index];
- } else {
- return -1;
- }
- long position = mStartPosition + (System.currentTimeMillis() - mStartTime) * speed;
- if (position > getMediaDuration()) {
- position = getMediaDuration();
- onPlaybackComplete(true);
- } else if (position < 0) {
- position = 0;
- onPlaybackComplete(false);
- }
- return (int) position;
- }
-
- void onPlaybackComplete(final boolean ended) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- if (mRepeatAction.getIndex() == PlaybackControlsRow.RepeatAction.INDEX_NONE) {
- pausePlayback();
- } else {
- startPlayback(PlaybackControlGlue.PLAYBACK_SPEED_NORMAL);
- }
- mStartPosition = 0;
- onStateChanged();
- }
- });
- }
-
- @Override
- protected void startPlayback(int speed) {
- if (speed == mSpeed) {
- return;
- }
- mStartPosition = getCurrentPosition();
- mSpeed = speed;
- mIsPlaying = true;
- mStartTime = System.currentTimeMillis();
- }
-
- @Override
- protected void pausePlayback() {
- if (mSpeed == PlaybackControlGlue.PLAYBACK_SPEED_PAUSED) {
- return;
- }
- mStartPosition = getCurrentPosition();
- mSpeed = PlaybackControlGlue.PLAYBACK_SPEED_PAUSED;
- mIsPlaying = false;
- }
-
- @Override
- protected void skipToNext() {
- // Not supported
- }
-
- @Override
- protected void skipToPrevious() {
- // Not supported
- }
-
- @Override
- public void enableProgressUpdating(boolean enable) {
- mHandler.removeCallbacks(mUpdateProgressRunnable);
- if (enable) {
- mUpdateProgressRunnable.run();
- }
- }
- }
-}
diff --git a/v7/appcompat/Android.mk b/v7/appcompat/Android.mk
index 93baa95..500a2a2 100644
--- a/v7/appcompat/Android.mk
+++ b/v7/appcompat/Android.mk
@@ -26,7 +26,7 @@
LOCAL_USE_AAPT2 := true
LOCAL_MODULE := android-support-v7-appcompat
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
+LOCAL_SRC_FILES := $(call all-java-files-under,src/main/java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_STATIC_JAVA_LIBRARIES := \
android-support-vectordrawable \
diff --git a/v7/appcompat/build.gradle b/v7/appcompat/build.gradle
index a0e5290..2d57ac4 100644
--- a/v7/appcompat/build.gradle
+++ b/v7/appcompat/build.gradle
@@ -22,10 +22,7 @@
}
sourceSets {
- main.java.srcDir 'src'
main.res.srcDirs 'res', 'res-public'
- main.assets.srcDir 'assets'
- main.resources.srcDir 'src'
}
aaptOptions {
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBar.java b/v7/appcompat/src/main/java/android/support/v7/app/ActionBar.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/ActionBar.java
rename to v7/appcompat/src/main/java/android/support/v7/app/ActionBar.java
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBarDrawerToggle.java b/v7/appcompat/src/main/java/android/support/v7/app/ActionBarDrawerToggle.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/ActionBarDrawerToggle.java
rename to v7/appcompat/src/main/java/android/support/v7/app/ActionBarDrawerToggle.java
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBarDrawerToggleHoneycomb.java b/v7/appcompat/src/main/java/android/support/v7/app/ActionBarDrawerToggleHoneycomb.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/ActionBarDrawerToggleHoneycomb.java
rename to v7/appcompat/src/main/java/android/support/v7/app/ActionBarDrawerToggleHoneycomb.java
diff --git a/v7/appcompat/src/android/support/v7/app/AlertController.java b/v7/appcompat/src/main/java/android/support/v7/app/AlertController.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/AlertController.java
rename to v7/appcompat/src/main/java/android/support/v7/app/AlertController.java
diff --git a/v7/appcompat/src/android/support/v7/app/AlertDialog.java b/v7/appcompat/src/main/java/android/support/v7/app/AlertDialog.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/AlertDialog.java
rename to v7/appcompat/src/main/java/android/support/v7/app/AlertDialog.java
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatActivity.java b/v7/appcompat/src/main/java/android/support/v7/app/AppCompatActivity.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/AppCompatActivity.java
rename to v7/appcompat/src/main/java/android/support/v7/app/AppCompatActivity.java
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatCallback.java b/v7/appcompat/src/main/java/android/support/v7/app/AppCompatCallback.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/AppCompatCallback.java
rename to v7/appcompat/src/main/java/android/support/v7/app/AppCompatCallback.java
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegate.java b/v7/appcompat/src/main/java/android/support/v7/app/AppCompatDelegate.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/AppCompatDelegate.java
rename to v7/appcompat/src/main/java/android/support/v7/app/AppCompatDelegate.java
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java b/v7/appcompat/src/main/java/android/support/v7/app/AppCompatDelegateImplBase.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java
rename to v7/appcompat/src/main/java/android/support/v7/app/AppCompatDelegateImplBase.java
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplN.java b/v7/appcompat/src/main/java/android/support/v7/app/AppCompatDelegateImplN.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplN.java
rename to v7/appcompat/src/main/java/android/support/v7/app/AppCompatDelegateImplN.java
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV11.java b/v7/appcompat/src/main/java/android/support/v7/app/AppCompatDelegateImplV11.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV11.java
rename to v7/appcompat/src/main/java/android/support/v7/app/AppCompatDelegateImplV11.java
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV14.java b/v7/appcompat/src/main/java/android/support/v7/app/AppCompatDelegateImplV14.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV14.java
rename to v7/appcompat/src/main/java/android/support/v7/app/AppCompatDelegateImplV14.java
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV23.java b/v7/appcompat/src/main/java/android/support/v7/app/AppCompatDelegateImplV23.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV23.java
rename to v7/appcompat/src/main/java/android/support/v7/app/AppCompatDelegateImplV23.java
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java b/v7/appcompat/src/main/java/android/support/v7/app/AppCompatDelegateImplV9.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java
rename to v7/appcompat/src/main/java/android/support/v7/app/AppCompatDelegateImplV9.java
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDialog.java b/v7/appcompat/src/main/java/android/support/v7/app/AppCompatDialog.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/AppCompatDialog.java
rename to v7/appcompat/src/main/java/android/support/v7/app/AppCompatDialog.java
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDialogFragment.java b/v7/appcompat/src/main/java/android/support/v7/app/AppCompatDialogFragment.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/AppCompatDialogFragment.java
rename to v7/appcompat/src/main/java/android/support/v7/app/AppCompatDialogFragment.java
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatViewInflater.java b/v7/appcompat/src/main/java/android/support/v7/app/AppCompatViewInflater.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/AppCompatViewInflater.java
rename to v7/appcompat/src/main/java/android/support/v7/app/AppCompatViewInflater.java
diff --git a/v7/appcompat/src/android/support/v7/app/NavItemSelectedListener.java b/v7/appcompat/src/main/java/android/support/v7/app/NavItemSelectedListener.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/NavItemSelectedListener.java
rename to v7/appcompat/src/main/java/android/support/v7/app/NavItemSelectedListener.java
diff --git a/v7/appcompat/src/android/support/v7/app/ResourcesFlusher.java b/v7/appcompat/src/main/java/android/support/v7/app/ResourcesFlusher.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/ResourcesFlusher.java
rename to v7/appcompat/src/main/java/android/support/v7/app/ResourcesFlusher.java
diff --git a/v7/appcompat/src/android/support/v7/app/ToolbarActionBar.java b/v7/appcompat/src/main/java/android/support/v7/app/ToolbarActionBar.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/ToolbarActionBar.java
rename to v7/appcompat/src/main/java/android/support/v7/app/ToolbarActionBar.java
diff --git a/v7/appcompat/src/android/support/v7/app/TwilightCalculator.java b/v7/appcompat/src/main/java/android/support/v7/app/TwilightCalculator.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/TwilightCalculator.java
rename to v7/appcompat/src/main/java/android/support/v7/app/TwilightCalculator.java
diff --git a/v7/appcompat/src/android/support/v7/app/TwilightManager.java b/v7/appcompat/src/main/java/android/support/v7/app/TwilightManager.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/TwilightManager.java
rename to v7/appcompat/src/main/java/android/support/v7/app/TwilightManager.java
diff --git a/v7/appcompat/src/android/support/v7/app/WindowDecorActionBar.java b/v7/appcompat/src/main/java/android/support/v7/app/WindowDecorActionBar.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/app/WindowDecorActionBar.java
rename to v7/appcompat/src/main/java/android/support/v7/app/WindowDecorActionBar.java
diff --git a/v7/appcompat/src/android/support/v7/content/res/AppCompatColorStateListInflater.java b/v7/appcompat/src/main/java/android/support/v7/content/res/AppCompatColorStateListInflater.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/content/res/AppCompatColorStateListInflater.java
rename to v7/appcompat/src/main/java/android/support/v7/content/res/AppCompatColorStateListInflater.java
diff --git a/v7/appcompat/src/android/support/v7/content/res/AppCompatResources.java b/v7/appcompat/src/main/java/android/support/v7/content/res/AppCompatResources.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/content/res/AppCompatResources.java
rename to v7/appcompat/src/main/java/android/support/v7/content/res/AppCompatResources.java
diff --git a/v7/appcompat/src/android/support/v7/content/res/GrowingArrayUtils.java b/v7/appcompat/src/main/java/android/support/v7/content/res/GrowingArrayUtils.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/content/res/GrowingArrayUtils.java
rename to v7/appcompat/src/main/java/android/support/v7/content/res/GrowingArrayUtils.java
diff --git a/v7/appcompat/src/android/support/v7/graphics/drawable/DrawableWrapper.java b/v7/appcompat/src/main/java/android/support/v7/graphics/drawable/DrawableWrapper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/graphics/drawable/DrawableWrapper.java
rename to v7/appcompat/src/main/java/android/support/v7/graphics/drawable/DrawableWrapper.java
diff --git a/v7/appcompat/src/android/support/v7/graphics/drawable/DrawerArrowDrawable.java b/v7/appcompat/src/main/java/android/support/v7/graphics/drawable/DrawerArrowDrawable.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/graphics/drawable/DrawerArrowDrawable.java
rename to v7/appcompat/src/main/java/android/support/v7/graphics/drawable/DrawerArrowDrawable.java
diff --git a/v7/appcompat/src/android/support/v7/text/AllCapsTransformationMethod.java b/v7/appcompat/src/main/java/android/support/v7/text/AllCapsTransformationMethod.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/text/AllCapsTransformationMethod.java
rename to v7/appcompat/src/main/java/android/support/v7/text/AllCapsTransformationMethod.java
diff --git a/v7/appcompat/src/android/support/v7/view/ActionBarPolicy.java b/v7/appcompat/src/main/java/android/support/v7/view/ActionBarPolicy.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/ActionBarPolicy.java
rename to v7/appcompat/src/main/java/android/support/v7/view/ActionBarPolicy.java
diff --git a/v7/appcompat/src/android/support/v7/view/ActionMode.java b/v7/appcompat/src/main/java/android/support/v7/view/ActionMode.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/ActionMode.java
rename to v7/appcompat/src/main/java/android/support/v7/view/ActionMode.java
diff --git a/v7/appcompat/src/android/support/v7/view/CollapsibleActionView.java b/v7/appcompat/src/main/java/android/support/v7/view/CollapsibleActionView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/CollapsibleActionView.java
rename to v7/appcompat/src/main/java/android/support/v7/view/CollapsibleActionView.java
diff --git a/v7/appcompat/src/android/support/v7/view/ContextThemeWrapper.java b/v7/appcompat/src/main/java/android/support/v7/view/ContextThemeWrapper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/ContextThemeWrapper.java
rename to v7/appcompat/src/main/java/android/support/v7/view/ContextThemeWrapper.java
diff --git a/v7/appcompat/src/android/support/v7/view/StandaloneActionMode.java b/v7/appcompat/src/main/java/android/support/v7/view/StandaloneActionMode.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/StandaloneActionMode.java
rename to v7/appcompat/src/main/java/android/support/v7/view/StandaloneActionMode.java
diff --git a/v7/appcompat/src/android/support/v7/view/SupportActionModeWrapper.java b/v7/appcompat/src/main/java/android/support/v7/view/SupportActionModeWrapper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/SupportActionModeWrapper.java
rename to v7/appcompat/src/main/java/android/support/v7/view/SupportActionModeWrapper.java
diff --git a/v7/appcompat/src/android/support/v7/view/SupportMenuInflater.java b/v7/appcompat/src/main/java/android/support/v7/view/SupportMenuInflater.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/SupportMenuInflater.java
rename to v7/appcompat/src/main/java/android/support/v7/view/SupportMenuInflater.java
diff --git a/v7/appcompat/src/android/support/v7/view/ViewPropertyAnimatorCompatSet.java b/v7/appcompat/src/main/java/android/support/v7/view/ViewPropertyAnimatorCompatSet.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/ViewPropertyAnimatorCompatSet.java
rename to v7/appcompat/src/main/java/android/support/v7/view/ViewPropertyAnimatorCompatSet.java
diff --git a/v7/appcompat/src/android/support/v7/view/WindowCallbackWrapper.java b/v7/appcompat/src/main/java/android/support/v7/view/WindowCallbackWrapper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/WindowCallbackWrapper.java
rename to v7/appcompat/src/main/java/android/support/v7/view/WindowCallbackWrapper.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItem.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/ActionMenuItem.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/ActionMenuItem.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/ActionMenuItem.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItemView.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/ActionMenuItemView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/ActionMenuItemView.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/ActionMenuItemView.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/BaseMenuPresenter.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/BaseMenuPresenter.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/BaseMenuPresenter.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/BaseMenuPresenter.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/BaseMenuWrapper.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/BaseMenuWrapper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/BaseMenuWrapper.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/BaseMenuWrapper.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/BaseWrapper.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/BaseWrapper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/BaseWrapper.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/BaseWrapper.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/CascadingMenuPopup.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/CascadingMenuPopup.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/CascadingMenuPopup.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/CascadingMenuPopup.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ExpandedMenuView.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/ExpandedMenuView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/ExpandedMenuView.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/ExpandedMenuView.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ListMenuItemView.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/ListMenuItemView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/ListMenuItemView.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/ListMenuItemView.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ListMenuPresenter.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/ListMenuPresenter.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/ListMenuPresenter.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/ListMenuPresenter.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuAdapter.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/MenuAdapter.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/MenuAdapter.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/MenuAdapter.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuBuilder.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/MenuBuilder.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/MenuBuilder.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/MenuBuilder.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuDialogHelper.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/MenuDialogHelper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/MenuDialogHelper.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/MenuDialogHelper.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuHelper.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/MenuHelper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/MenuHelper.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/MenuHelper.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuItemImpl.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/MenuItemImpl.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/MenuItemImpl.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/MenuItemImpl.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperICS.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/MenuItemWrapperICS.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperICS.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/MenuItemWrapperICS.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperJB.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/MenuItemWrapperJB.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperJB.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/MenuItemWrapperJB.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuPopup.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/MenuPopup.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/MenuPopup.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/MenuPopup.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuPopupHelper.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/MenuPopupHelper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/MenuPopupHelper.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/MenuPopupHelper.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuPresenter.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/MenuPresenter.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/MenuPresenter.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/MenuPresenter.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuView.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/MenuView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/MenuView.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/MenuView.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuWrapperFactory.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/MenuWrapperFactory.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/MenuWrapperFactory.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/MenuWrapperFactory.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuWrapperICS.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/MenuWrapperICS.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/MenuWrapperICS.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/MenuWrapperICS.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ShowableListMenu.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/ShowableListMenu.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/ShowableListMenu.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/ShowableListMenu.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/StandardMenuPopup.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/StandardMenuPopup.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/StandardMenuPopup.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/StandardMenuPopup.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/SubMenuBuilder.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/SubMenuBuilder.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/SubMenuBuilder.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/SubMenuBuilder.java
diff --git a/v7/appcompat/src/android/support/v7/view/menu/SubMenuWrapperICS.java b/v7/appcompat/src/main/java/android/support/v7/view/menu/SubMenuWrapperICS.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/view/menu/SubMenuWrapperICS.java
rename to v7/appcompat/src/main/java/android/support/v7/view/menu/SubMenuWrapperICS.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AbsActionBarView.java b/v7/appcompat/src/main/java/android/support/v7/widget/AbsActionBarView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AbsActionBarView.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AbsActionBarView.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionBarBackgroundDrawable.java b/v7/appcompat/src/main/java/android/support/v7/widget/ActionBarBackgroundDrawable.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ActionBarBackgroundDrawable.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ActionBarBackgroundDrawable.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionBarBackgroundDrawableV21.java b/v7/appcompat/src/main/java/android/support/v7/widget/ActionBarBackgroundDrawableV21.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ActionBarBackgroundDrawableV21.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ActionBarBackgroundDrawableV21.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionBarContainer.java b/v7/appcompat/src/main/java/android/support/v7/widget/ActionBarContainer.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ActionBarContainer.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ActionBarContainer.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionBarContextView.java b/v7/appcompat/src/main/java/android/support/v7/widget/ActionBarContextView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ActionBarContextView.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ActionBarContextView.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionBarOverlayLayout.java b/v7/appcompat/src/main/java/android/support/v7/widget/ActionBarOverlayLayout.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ActionBarOverlayLayout.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ActionBarOverlayLayout.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java b/v7/appcompat/src/main/java/android/support/v7/widget/ActionMenuPresenter.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ActionMenuPresenter.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionMenuView.java b/v7/appcompat/src/main/java/android/support/v7/widget/ActionMenuView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ActionMenuView.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ActionMenuView.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ActivityChooserModel.java b/v7/appcompat/src/main/java/android/support/v7/widget/ActivityChooserModel.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ActivityChooserModel.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ActivityChooserModel.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ActivityChooserView.java b/v7/appcompat/src/main/java/android/support/v7/widget/ActivityChooserView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ActivityChooserView.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ActivityChooserView.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AlertDialogLayout.java b/v7/appcompat/src/main/java/android/support/v7/widget/AlertDialogLayout.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AlertDialogLayout.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AlertDialogLayout.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatAutoCompleteTextView.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatAutoCompleteTextView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatAutoCompleteTextView.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatAutoCompleteTextView.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatBackgroundHelper.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatBackgroundHelper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatBackgroundHelper.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatBackgroundHelper.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatButton.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatButton.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatButton.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatButton.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatCheckBox.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatCheckBox.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatCheckBox.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatCheckBox.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatCheckedTextView.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatCheckedTextView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatCheckedTextView.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatCheckedTextView.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatCompoundButtonHelper.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatCompoundButtonHelper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatCompoundButtonHelper.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatCompoundButtonHelper.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatDrawableManager.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatDrawableManager.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatEditText.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatEditText.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatEditText.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatEditText.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatImageButton.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatImageButton.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatImageButton.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatImageButton.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatImageHelper.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatImageHelper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatImageHelper.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatImageHelper.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatImageView.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatImageView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatImageView.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatImageView.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatMultiAutoCompleteTextView.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatMultiAutoCompleteTextView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatMultiAutoCompleteTextView.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatMultiAutoCompleteTextView.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatPopupWindow.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatPopupWindow.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatPopupWindow.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatPopupWindow.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatProgressBarHelper.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatProgressBarHelper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatProgressBarHelper.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatProgressBarHelper.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatRadioButton.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatRadioButton.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatRadioButton.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatRadioButton.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatRatingBar.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatRatingBar.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatRatingBar.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatRatingBar.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatSeekBar.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatSeekBar.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatSeekBar.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatSeekBar.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatSeekBarHelper.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatSeekBarHelper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatSeekBarHelper.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatSeekBarHelper.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatSpinner.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatSpinner.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatSpinner.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatSpinner.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelper.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatTextHelper.java
similarity index 99%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatTextHelper.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatTextHelper.java
index 75fa38f..51510aa 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelper.java
+++ b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatTextHelper.java
@@ -214,7 +214,7 @@
: R.styleable.TextAppearance_fontFamily;
if (!context.isRestricted()) {
try {
- mFontTypeface = a.getFont(fontFamilyId, mStyle, mView);
+ mFontTypeface = a.getFont(fontFamilyId, mStyle);
} catch (UnsupportedOperationException | Resources.NotFoundException e) {
// Expected if it is not a font resource.
}
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelperV17.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatTextHelperV17.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatTextHelperV17.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatTextHelperV17.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatTextView.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatTextView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatTextView.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatTextView.java
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatTextViewAutoSizeHelper.java b/v7/appcompat/src/main/java/android/support/v7/widget/AppCompatTextViewAutoSizeHelper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/AppCompatTextViewAutoSizeHelper.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/AppCompatTextViewAutoSizeHelper.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ButtonBarLayout.java b/v7/appcompat/src/main/java/android/support/v7/widget/ButtonBarLayout.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ButtonBarLayout.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ButtonBarLayout.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ContentFrameLayout.java b/v7/appcompat/src/main/java/android/support/v7/widget/ContentFrameLayout.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ContentFrameLayout.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ContentFrameLayout.java
diff --git a/v7/appcompat/src/android/support/v7/widget/DecorContentParent.java b/v7/appcompat/src/main/java/android/support/v7/widget/DecorContentParent.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/DecorContentParent.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/DecorContentParent.java
diff --git a/v7/appcompat/src/android/support/v7/widget/DecorToolbar.java b/v7/appcompat/src/main/java/android/support/v7/widget/DecorToolbar.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/DecorToolbar.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/DecorToolbar.java
diff --git a/v7/appcompat/src/android/support/v7/widget/DialogTitle.java b/v7/appcompat/src/main/java/android/support/v7/widget/DialogTitle.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/DialogTitle.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/DialogTitle.java
diff --git a/v7/appcompat/src/android/support/v7/widget/DrawableUtils.java b/v7/appcompat/src/main/java/android/support/v7/widget/DrawableUtils.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/DrawableUtils.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/DrawableUtils.java
diff --git a/v7/appcompat/src/android/support/v7/widget/DropDownListView.java b/v7/appcompat/src/main/java/android/support/v7/widget/DropDownListView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/DropDownListView.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/DropDownListView.java
diff --git a/v7/appcompat/src/android/support/v7/widget/FitWindowsFrameLayout.java b/v7/appcompat/src/main/java/android/support/v7/widget/FitWindowsFrameLayout.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/FitWindowsFrameLayout.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/FitWindowsFrameLayout.java
diff --git a/v7/appcompat/src/android/support/v7/widget/FitWindowsLinearLayout.java b/v7/appcompat/src/main/java/android/support/v7/widget/FitWindowsLinearLayout.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/FitWindowsLinearLayout.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/FitWindowsLinearLayout.java
diff --git a/v7/appcompat/src/android/support/v7/widget/FitWindowsViewGroup.java b/v7/appcompat/src/main/java/android/support/v7/widget/FitWindowsViewGroup.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/FitWindowsViewGroup.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/FitWindowsViewGroup.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ForwardingListener.java b/v7/appcompat/src/main/java/android/support/v7/widget/ForwardingListener.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ForwardingListener.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ForwardingListener.java
diff --git a/v7/appcompat/src/android/support/v7/widget/LinearLayoutCompat.java b/v7/appcompat/src/main/java/android/support/v7/widget/LinearLayoutCompat.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/LinearLayoutCompat.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/LinearLayoutCompat.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ListPopupWindow.java b/v7/appcompat/src/main/java/android/support/v7/widget/ListPopupWindow.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ListPopupWindow.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ListPopupWindow.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ListViewCompat.java b/v7/appcompat/src/main/java/android/support/v7/widget/ListViewCompat.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ListViewCompat.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ListViewCompat.java
diff --git a/v7/appcompat/src/android/support/v7/widget/MenuItemHoverListener.java b/v7/appcompat/src/main/java/android/support/v7/widget/MenuItemHoverListener.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/MenuItemHoverListener.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/MenuItemHoverListener.java
diff --git a/v7/appcompat/src/android/support/v7/widget/MenuPopupWindow.java b/v7/appcompat/src/main/java/android/support/v7/widget/MenuPopupWindow.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/MenuPopupWindow.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/MenuPopupWindow.java
diff --git a/v7/appcompat/src/android/support/v7/widget/PopupMenu.java b/v7/appcompat/src/main/java/android/support/v7/widget/PopupMenu.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/PopupMenu.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/PopupMenu.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ResourcesWrapper.java b/v7/appcompat/src/main/java/android/support/v7/widget/ResourcesWrapper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ResourcesWrapper.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ResourcesWrapper.java
diff --git a/v7/appcompat/src/android/support/v7/widget/RtlSpacingHelper.java b/v7/appcompat/src/main/java/android/support/v7/widget/RtlSpacingHelper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/RtlSpacingHelper.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/RtlSpacingHelper.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ScrollingTabContainerView.java b/v7/appcompat/src/main/java/android/support/v7/widget/ScrollingTabContainerView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ScrollingTabContainerView.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ScrollingTabContainerView.java
diff --git a/v7/appcompat/src/android/support/v7/widget/SearchView.java b/v7/appcompat/src/main/java/android/support/v7/widget/SearchView.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/SearchView.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/SearchView.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ShareActionProvider.java b/v7/appcompat/src/main/java/android/support/v7/widget/ShareActionProvider.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ShareActionProvider.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ShareActionProvider.java
diff --git a/v7/appcompat/src/android/support/v7/widget/SuggestionsAdapter.java b/v7/appcompat/src/main/java/android/support/v7/widget/SuggestionsAdapter.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/SuggestionsAdapter.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/SuggestionsAdapter.java
diff --git a/v7/appcompat/src/android/support/v7/widget/SwitchCompat.java b/v7/appcompat/src/main/java/android/support/v7/widget/SwitchCompat.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/SwitchCompat.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/SwitchCompat.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ThemeUtils.java b/v7/appcompat/src/main/java/android/support/v7/widget/ThemeUtils.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ThemeUtils.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ThemeUtils.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ThemedSpinnerAdapter.java b/v7/appcompat/src/main/java/android/support/v7/widget/ThemedSpinnerAdapter.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ThemedSpinnerAdapter.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ThemedSpinnerAdapter.java
diff --git a/v7/appcompat/src/android/support/v7/widget/TintContextWrapper.java b/v7/appcompat/src/main/java/android/support/v7/widget/TintContextWrapper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/TintContextWrapper.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/TintContextWrapper.java
diff --git a/v7/appcompat/src/android/support/v7/widget/TintInfo.java b/v7/appcompat/src/main/java/android/support/v7/widget/TintInfo.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/TintInfo.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/TintInfo.java
diff --git a/v7/appcompat/src/android/support/v7/widget/TintResources.java b/v7/appcompat/src/main/java/android/support/v7/widget/TintResources.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/TintResources.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/TintResources.java
diff --git a/v7/appcompat/src/android/support/v7/widget/TintTypedArray.java b/v7/appcompat/src/main/java/android/support/v7/widget/TintTypedArray.java
similarity index 95%
rename from v7/appcompat/src/android/support/v7/widget/TintTypedArray.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/TintTypedArray.java
index 2213dd3..2270955 100644
--- a/v7/appcompat/src/android/support/v7/widget/TintTypedArray.java
+++ b/v7/appcompat/src/main/java/android/support/v7/widget/TintTypedArray.java
@@ -25,7 +25,6 @@
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
-import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.annotation.RestrictTo;
@@ -34,7 +33,6 @@
import android.support.v7.content.res.AppCompatResources;
import android.util.AttributeSet;
import android.util.TypedValue;
-import android.widget.TextView;
/**
* A class that wraps a {@link android.content.res.TypedArray} and provides the same public API
@@ -98,9 +96,9 @@
*
* @param index Index of attribute to retrieve.
* @param style A style value used for selecting best match font from the list of family. Note
- * that this value will be ignored if the platform supports font family(API 24 or later).
- * @param targetView A text view to be applied this font. If async loading is specified in XML,
- * this view will be refreshed with result typeface.
+ * that this value will be ignored if the platform supports font family (API 24 or later).
+ * @param fontCallback A callback to receive async fetching of this font. If async loading is
+ * specified in XML, this callback will be triggered.
*
* @return Typeface for the attribute, or {@code null} if not defined.
* @throws RuntimeException if the TypedArray has already been recycled.
@@ -108,7 +106,7 @@
* not a font resource.
*/
@Nullable
- public Typeface getFont(@StyleableRes int index, int style, @NonNull TextView targetView) {
+ public Typeface getFont(@StyleableRes int index, int style) {
final int resourceId = mWrapped.getResourceId(index, 0);
if (resourceId == 0) {
return null;
@@ -116,7 +114,7 @@
if (mTypedValue == null) {
mTypedValue = new TypedValue();
}
- return ResourcesCompat.getFont(mContext, resourceId, mTypedValue, style, targetView);
+ return ResourcesCompat.getFont(mContext, resourceId, mTypedValue, style);
}
public int length() {
diff --git a/v7/appcompat/src/android/support/v7/widget/Toolbar.java b/v7/appcompat/src/main/java/android/support/v7/widget/Toolbar.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/Toolbar.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/Toolbar.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ToolbarWidgetWrapper.java b/v7/appcompat/src/main/java/android/support/v7/widget/ToolbarWidgetWrapper.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ToolbarWidgetWrapper.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ToolbarWidgetWrapper.java
diff --git a/v7/appcompat/src/android/support/v7/widget/TooltipCompat.java b/v7/appcompat/src/main/java/android/support/v7/widget/TooltipCompat.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/TooltipCompat.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/TooltipCompat.java
diff --git a/v7/appcompat/src/android/support/v7/widget/TooltipCompatHandler.java b/v7/appcompat/src/main/java/android/support/v7/widget/TooltipCompatHandler.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/TooltipCompatHandler.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/TooltipCompatHandler.java
diff --git a/v7/appcompat/src/android/support/v7/widget/TooltipPopup.java b/v7/appcompat/src/main/java/android/support/v7/widget/TooltipPopup.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/TooltipPopup.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/TooltipPopup.java
diff --git a/v7/appcompat/src/android/support/v7/widget/VectorEnabledTintResources.java b/v7/appcompat/src/main/java/android/support/v7/widget/VectorEnabledTintResources.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/VectorEnabledTintResources.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/VectorEnabledTintResources.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ViewStubCompat.java b/v7/appcompat/src/main/java/android/support/v7/widget/ViewStubCompat.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ViewStubCompat.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ViewStubCompat.java
diff --git a/v7/appcompat/src/android/support/v7/widget/ViewUtils.java b/v7/appcompat/src/main/java/android/support/v7/widget/ViewUtils.java
similarity index 100%
rename from v7/appcompat/src/android/support/v7/widget/ViewUtils.java
rename to v7/appcompat/src/main/java/android/support/v7/widget/ViewUtils.java
diff --git a/v7/cardview/Android.mk b/v7/cardview/Android.mk
index 56fa996..19d377c 100644
--- a/v7/cardview/Android.mk
+++ b/v7/cardview/Android.mk
@@ -25,7 +25,7 @@
LOCAL_MODULE := android-support-v7-cardview
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
LOCAL_SRC_FILES := \
- $(call all-java-files-under,src)
+ $(call all-java-files-under,src/main/java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-annotations
diff --git a/v7/cardview/build.gradle b/v7/cardview/build.gradle
index 5d9494e..76c3bf3 100644
--- a/v7/cardview/build.gradle
+++ b/v7/cardview/build.gradle
@@ -10,9 +10,6 @@
}
sourceSets {
- main.java.srcDirs = [
- 'src'
- ]
main.res.srcDir 'res'
}
}
diff --git a/v7/cardview/src/android/support/v7/widget/CardView.java b/v7/cardview/src/main/java/android/support/v7/widget/CardView.java
similarity index 98%
rename from v7/cardview/src/android/support/v7/widget/CardView.java
rename to v7/cardview/src/main/java/android/support/v7/widget/CardView.java
index 3df45d9..58a04f0 100644
--- a/v7/cardview/src/android/support/v7/widget/CardView.java
+++ b/v7/cardview/src/main/java/android/support/v7/widget/CardView.java
@@ -24,6 +24,7 @@
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.ColorInt;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.cardview.R;
import android.util.AttributeSet;
@@ -106,17 +107,17 @@
final Rect mShadowBounds = new Rect();
- public CardView(Context context) {
+ public CardView(@NonNull Context context) {
super(context);
initialize(context, null, 0);
}
- public CardView(Context context, AttributeSet attrs) {
+ public CardView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initialize(context, attrs, 0);
}
- public CardView(Context context, AttributeSet attrs, int defStyleAttr) {
+ public CardView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize(context, attrs, defStyleAttr);
}
@@ -300,6 +301,7 @@
*
* @return The background color state list of the CardView.
*/
+ @NonNull
public ColorStateList getCardBackgroundColor() {
return IMPL.getBackgroundColor(mCardViewDelegate);
}
diff --git a/v7/cardview/src/android/support/v7/widget/CardViewApi17Impl.java b/v7/cardview/src/main/java/android/support/v7/widget/CardViewApi17Impl.java
similarity index 100%
rename from v7/cardview/src/android/support/v7/widget/CardViewApi17Impl.java
rename to v7/cardview/src/main/java/android/support/v7/widget/CardViewApi17Impl.java
diff --git a/v7/cardview/src/android/support/v7/widget/CardViewApi21Impl.java b/v7/cardview/src/main/java/android/support/v7/widget/CardViewApi21Impl.java
similarity index 100%
rename from v7/cardview/src/android/support/v7/widget/CardViewApi21Impl.java
rename to v7/cardview/src/main/java/android/support/v7/widget/CardViewApi21Impl.java
diff --git a/v7/cardview/src/android/support/v7/widget/CardViewBaseImpl.java b/v7/cardview/src/main/java/android/support/v7/widget/CardViewBaseImpl.java
similarity index 100%
rename from v7/cardview/src/android/support/v7/widget/CardViewBaseImpl.java
rename to v7/cardview/src/main/java/android/support/v7/widget/CardViewBaseImpl.java
diff --git a/v7/cardview/src/android/support/v7/widget/CardViewDelegate.java b/v7/cardview/src/main/java/android/support/v7/widget/CardViewDelegate.java
similarity index 100%
rename from v7/cardview/src/android/support/v7/widget/CardViewDelegate.java
rename to v7/cardview/src/main/java/android/support/v7/widget/CardViewDelegate.java
diff --git a/v7/cardview/src/android/support/v7/widget/CardViewImpl.java b/v7/cardview/src/main/java/android/support/v7/widget/CardViewImpl.java
similarity index 100%
rename from v7/cardview/src/android/support/v7/widget/CardViewImpl.java
rename to v7/cardview/src/main/java/android/support/v7/widget/CardViewImpl.java
diff --git a/v7/cardview/src/android/support/v7/widget/RoundRectDrawable.java b/v7/cardview/src/main/java/android/support/v7/widget/RoundRectDrawable.java
similarity index 100%
rename from v7/cardview/src/android/support/v7/widget/RoundRectDrawable.java
rename to v7/cardview/src/main/java/android/support/v7/widget/RoundRectDrawable.java
diff --git a/v7/cardview/src/android/support/v7/widget/RoundRectDrawableWithShadow.java b/v7/cardview/src/main/java/android/support/v7/widget/RoundRectDrawableWithShadow.java
similarity index 100%
rename from v7/cardview/src/android/support/v7/widget/RoundRectDrawableWithShadow.java
rename to v7/cardview/src/main/java/android/support/v7/widget/RoundRectDrawableWithShadow.java
diff --git a/v7/gridlayout/Android.mk b/v7/gridlayout/Android.mk
index 6eac23b4..5091081 100644
--- a/v7/gridlayout/Android.mk
+++ b/v7/gridlayout/Android.mk
@@ -27,7 +27,7 @@
LOCAL_USE_AAPT2 := true
LOCAL_MODULE := android-support-v7-gridlayout
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES := $(call all-java-files-under, src/main/java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
diff --git a/v7/gridlayout/build.gradle b/v7/gridlayout/build.gradle
index e0df821..d4d467d 100644
--- a/v7/gridlayout/build.gradle
+++ b/v7/gridlayout/build.gradle
@@ -14,7 +14,6 @@
}
sourceSets {
- main.java.srcDir 'src'
main.res.srcDir 'res'
}
}
diff --git a/v7/gridlayout/src/android/support/v7/widget/GridLayout.java b/v7/gridlayout/src/main/java/android/support/v7/widget/GridLayout.java
similarity index 100%
rename from v7/gridlayout/src/android/support/v7/widget/GridLayout.java
rename to v7/gridlayout/src/main/java/android/support/v7/widget/GridLayout.java
diff --git a/v7/palette/src/main/java/android/support/v7/graphics/Palette.java b/v7/palette/src/main/java/android/support/v7/graphics/Palette.java
index b7fb054..e716fb5 100644
--- a/v7/palette/src/main/java/android/support/v7/graphics/Palette.java
+++ b/v7/palette/src/main/java/android/support/v7/graphics/Palette.java
@@ -80,7 +80,7 @@
/**
* Called when the {@link Palette} has been generated.
*/
- void onGenerated(Palette palette);
+ void onGenerated(@NonNull Palette palette);
}
static final int DEFAULT_RESIZE_BITMAP_AREA = 112 * 112;
@@ -95,7 +95,8 @@
/**
* Start generating a {@link Palette} with the returned {@link Builder} instance.
*/
- public static Builder from(Bitmap bitmap) {
+ @NonNull
+ public static Builder from(@NonNull Bitmap bitmap) {
return new Builder(bitmap);
}
@@ -104,7 +105,8 @@
* This is useful for testing, or if you want to resurrect a {@link Palette} instance from a
* list of swatches. Will return null if the {@code swatches} is null.
*/
- public static Palette from(List<Swatch> swatches) {
+ @NonNull
+ public static Palette from(@NonNull List<Swatch> swatches) {
return new Builder(swatches).generate();
}
@@ -484,6 +486,7 @@
* hsv[1] is Saturation [0...1]
* hsv[2] is Lightness [0...1]
*/
+ @NonNull
public float[] getHsl() {
if (mHsl == null) {
mHsl = new float[3];
@@ -610,7 +613,7 @@
/**
* Construct a new {@link Builder} using a source {@link Bitmap}
*/
- public Builder(Bitmap bitmap) {
+ public Builder(@NonNull Bitmap bitmap) {
if (bitmap == null || bitmap.isRecycled()) {
throw new IllegalArgumentException("Bitmap is not valid");
}
@@ -631,7 +634,7 @@
* Construct a new {@link Builder} using a list of {@link Swatch} instances.
* Typically only used for testing.
*/
- public Builder(List<Swatch> swatches) {
+ public Builder(@NonNull List<Swatch> swatches) {
if (swatches == null || swatches.isEmpty()) {
throw new IllegalArgumentException("List of Swatches is not valid");
}
@@ -850,7 +853,8 @@
* generated.
*/
@NonNull
- public AsyncTask<Bitmap, Void, Palette> generate(final PaletteAsyncListener listener) {
+ public AsyncTask<Bitmap, Void, Palette> generate(
+ @NonNull final PaletteAsyncListener listener) {
if (listener == null) {
throw new IllegalArgumentException("listener can not be null");
}
@@ -943,7 +947,7 @@
*
* @see Builder#addFilter(Filter)
*/
- boolean isAllowed(int rgb, float[] hsl);
+ boolean isAllowed(@ColorInt int rgb, @NonNull float[] hsl);
}
/**
diff --git a/v7/palette/src/main/java/android/support/v7/graphics/Target.java b/v7/palette/src/main/java/android/support/v7/graphics/Target.java
index 640970b..0eff90b 100644
--- a/v7/palette/src/main/java/android/support/v7/graphics/Target.java
+++ b/v7/palette/src/main/java/android/support/v7/graphics/Target.java
@@ -17,6 +17,7 @@
package android.support.v7.graphics;
import android.support.annotation.FloatRange;
+import android.support.annotation.NonNull;
/**
* A class which allows custom selection of colors in a {@link Palette}'s generation. Instances
@@ -122,7 +123,7 @@
setDefaultWeights();
}
- Target(Target from) {
+ Target(@NonNull Target from) {
System.arraycopy(from.mSaturationTargets, 0, mSaturationTargets, 0,
mSaturationTargets.length);
System.arraycopy(from.mLightnessTargets, 0, mLightnessTargets, 0,
@@ -295,13 +296,14 @@
/**
* Create a new builder based on an existing {@link Target}.
*/
- public Builder(Target target) {
+ public Builder(@NonNull Target target) {
mTarget = new Target(target);
}
/**
* Set the minimum saturation value for this target.
*/
+ @NonNull
public Builder setMinimumSaturation(@FloatRange(from = 0, to = 1) float value) {
mTarget.mSaturationTargets[INDEX_MIN] = value;
return this;
@@ -310,6 +312,7 @@
/**
* Set the target/ideal saturation value for this target.
*/
+ @NonNull
public Builder setTargetSaturation(@FloatRange(from = 0, to = 1) float value) {
mTarget.mSaturationTargets[INDEX_TARGET] = value;
return this;
@@ -318,6 +321,7 @@
/**
* Set the maximum saturation value for this target.
*/
+ @NonNull
public Builder setMaximumSaturation(@FloatRange(from = 0, to = 1) float value) {
mTarget.mSaturationTargets[INDEX_MAX] = value;
return this;
@@ -326,6 +330,7 @@
/**
* Set the minimum lightness value for this target.
*/
+ @NonNull
public Builder setMinimumLightness(@FloatRange(from = 0, to = 1) float value) {
mTarget.mLightnessTargets[INDEX_MIN] = value;
return this;
@@ -334,6 +339,7 @@
/**
* Set the target/ideal lightness value for this target.
*/
+ @NonNull
public Builder setTargetLightness(@FloatRange(from = 0, to = 1) float value) {
mTarget.mLightnessTargets[INDEX_TARGET] = value;
return this;
@@ -342,6 +348,7 @@
/**
* Set the maximum lightness value for this target.
*/
+ @NonNull
public Builder setMaximumLightness(@FloatRange(from = 0, to = 1) float value) {
mTarget.mLightnessTargets[INDEX_MAX] = value;
return this;
@@ -358,6 +365,7 @@
*
* @see #setTargetSaturation(float)
*/
+ @NonNull
public Builder setSaturationWeight(@FloatRange(from = 0) float weight) {
mTarget.mWeights[INDEX_WEIGHT_SAT] = weight;
return this;
@@ -374,6 +382,7 @@
*
* @see #setTargetLightness(float)
*/
+ @NonNull
public Builder setLightnessWeight(@FloatRange(from = 0) float weight) {
mTarget.mWeights[INDEX_WEIGHT_LUMA] = weight;
return this;
@@ -389,6 +398,7 @@
* <p>A weight of 0 means that it has no weight, and thus has no
* bearing on the selection.</p>
*/
+ @NonNull
public Builder setPopulationWeight(@FloatRange(from = 0) float weight) {
mTarget.mWeights[INDEX_WEIGHT_POP] = weight;
return this;
@@ -401,6 +411,7 @@
* @param exclusive true if any the color is exclusive to this target, or false is the
* color can be selected for other targets.
*/
+ @NonNull
public Builder setExclusive(boolean exclusive) {
mTarget.mIsExclusive = exclusive;
return this;
@@ -409,6 +420,7 @@
/**
* Builds and returns the resulting {@link Target}.
*/
+ @NonNull
public Target build() {
return mTarget;
}
diff --git a/v7/recyclerview/Android.mk b/v7/recyclerview/Android.mk
index e434ab2..dcebe88 100644
--- a/v7/recyclerview/Android.mk
+++ b/v7/recyclerview/Android.mk
@@ -27,7 +27,7 @@
LOCAL_USE_AAPT2 := true
LOCAL_MODULE := android-support-v7-recyclerview
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
+LOCAL_SRC_FILES := $(call all-java-files-under,src/main/java)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
diff --git a/v7/recyclerview/build.gradle b/v7/recyclerview/build.gradle
index e035b82..ad1150f 100644
--- a/v7/recyclerview/build.gradle
+++ b/v7/recyclerview/build.gradle
@@ -23,10 +23,7 @@
}
sourceSets {
- main.java.srcDir 'src'
main.res.srcDirs 'res', 'res-public'
-
- test.java.srcDir 'jvm-tests/src'
}
testOptions {
diff --git a/v7/recyclerview/src/android/support/v7/util/AsyncListUtil.java b/v7/recyclerview/src/main/java/android/support/v7/util/AsyncListUtil.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/util/AsyncListUtil.java
rename to v7/recyclerview/src/main/java/android/support/v7/util/AsyncListUtil.java
diff --git a/v7/recyclerview/src/android/support/v7/util/BatchingListUpdateCallback.java b/v7/recyclerview/src/main/java/android/support/v7/util/BatchingListUpdateCallback.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/util/BatchingListUpdateCallback.java
rename to v7/recyclerview/src/main/java/android/support/v7/util/BatchingListUpdateCallback.java
diff --git a/v7/recyclerview/src/android/support/v7/util/DiffUtil.java b/v7/recyclerview/src/main/java/android/support/v7/util/DiffUtil.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/util/DiffUtil.java
rename to v7/recyclerview/src/main/java/android/support/v7/util/DiffUtil.java
diff --git a/v7/recyclerview/src/android/support/v7/util/ListUpdateCallback.java b/v7/recyclerview/src/main/java/android/support/v7/util/ListUpdateCallback.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/util/ListUpdateCallback.java
rename to v7/recyclerview/src/main/java/android/support/v7/util/ListUpdateCallback.java
diff --git a/v7/recyclerview/src/android/support/v7/util/MessageThreadUtil.java b/v7/recyclerview/src/main/java/android/support/v7/util/MessageThreadUtil.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/util/MessageThreadUtil.java
rename to v7/recyclerview/src/main/java/android/support/v7/util/MessageThreadUtil.java
diff --git a/v7/recyclerview/src/android/support/v7/util/SortedList.java b/v7/recyclerview/src/main/java/android/support/v7/util/SortedList.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/util/SortedList.java
rename to v7/recyclerview/src/main/java/android/support/v7/util/SortedList.java
diff --git a/v7/recyclerview/src/android/support/v7/util/ThreadUtil.java b/v7/recyclerview/src/main/java/android/support/v7/util/ThreadUtil.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/util/ThreadUtil.java
rename to v7/recyclerview/src/main/java/android/support/v7/util/ThreadUtil.java
diff --git a/v7/recyclerview/src/android/support/v7/util/TileList.java b/v7/recyclerview/src/main/java/android/support/v7/util/TileList.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/util/TileList.java
rename to v7/recyclerview/src/main/java/android/support/v7/util/TileList.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/AdapterHelper.java b/v7/recyclerview/src/main/java/android/support/v7/widget/AdapterHelper.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/AdapterHelper.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/AdapterHelper.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/ChildHelper.java b/v7/recyclerview/src/main/java/android/support/v7/widget/ChildHelper.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/ChildHelper.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/ChildHelper.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/DefaultItemAnimator.java b/v7/recyclerview/src/main/java/android/support/v7/widget/DefaultItemAnimator.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/DefaultItemAnimator.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/DefaultItemAnimator.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/DividerItemDecoration.java b/v7/recyclerview/src/main/java/android/support/v7/widget/DividerItemDecoration.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/DividerItemDecoration.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/DividerItemDecoration.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/FastScroller.java b/v7/recyclerview/src/main/java/android/support/v7/widget/FastScroller.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/FastScroller.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/FastScroller.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/GapWorker.java b/v7/recyclerview/src/main/java/android/support/v7/widget/GapWorker.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/GapWorker.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/GapWorker.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/GridLayoutManager.java b/v7/recyclerview/src/main/java/android/support/v7/widget/GridLayoutManager.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/GridLayoutManager.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/GridLayoutManager.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/LayoutState.java b/v7/recyclerview/src/main/java/android/support/v7/widget/LayoutState.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/LayoutState.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/LayoutState.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java b/v7/recyclerview/src/main/java/android/support/v7/widget/LinearLayoutManager.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/LinearLayoutManager.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/LinearSmoothScroller.java b/v7/recyclerview/src/main/java/android/support/v7/widget/LinearSmoothScroller.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/LinearSmoothScroller.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/LinearSmoothScroller.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/LinearSnapHelper.java b/v7/recyclerview/src/main/java/android/support/v7/widget/LinearSnapHelper.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/LinearSnapHelper.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/LinearSnapHelper.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/OpReorderer.java b/v7/recyclerview/src/main/java/android/support/v7/widget/OpReorderer.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/OpReorderer.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/OpReorderer.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/OrientationHelper.java b/v7/recyclerview/src/main/java/android/support/v7/widget/OrientationHelper.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/OrientationHelper.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/OrientationHelper.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/PagerSnapHelper.java b/v7/recyclerview/src/main/java/android/support/v7/widget/PagerSnapHelper.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/PagerSnapHelper.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/PagerSnapHelper.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/PositionMap.java b/v7/recyclerview/src/main/java/android/support/v7/widget/PositionMap.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/PositionMap.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/PositionMap.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java b/v7/recyclerview/src/main/java/android/support/v7/widget/RecyclerView.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/RecyclerView.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/RecyclerViewAccessibilityDelegate.java b/v7/recyclerview/src/main/java/android/support/v7/widget/RecyclerViewAccessibilityDelegate.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/RecyclerViewAccessibilityDelegate.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/RecyclerViewAccessibilityDelegate.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/ScrollbarHelper.java b/v7/recyclerview/src/main/java/android/support/v7/widget/ScrollbarHelper.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/ScrollbarHelper.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/ScrollbarHelper.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/SimpleItemAnimator.java b/v7/recyclerview/src/main/java/android/support/v7/widget/SimpleItemAnimator.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/SimpleItemAnimator.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/SimpleItemAnimator.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/SnapHelper.java b/v7/recyclerview/src/main/java/android/support/v7/widget/SnapHelper.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/SnapHelper.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/SnapHelper.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/StaggeredGridLayoutManager.java b/v7/recyclerview/src/main/java/android/support/v7/widget/StaggeredGridLayoutManager.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/StaggeredGridLayoutManager.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/StaggeredGridLayoutManager.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/ViewBoundsCheck.java b/v7/recyclerview/src/main/java/android/support/v7/widget/ViewBoundsCheck.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/ViewBoundsCheck.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/ViewBoundsCheck.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/ViewInfoStore.java b/v7/recyclerview/src/main/java/android/support/v7/widget/ViewInfoStore.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/ViewInfoStore.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/ViewInfoStore.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchHelper.java b/v7/recyclerview/src/main/java/android/support/v7/widget/helper/ItemTouchHelper.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchHelper.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/helper/ItemTouchHelper.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchUIUtil.java b/v7/recyclerview/src/main/java/android/support/v7/widget/helper/ItemTouchUIUtil.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchUIUtil.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/helper/ItemTouchUIUtil.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchUIUtilImpl.java b/v7/recyclerview/src/main/java/android/support/v7/widget/helper/ItemTouchUIUtilImpl.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchUIUtilImpl.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/helper/ItemTouchUIUtilImpl.java
diff --git a/v7/recyclerview/src/android/support/v7/widget/util/SortedListAdapterCallback.java b/v7/recyclerview/src/main/java/android/support/v7/widget/util/SortedListAdapterCallback.java
similarity index 100%
rename from v7/recyclerview/src/android/support/v7/widget/util/SortedListAdapterCallback.java
rename to v7/recyclerview/src/main/java/android/support/v7/widget/util/SortedListAdapterCallback.java
diff --git a/v7/recyclerview/jvm-tests/NO_DOCS b/v7/recyclerview/src/test/NO_DOCS
similarity index 100%
rename from v7/recyclerview/jvm-tests/NO_DOCS
rename to v7/recyclerview/src/test/NO_DOCS
diff --git a/v7/recyclerview/jvm-tests/src/android/support/v7/util/BatchingListUpdateCallbackTest.java b/v7/recyclerview/src/test/java/android/support/v7/util/BatchingListUpdateCallbackTest.java
similarity index 100%
rename from v7/recyclerview/jvm-tests/src/android/support/v7/util/BatchingListUpdateCallbackTest.java
rename to v7/recyclerview/src/test/java/android/support/v7/util/BatchingListUpdateCallbackTest.java
diff --git a/v7/recyclerview/jvm-tests/src/android/support/v7/util/DiffUtilTest.java b/v7/recyclerview/src/test/java/android/support/v7/util/DiffUtilTest.java
similarity index 100%
rename from v7/recyclerview/jvm-tests/src/android/support/v7/util/DiffUtilTest.java
rename to v7/recyclerview/src/test/java/android/support/v7/util/DiffUtilTest.java
diff --git a/v7/recyclerview/jvm-tests/src/android/support/v7/util/SortedListBatchedCallbackTest.java b/v7/recyclerview/src/test/java/android/support/v7/util/SortedListBatchedCallbackTest.java
similarity index 100%
rename from v7/recyclerview/jvm-tests/src/android/support/v7/util/SortedListBatchedCallbackTest.java
rename to v7/recyclerview/src/test/java/android/support/v7/util/SortedListBatchedCallbackTest.java
diff --git a/v7/recyclerview/jvm-tests/src/android/support/v7/util/SortedListTest.java b/v7/recyclerview/src/test/java/android/support/v7/util/SortedListTest.java
similarity index 100%
rename from v7/recyclerview/jvm-tests/src/android/support/v7/util/SortedListTest.java
rename to v7/recyclerview/src/test/java/android/support/v7/util/SortedListTest.java
diff --git a/v7/recyclerview/jvm-tests/src/android/support/v7/widget/AdapterHelperTest.java b/v7/recyclerview/src/test/java/android/support/v7/widget/AdapterHelperTest.java
similarity index 100%
rename from v7/recyclerview/jvm-tests/src/android/support/v7/widget/AdapterHelperTest.java
rename to v7/recyclerview/src/test/java/android/support/v7/widget/AdapterHelperTest.java
diff --git a/v7/recyclerview/jvm-tests/src/android/support/v7/widget/OpReorderTest.java b/v7/recyclerview/src/test/java/android/support/v7/widget/OpReorderTest.java
similarity index 100%
rename from v7/recyclerview/jvm-tests/src/android/support/v7/widget/OpReorderTest.java
rename to v7/recyclerview/src/test/java/android/support/v7/widget/OpReorderTest.java
diff --git a/v7/recyclerview/jvm-tests/src/android/support/v7/widget/ViewInfoStoreTest.java b/v7/recyclerview/src/test/java/android/support/v7/widget/ViewInfoStoreTest.java
similarity index 100%
rename from v7/recyclerview/jvm-tests/src/android/support/v7/widget/ViewInfoStoreTest.java
rename to v7/recyclerview/src/test/java/android/support/v7/widget/ViewInfoStoreTest.java
diff --git a/wear/Android.mk b/wear/Android.mk
index eec890b..fde4aa1 100644
--- a/wear/Android.mk
+++ b/wear/Android.mk
@@ -14,6 +14,12 @@
LOCAL_PATH := $(call my-dir)
+# Here is a prebuilt library containing all the wearable stubs necessary for ambient mode
+include $(CLEAR_VARS)
+LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
+ prebuilt-com.google.android.wearable-stubs:wear_stubs/com.google.android.wearable-stubs.jar
+include $(BUILD_MULTI_PREBUILT)
+
# Here is the final static library that apps can link against.
# Applications that use this library must specify
#
@@ -22,7 +28,8 @@
# android-support-core-ui \
# android-support-v7-recyclerview
#
-# in their makefiles to include the resources and their dependencies in their package.
+# in their makefiles to include the resources and their dependencies in their package
+
include $(CLEAR_VARS)
LOCAL_USE_AAPT2 := true
LOCAL_MODULE := android-support-wear
@@ -35,7 +42,10 @@
android-support-percent \
android-support-v7-recyclerview \
android-support-v4
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ prebuilt-com.google.android.wearable-stubs
LOCAL_JAR_EXCLUDE_FILES := none
LOCAL_JAVA_LANGUAGE_VERSION := 1.7
LOCAL_AAPT_FLAGS := --add-javadoc-annotation doconly
include $(BUILD_STATIC_JAVA_LIBRARY)
+
diff --git a/wear/api/current.txt b/wear/api/current.txt
index afffeed..e397eb3 100644
--- a/wear/api/current.txt
+++ b/wear/api/current.txt
@@ -1,3 +1,31 @@
+package android.support.wear.ambient {
+
+ public final class AmbientMode extends android.app.Fragment {
+ ctor public AmbientMode();
+ method public static <T extends android.app.Activity & android.support.wear.ambient.AmbientMode.AmbientCallbackProvider> android.support.wear.ambient.AmbientMode.AmbientController attachAmbientSupport(T);
+ field public static final java.lang.String EXTRA_BURN_IN_PROTECTION = "com.google.android.wearable.compat.extra.BURN_IN_PROTECTION";
+ field public static final java.lang.String EXTRA_LOWBIT_AMBIENT = "com.google.android.wearable.compat.extra.LOWBIT_AMBIENT";
+ field public static final java.lang.String FRAGMENT_TAG = "android.support.wearable.ambient.AmbientMode";
+ }
+
+ public static abstract class AmbientMode.AmbientCallback {
+ ctor public AmbientMode.AmbientCallback();
+ method public void onEnterAmbient(android.os.Bundle);
+ method public void onExitAmbient();
+ method public void onUpdateAmbient();
+ }
+
+ public static abstract interface AmbientMode.AmbientCallbackProvider {
+ method public abstract android.support.wear.ambient.AmbientMode.AmbientCallback getAmbientCallback();
+ }
+
+ public final class AmbientMode.AmbientController {
+ method public boolean isAmbient();
+ method public void setAutoResumeEnabled(boolean);
+ }
+
+}
+
package android.support.wear.utils {
public class MetadataConstants {
diff --git a/wear/build.gradle b/wear/build.gradle
index f471bc0..23a397a 100644
--- a/wear/build.gradle
+++ b/wear/build.gradle
@@ -3,6 +3,7 @@
dependencies {
api project(':support-annotations')
api project(':support-core-ui')
+ api project(':support-fragment')
api project(':percent')
api project(':recyclerview-v7')
@@ -10,6 +11,8 @@
androidTestImplementation libs.espresso_core, { exclude module: 'support-annotations' }
androidTestImplementation libs.mockito_core, { exclude group: 'net.bytebuddy' } // DexMaker has it"s own MockMaker
androidTestImplementation libs.dexmaker_mockito, { exclude group: 'net.bytebuddy' } // DexMaker has it"s own MockMaker
+
+ provided fileTree(dir: 'wear_stubs', include: ['com.google.android.wearable-stubs.jar'])
}
android {
@@ -20,6 +23,9 @@
sourceSets {
main.java.srcDir 'src'
main.res.srcDirs 'res', 'res-public'
+ main.resources {
+ includes = ["wear_stubs/LICENSE"]
+ }
}
buildTypes.all {
@@ -32,4 +38,9 @@
publish true
inceptionYear '2016'
description 'Android Wear Support UI'
+
+ license {
+ name 'The Apache Software License, Version 2.0'
+ url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+ }
}
diff --git a/wear/src/android/support/wear/ambient/AmbientDelegate.java b/wear/src/android/support/wear/ambient/AmbientDelegate.java
new file mode 100644
index 0000000..4901290
--- /dev/null
+++ b/wear/src/android/support/wear/ambient/AmbientDelegate.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2017 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.wear.ambient;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.Log;
+
+import com.google.android.wearable.compat.WearableActivityController;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+
+/**
+ * Provides compatibility for ambient mode.
+ */
+final class AmbientDelegate {
+
+ private static final String TAG = "AmbientDelegate";
+
+ private WearableActivityController mWearableController;
+
+ private static boolean sInitAutoResumeEnabledMethod;
+ private static boolean sHasAutoResumeEnabledMethod;
+ private final WearableControllerProvider mWearableControllerProvider;
+ private final AmbientCallback mCallback;
+ private final WeakReference<Activity> mActivity;
+
+ /**
+ * AmbientCallback must be implemented by all users of the delegate.
+ */
+ interface AmbientCallback {
+ /**
+ * Called when an activity is entering ambient mode. This event is sent while an activity is
+ * running (after onResume, before onPause). All drawing should complete by the conclusion
+ * of this method. Note that {@code invalidate()} calls will be executed before resuming
+ * lower-power mode.
+ * <p>
+ * <p><em>Derived classes must call through to the super class's implementation of this
+ * method. If they do not, an exception will be thrown.</em>
+ *
+ * @param ambientDetails bundle containing information about the display being used.
+ * It includes information about low-bit color and burn-in protection.
+ */
+ void onEnterAmbient(Bundle ambientDetails);
+
+ /**
+ * Called when the system is updating the display for ambient mode. Activities may use this
+ * opportunity to update or invalidate views.
+ */
+ void onUpdateAmbient();
+
+ /**
+ * Called when an activity should exit ambient mode. This event is sent while an activity is
+ * running (after onResume, before onPause).
+ * <p>
+ * <p><em>Derived classes must call through to the super class's implementation of this
+ * method. If they do not, an exception will be thrown.</em>
+ */
+ void onExitAmbient();
+ }
+
+ AmbientDelegate(@Nullable Activity activity,
+ @NonNull WearableControllerProvider wearableControllerProvider,
+ @NonNull AmbientCallback callback) {
+ mActivity = new WeakReference<>(activity);
+ mCallback = callback;
+ mWearableControllerProvider = wearableControllerProvider;
+ }
+
+ /**
+ * Receives and handles the onCreate call from the associated {@link AmbientMode}
+ */
+ void onCreate() {
+ Activity activity = mActivity.get();
+ if (activity != null) {
+ mWearableController =
+ mWearableControllerProvider.getWearableController(activity, mCallback);
+ }
+ if (mWearableController != null) {
+ mWearableController.onCreate();
+ }
+ }
+
+ /**
+ * Receives and handles the onResume call from the associated {@link AmbientMode}
+ */
+ void onResume() {
+ if (mWearableController != null) {
+ mWearableController.onResume();
+ }
+ }
+
+ /**
+ * Receives and handles the onPause call from the associated {@link AmbientMode}
+ */
+ void onPause() {
+ if (mWearableController != null) {
+ mWearableController.onPause();
+ }
+ }
+
+ /**
+ * Receives and handles the onStop call from the associated {@link AmbientMode}
+ */
+ void onStop() {
+ if (mWearableController != null) {
+ mWearableController.onStop();
+ }
+ }
+
+ /**
+ * Receives and handles the onDestroy call from the associated {@link AmbientMode}
+ */
+ void onDestroy() {
+ if (mWearableController != null) {
+ mWearableController.onDestroy();
+ }
+ }
+
+ /**
+ * Sets that this activity should remain displayed when the system enters ambient mode. The
+ * default is false. In this case, the activity is stopped when the system enters ambient mode.
+ */
+ void setAmbientEnabled() {
+ if (mWearableController != null) {
+ mWearableController.setAmbientEnabled();
+ }
+ }
+
+ /**
+ * Sets whether this activity's task should be moved to the front when the system exits ambient
+ * mode. If true, the activity's task may be moved to the front if it was the last activity to
+ * be running when ambient started, depending on how much time the system spent in ambient mode.
+ */
+ void setAutoResumeEnabled(boolean enabled) {
+ if (mWearableController != null) {
+ if (hasSetAutoResumeEnabledMethod()) {
+ mWearableController.setAutoResumeEnabled(enabled);
+ }
+ }
+ }
+
+ /**
+ * @return {@code true} if the activity is currently in ambient.
+ */
+ boolean isAmbient() {
+ if (mWearableController != null) {
+ return mWearableController.isAmbient();
+ }
+ return false;
+ }
+
+ /**
+ * Dump the current state of the wearableController responsible for implementing the Ambient
+ * mode.
+ */
+ void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+ if (mWearableController != null) {
+ mWearableController.dump(prefix, fd, writer, args);
+ }
+ }
+
+ private boolean hasSetAutoResumeEnabledMethod() {
+ if (!sInitAutoResumeEnabledMethod) {
+ sInitAutoResumeEnabledMethod = true;
+ try {
+ Method method =
+ WearableActivityController.class
+ .getDeclaredMethod("setAutoResumeEnabled", boolean.class);
+ // Proguard is sneaky -- it will actually rewrite strings it finds in addition to
+ // function names. Therefore add a "." prefix to the method name check to ensure the
+ // function was not renamed by proguard.
+ if (!(".setAutoResumeEnabled".equals("." + method.getName()))) {
+ throw new NoSuchMethodException();
+ }
+ sHasAutoResumeEnabledMethod = true;
+ } catch (NoSuchMethodException e) {
+ Log.w(
+ "WearableActivity",
+ "Could not find a required method for auto-resume "
+ + "support, likely due to proguard optimization. Please add "
+ + "com.google.android.wearable:wearable jar to the list of library "
+ + "jars for your project");
+ sHasAutoResumeEnabledMethod = false;
+ }
+ }
+ return sHasAutoResumeEnabledMethod;
+ }
+}
diff --git a/wear/src/android/support/wear/ambient/AmbientMode.java b/wear/src/android/support/wear/ambient/AmbientMode.java
new file mode 100644
index 0000000..7fbbbb3
--- /dev/null
+++ b/wear/src/android/support/wear/ambient/AmbientMode.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2017 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.wear.ambient;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.CallSuper;
+import android.support.annotation.VisibleForTesting;
+import android.util.Log;
+
+import com.google.android.wearable.compat.WearableActivityController;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Use this as a headless Fragment to add ambient support to an Activity on Wearable devices.
+ * <p>
+ * The application that uses this should add the {@link android.Manifest.permission#WAKE_LOCK}
+ * permission to its manifest.
+ * <p>
+ * The primary entry point for this code is the {@link #attachAmbientSupport(Activity)} method.
+ * It should be called with an {@link Activity} as an argument and that {@link Activity} will then
+ * be able to receive ambient lifecycle events through an {@link AmbientCallback}. The
+ * {@link Activity} will also receive a {@link AmbientController} object from the attachment which
+ * can be used to query the current status of the ambient mode, or toggle simple settings.
+ * An example of how to attach {@link AmbientMode} to your {@link Activity} and use
+ * the {@link AmbientController} can be found below:
+ * <p>
+ * <pre class="prettyprint">{@code
+ * AmbientMode.AmbientController controller = AmbientMode.attachAmbientSupport(this);
+ * controller.setAutoResumeEnabled(true);
+ * }</pre>
+ */
+public final class AmbientMode extends Fragment {
+
+ /**
+ * Property in bundle passed to {@code AmbientCallback#onEnterAmbient(Bundle)} to indicate
+ * whether burn-in protection is required. When this property is set to true, views must be
+ * shifted around periodically in ambient mode. To ensure that content isn't shifted off
+ * the screen, avoid placing content within 10 pixels of the edge of the screen. Activities
+ * should also avoid solid white areas to prevent pixel burn-in. Both of these requirements
+ * only apply in ambient mode, and only when this property is set to true.
+ */
+ public static final String EXTRA_BURN_IN_PROTECTION =
+ WearableActivityController.EXTRA_BURN_IN_PROTECTION;
+
+ /**
+ * Property in bundle passed to {@code AmbientCallback#onEnterAmbient(Bundle)} to indicate
+ * whether the device has low-bit ambient mode. When this property is set to true, the screen
+ * supports fewer bits for each color in ambient mode. In this case, activities should disable
+ * anti-aliasing in ambient mode.
+ */
+ public static final String EXTRA_LOWBIT_AMBIENT =
+ WearableActivityController.EXTRA_LOWBIT_AMBIENT;
+
+ /**
+ * Fragment tag used by default when adding {@link AmbientMode} to add ambient support to an
+ * {@link Activity}.
+ */
+ public static final String FRAGMENT_TAG = "android.support.wearable.ambient.AmbientMode";
+
+ /**
+ * Interface for any {@link Activity} that wishes to implement Ambient Mode. Use the
+ * {@link #getAmbientCallback()} method to return and {@link AmbientCallback} which can be used
+ * to bind the {@link AmbientMode} to the instantiation of this interface.
+ * <p>
+ * <pre class="prettyprint">{@code
+ * return new AmbientMode.AmbientCallback() {
+ * public void onEnterAmbient(Bundle ambientDetails) {...}
+ * public void onExitAmbient(Bundle ambientDetails) {...}
+ * }
+ * }</pre>
+ */
+ public interface AmbientCallbackProvider {
+ /**
+ * @return the {@link AmbientCallback} to be used by this class to communicate with the
+ * entity interested in ambient events.
+ */
+ AmbientCallback getAmbientCallback();
+ }
+
+ /**
+ * Callback to receive ambient mode state changes. It must be used by all users of AmbientMode.
+ */
+ public abstract static class AmbientCallback {
+ /**
+ * Called when an activity is entering ambient mode. This event is sent while an activity is
+ * running (after onResume, before onPause). All drawing should complete by the conclusion
+ * of this method. Note that {@code invalidate()} calls will be executed before resuming
+ * lower-power mode.
+ * <p>
+ * <p><em>Derived classes must call through to the super class's implementation of this
+ * method. If they do not, an exception will be thrown.</em>
+ *
+ * @param ambientDetails bundle containing information about the display being used.
+ * It includes information about low-bit color and burn-in protection.
+ */
+ public void onEnterAmbient(Bundle ambientDetails) {}
+
+ /**
+ * Called when the system is updating the display for ambient mode. Activities may use this
+ * opportunity to update or invalidate views.
+ */
+ public void onUpdateAmbient() {};
+
+ /**
+ * Called when an activity should exit ambient mode. This event is sent while an activity is
+ * running (after onResume, before onPause).
+ * <p>
+ * <p><em>Derived classes must call through to the super class's implementation of this
+ * method. If they do not, an exception will be thrown.</em>
+ */
+ public void onExitAmbient() {};
+ }
+
+ private final AmbientDelegate.AmbientCallback mCallback =
+ new AmbientDelegate.AmbientCallback() {
+ @Override
+ public void onEnterAmbient(Bundle ambientDetails) {
+ mSuppliedCallback.onEnterAmbient(ambientDetails);
+ }
+
+ @Override
+ public void onExitAmbient() {
+ mSuppliedCallback.onExitAmbient();
+ }
+
+ @Override
+ public void onUpdateAmbient() {
+ mSuppliedCallback.onUpdateAmbient();
+ }
+ };
+ private AmbientDelegate mDelegate;
+ private AmbientCallback mSuppliedCallback;
+ private AmbientController mController;
+
+ /**
+ * Constructor
+ */
+ public AmbientMode() {
+ mController = new AmbientController();
+ }
+
+ @Override
+ @CallSuper
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ mDelegate = new AmbientDelegate(getActivity(), new WearableControllerProvider(), mCallback);
+
+ if (context instanceof AmbientCallbackProvider) {
+ mSuppliedCallback = ((AmbientCallbackProvider) context).getAmbientCallback();
+ } else {
+ throw new IllegalArgumentException(
+ "fragment should attach to an activity that implements AmbientCallback");
+ }
+ }
+
+ @Override
+ @CallSuper
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mDelegate.onCreate();
+ mDelegate.setAmbientEnabled();
+ }
+
+ @Override
+ @CallSuper
+ public void onResume() {
+ super.onResume();
+ mDelegate.onResume();
+ }
+
+ @Override
+ @CallSuper
+ public void onPause() {
+ mDelegate.onPause();
+ super.onPause();
+ }
+
+ @Override
+ @CallSuper
+ public void onStop() {
+ mDelegate.onStop();
+ super.onStop();
+ }
+
+ @Override
+ @CallSuper
+ public void onDestroy() {
+ mDelegate.onDestroy();
+ super.onDestroy();
+ }
+
+ @Override
+ @CallSuper
+ public void onDetach() {
+ mDelegate = null;
+ super.onDetach();
+ }
+
+ /**
+ * Attach ambient support to the given activity.
+ *
+ * @param activity the activity to attach ambient support to. This activity has to also
+ * implement {@link AmbientCallbackProvider}
+ * @return the associated {@link AmbientController} which can be used to query the state of
+ * ambient mode and toggle simple settings related to it.
+ */
+ public static <T extends Activity & AmbientCallbackProvider> AmbientController
+ attachAmbientSupport(T activity) {
+ FragmentManager fragmentManager = activity.getFragmentManager();
+ AmbientMode ambientFragment = (AmbientMode) fragmentManager.findFragmentByTag(FRAGMENT_TAG);
+ if (ambientFragment == null) {
+ AmbientMode fragment = new AmbientMode();
+ fragmentManager
+ .beginTransaction()
+ .add(fragment, FRAGMENT_TAG)
+ .commit();
+ ambientFragment = fragment;
+ }
+ return ambientFragment.mController;
+ }
+
+ @Override
+ public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+ if (mDelegate != null) {
+ mDelegate.dump(prefix, fd, writer, args);
+ }
+ }
+
+ @VisibleForTesting
+ void setAmbientDelegate(AmbientDelegate delegate) {
+ mDelegate = delegate;
+ }
+
+ /**
+ * A class for interacting with the ambient mode on a wearable device. This class can be used to
+ * query the current state of ambient mode and to enable or disable certain settings.
+ * An instance of this class is returned to the user when they attach their {@link Activity}
+ * to {@link AmbientMode}.
+ */
+ public final class AmbientController {
+ private static final String TAG = "AmbientController";
+
+ // Do not initialize outside of this class.
+ AmbientController() {}
+
+ /**
+ * Sets whether this activity's task should be moved to the front when the system exits
+ * ambient mode. If true, the activity's task may be moved to the front if it was the last
+ * activity to be running when ambient started, depending on how much time the system spent
+ * in ambient mode.
+ */
+ public void setAutoResumeEnabled(boolean enabled) {
+ if (mDelegate != null) {
+ mDelegate.setAutoResumeEnabled(enabled);
+ } else {
+ Log.w(TAG, "The fragment is not yet fully initialized, this call is a no-op");
+ }
+ }
+
+ /**
+ * @return {@code true} if the activity is currently in ambient.
+ */
+ public boolean isAmbient() {
+ return mDelegate == null ? false : mDelegate.isAmbient();
+ }
+ }
+}
diff --git a/wear/src/android/support/wear/ambient/SharedLibraryVersion.java b/wear/src/android/support/wear/ambient/SharedLibraryVersion.java
new file mode 100644
index 0000000..cd90a3b
--- /dev/null
+++ b/wear/src/android/support/wear/ambient/SharedLibraryVersion.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2017 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.wear.ambient;
+
+import android.os.Build;
+import android.support.annotation.RestrictTo;
+import android.support.annotation.VisibleForTesting;
+
+import com.google.android.wearable.WearableSharedLib;
+
+/**
+ * Internal class which can be used to determine the version of the wearable shared library that is
+ * available on the current device.
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+final class SharedLibraryVersion {
+
+ private SharedLibraryVersion() {
+ }
+
+ /**
+ * Returns the version of the wearable shared library available on the current device.
+ * <p>
+ * <p>Version 1 was introduced on 2016-09-26, so any previous shared library will return 0. In
+ * those cases, it may be necessary to check {@code Build.VERSION.SDK_INT}.
+ *
+ * @throws IllegalStateException if the Wearable Shared Library is not present, which means that
+ * the {@code <uses-library>} tag is missing.
+ */
+ public static int version() {
+ verifySharedLibraryPresent();
+ return VersionHolder.VERSION;
+ }
+
+ /**
+ * Throws {@link IllegalStateException} if the Wearable Shared Library is not present and API
+ * level is at least LMP MR1.
+ * <p>
+ * <p>This validates that the developer hasn't forgotten to include a {@code <uses-library>} tag
+ * in their manifest. The method should be used in combination with API level checks for
+ * features added before {@link #version() version} 1.
+ */
+ public static void verifySharedLibraryPresent() {
+ if (!PresenceHolder.PRESENT) {
+ throw new IllegalStateException("Could not find wearable shared library classes. "
+ + "Please add <uses-library android:name=\"com.google.android.wearable\" "
+ + "android:required=\"false\" /> to the application manifest");
+ }
+ }
+
+ // Lazy initialization holder class (see Effective Java item 71)
+ @VisibleForTesting
+ static final class VersionHolder {
+ static final int VERSION = getSharedLibVersion(Build.VERSION.SDK_INT);
+
+ @VisibleForTesting
+ static int getSharedLibVersion(int sdkInt) {
+ if (sdkInt < Build.VERSION_CODES.N_MR1) {
+ // WearableSharedLib was introduced in N MR1 (Wear FDP 4)
+ return 0;
+ }
+ return WearableSharedLib.version();
+ }
+ }
+
+ // Lazy initialization holder class (see Effective Java item 71)
+ @VisibleForTesting
+ static final class PresenceHolder {
+ static final boolean PRESENT = isSharedLibPresent(Build.VERSION.SDK_INT);
+
+ @VisibleForTesting
+ static boolean isSharedLibPresent(int sdkInt) {
+ try {
+ // A class which has been available on the shared library from the first version.
+ Class.forName("com.google.android.wearable.compat.WearableActivityController");
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ return true;
+ }
+ }
+}
diff --git a/wear/src/android/support/wear/ambient/WearableControllerProvider.java b/wear/src/android/support/wear/ambient/WearableControllerProvider.java
new file mode 100644
index 0000000..1682dc0
--- /dev/null
+++ b/wear/src/android/support/wear/ambient/WearableControllerProvider.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2017 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.wear.ambient;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.annotation.RestrictTo;
+
+import com.google.android.wearable.compat.WearableActivityController;
+
+import java.lang.reflect.Method;
+
+/**
+ * Provides a {@link WearableActivityController} for ambient mode control.
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public class WearableControllerProvider {
+
+ private static final String TAG = "WearableControllerProvider";
+
+ private static volatile boolean sAmbientCallbacksVerifiedPresent;
+
+ /**
+ * Retrieves a {@link WearableActivityController} to use for ambient mode.
+ *
+ * @param activity The {@link Activity} to be associated with the Controller.
+ * @param callback The {@link AmbientDelegate.AmbientCallback} for the Controller.
+ * @return the platform-appropriate version of the {@link WearableActivityController}.
+ */
+ public WearableActivityController getWearableController(Activity activity,
+ final AmbientDelegate.AmbientCallback callback) {
+ SharedLibraryVersion.verifySharedLibraryPresent();
+
+ // The AmbientCallback is an abstract class instead of an interface.
+ WearableActivityController.AmbientCallback callbackBridge =
+ new WearableActivityController.AmbientCallback() {
+ @Override
+ public void onEnterAmbient(Bundle ambientDetails) {
+ callback.onEnterAmbient(ambientDetails);
+ }
+
+ @Override
+ public void onUpdateAmbient() {
+ callback.onUpdateAmbient();
+ }
+
+ @Override
+ public void onExitAmbient() {
+ callback.onExitAmbient();
+ }
+ };
+
+ verifyAmbientCallbacksPresent();
+
+ return new WearableActivityController(TAG, activity, callbackBridge);
+ }
+
+ private static void verifyAmbientCallbacksPresent() {
+ if (sAmbientCallbacksVerifiedPresent) {
+ return;
+ }
+ try {
+ Method method =
+ WearableActivityController.AmbientCallback.class.getDeclaredMethod(
+ "onEnterAmbient", Bundle.class);
+ // Proguard is sneaky -- it will actually rewrite strings it finds in addition to
+ // function names. Therefore add a "." prefix to the method name check to ensure the
+ // function was not renamed by proguard.
+ if (!(".onEnterAmbient".equals("." + method.getName()))) {
+ throw new NoSuchMethodException();
+ }
+ } catch (NoSuchMethodException e) {
+ throw new IllegalStateException(
+ "Could not find a required method for "
+ + "ambient support, likely due to proguard optimization. Please add "
+ + "com.google.android.wearable:wearable jar to the list of library jars"
+ + " for your project");
+ }
+ sAmbientCallbacksVerifiedPresent = true;
+ }
+}
diff --git a/wear/tests/AndroidManifest.xml b/wear/tests/AndroidManifest.xml
index 834e067..ce78477 100644
--- a/wear/tests/AndroidManifest.xml
+++ b/wear/tests/AndroidManifest.xml
@@ -48,6 +48,13 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
+
+ <activity android:name="android.support.wear.ambient.AmbientModeTestActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
<!-- Test app is iOS compatible. -->
<meta-data
android:name="com.google.android.wearable.standalone"
diff --git a/wear/tests/src/android/support/wear/ambient/AmbientDelegateTest.java b/wear/tests/src/android/support/wear/ambient/AmbientDelegateTest.java
new file mode 100644
index 0000000..32f9bb6
--- /dev/null
+++ b/wear/tests/src/android/support/wear/ambient/AmbientDelegateTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2017 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.wear.ambient;
+
+import static junit.framework.Assert.assertFalse;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v4.app.FragmentActivity;
+
+import com.google.android.wearable.compat.WearableActivityController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+/**
+ * Tests for {@link AmbientDelegate}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AmbientDelegateTest {
+
+ @Mock
+ AmbientDelegate.AmbientCallback mMockAmbientCallback;
+ @Mock
+ WearableControllerProvider mMockWearableControllerProvider;
+ @Mock
+ WearableActivityController mMockWearableController;
+ @Mock
+ FragmentActivity mMockActivity;
+
+ private AmbientDelegate mAmbientDelegateUnderTest;
+
+ @Before
+ public void setUp() {
+ mMockAmbientCallback = mock(AmbientDelegate.AmbientCallback.class);
+ mMockWearableControllerProvider = mock(WearableControllerProvider.class);
+ mMockWearableController = mock(WearableActivityController.class);
+ mMockActivity = mock(FragmentActivity.class);
+ when(mMockWearableControllerProvider
+ .getWearableController(mMockActivity, mMockAmbientCallback))
+ .thenReturn(mMockWearableController);
+ }
+
+ @Test
+ public void testNullActivity() {
+ mAmbientDelegateUnderTest = new AmbientDelegate(null,
+ mMockWearableControllerProvider, mMockAmbientCallback);
+ verifyZeroInteractions(mMockWearableControllerProvider);
+
+ assertFalse(mAmbientDelegateUnderTest.isAmbient());
+
+ }
+
+ @Test
+ public void testActivityPresent() {
+ mAmbientDelegateUnderTest = new AmbientDelegate(mMockActivity,
+ mMockWearableControllerProvider, mMockAmbientCallback);
+
+ mAmbientDelegateUnderTest.onCreate();
+ verify(mMockWearableController).onCreate();
+
+ mAmbientDelegateUnderTest.onResume();
+ verify(mMockWearableController).onResume();
+
+ mAmbientDelegateUnderTest.onPause();
+ verify(mMockWearableController).onPause();
+
+ mAmbientDelegateUnderTest.onStop();
+ verify(mMockWearableController).onStop();
+
+ mAmbientDelegateUnderTest.onDestroy();
+ verify(mMockWearableController).onDestroy();
+ }
+}
diff --git a/wear/tests/src/android/support/wear/ambient/AmbientModeTest.java b/wear/tests/src/android/support/wear/ambient/AmbientModeTest.java
new file mode 100644
index 0000000..155622d
--- /dev/null
+++ b/wear/tests/src/android/support/wear/ambient/AmbientModeTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2017 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.wear.ambient;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.wear.widget.util.WakeLockRule;
+
+import com.google.android.wearable.compat.WearableActivityController;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class AmbientModeTest {
+ @Rule
+ public final WakeLockRule mWakeLock = new WakeLockRule();
+
+ @Rule
+ public final ActivityTestRule<AmbientModeTestActivity> mActivityRule = new ActivityTestRule<>(
+ AmbientModeTestActivity.class);
+
+ @Test
+ public void testEnterAmbientCallback() throws Throwable {
+ AmbientModeTestActivity activity = mActivityRule.getActivity();
+
+ WearableActivityController.getLastInstance().enterAmbient();
+ assertTrue(activity.mEnterAmbientCalled);
+ assertFalse(activity.mUpdateAmbientCalled);
+ assertFalse(activity.mExitAmbientCalled);
+ }
+
+ @Test
+ public void testUpdateAmbientCallback() throws Throwable {
+ AmbientModeTestActivity activity = mActivityRule.getActivity();
+
+ WearableActivityController.getLastInstance().updateAmbient();
+ assertFalse(activity.mEnterAmbientCalled);
+ assertTrue(activity.mUpdateAmbientCalled);
+ assertFalse(activity.mExitAmbientCalled);
+ }
+
+ @Test
+ public void testExitAmbientCallback() throws Throwable {
+ AmbientModeTestActivity activity = mActivityRule.getActivity();
+
+ WearableActivityController.getLastInstance().exitAmbient();
+ assertFalse(activity.mEnterAmbientCalled);
+ assertFalse(activity.mUpdateAmbientCalled);
+ assertTrue(activity.mExitAmbientCalled);
+ }
+
+ @Test
+ public void testIsAmbientEnabled() {
+ assertTrue(WearableActivityController.getLastInstance().isAmbientEnabled());
+ }
+
+ @Test
+ public void testControllerSetAutoResumeEnabled() {
+ AmbientModeTestActivity activity = mActivityRule.getActivity();
+
+ activity.getAmbientController().setAutoResumeEnabled(true);
+ assertTrue(WearableActivityController.getLastInstance().isAutoResumeEnabled());
+
+ activity.getAmbientController().setAutoResumeEnabled(false);
+ assertFalse(WearableActivityController.getLastInstance().isAutoResumeEnabled());
+ }
+
+ @Test
+ public void testCallsControllerIsAmbient() {
+ AmbientModeTestActivity activity = mActivityRule.getActivity();
+
+ WearableActivityController.getLastInstance().setAmbient(true);
+ assertTrue(activity.getAmbientController().isAmbient());
+
+ WearableActivityController.getLastInstance().setAmbient(false);
+ assertFalse(activity.getAmbientController().isAmbient());
+ }
+}
diff --git a/wear/tests/src/android/support/wear/ambient/AmbientModeTestActivity.java b/wear/tests/src/android/support/wear/ambient/AmbientModeTestActivity.java
new file mode 100644
index 0000000..26155d8
--- /dev/null
+++ b/wear/tests/src/android/support/wear/ambient/AmbientModeTestActivity.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 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.wear.ambient;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+public class AmbientModeTestActivity extends FragmentActivity
+ implements AmbientMode.AmbientCallbackProvider {
+ AmbientMode.AmbientController mAmbientController;
+
+ boolean mEnterAmbientCalled;
+ boolean mUpdateAmbientCalled;
+ boolean mExitAmbientCalled;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mAmbientController = AmbientMode.attachAmbientSupport(this);
+ }
+
+ @Override
+ public AmbientMode.AmbientCallback getAmbientCallback() {
+ return new MyAmbientCallback();
+ }
+
+ private class MyAmbientCallback extends AmbientMode.AmbientCallback {
+
+ @Override
+ public void onEnterAmbient(Bundle ambientDetails) {
+ mEnterAmbientCalled = true;
+ }
+
+ @Override
+ public void onUpdateAmbient() {
+ mUpdateAmbientCalled = true;
+ }
+
+ @Override
+ public void onExitAmbient() {
+ mExitAmbientCalled = true;
+ }
+ }
+
+ public AmbientMode.AmbientController getAmbientController() {
+ return mAmbientController;
+ }
+
+}
diff --git a/wear/tests/src/com/google/android/wearable/compat/WearableActivityController.java b/wear/tests/src/com/google/android/wearable/compat/WearableActivityController.java
new file mode 100644
index 0000000..7823f23
--- /dev/null
+++ b/wear/tests/src/com/google/android/wearable/compat/WearableActivityController.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.wearable.compat;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Mock version of {@link WearableActivityController}. During instrumentation testing, the tests
+ * would end up using this instead of the version implemented on device.
+ */
+public class WearableActivityController {
+
+ private static WearableActivityController sLastInstance;
+
+ public static WearableActivityController getLastInstance() {
+ return sLastInstance;
+ }
+
+ private AmbientCallback mCallback;
+ private boolean mAmbientEnabled = false;
+ private boolean mAutoResumeEnabled = false;
+ private boolean mAmbient = false;
+
+ public WearableActivityController(String tag, Activity activity, AmbientCallback callback) {
+ sLastInstance = this;
+ mCallback = callback;
+ }
+
+ // Methods required by the stub but not currently used in tests.
+ public void onCreate() {}
+ public void onResume() {}
+ public void onPause() {}
+ public void onStop() {}
+ public void onDestroy() {}
+
+ public void enterAmbient() {
+ mCallback.onEnterAmbient(null);
+ }
+
+ public void exitAmbient() {
+ mCallback.onExitAmbient();
+ }
+
+ public void updateAmbient() {
+ mCallback.onUpdateAmbient();
+ }
+
+ public void setAmbientEnabled() {
+ mAmbientEnabled = true;
+ }
+
+ public boolean isAmbientEnabled() {
+ return mAmbientEnabled;
+ }
+
+ public void setAutoResumeEnabled(boolean enabled) {
+ mAutoResumeEnabled = enabled;
+ }
+
+ public boolean isAutoResumeEnabled() {
+ return mAutoResumeEnabled;
+ }
+
+ public final boolean isAmbient() {
+ return mAmbient;
+ }
+
+ public void setAmbient(boolean ambient) {
+ mAmbient = ambient;
+ }
+
+ /** Stub version of {@link WearableActivityController.AmbientCallback}. */
+ public static class AmbientCallback {
+ public void onEnterAmbient(Bundle ambientDetails) {}
+
+ public void onExitAmbient() {}
+
+ public void onUpdateAmbient() {}
+ }
+}
diff --git a/wear/wear_stubs/LICENSE b/wear/wear_stubs/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/wear/wear_stubs/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/wear/wear_stubs/README.android b/wear/wear_stubs/README.android
new file mode 100644
index 0000000..5fdff39
--- /dev/null
+++ b/wear/wear_stubs/README.android
@@ -0,0 +1,10 @@
+# Wearable support system stubs from http://ab/4131273
+This library contains system stubs generated for the
+com.google.android.wearable.jar shared library. Classes in the 1st/3rd party
+accessible wearable support library are able to access these apis.
+
+See `vendor/google_clockwork/libs/wearable` in Android Git.
+
+Imports to this directory must always be done from the Android Build server.
+To test with local changes made in Android Git see the instructions at
+http://go/clockwork-dev/device-builds.
diff --git a/wear/wear_stubs/api/1.txt b/wear/wear_stubs/api/1.txt
new file mode 100644
index 0000000..af53c8e
--- /dev/null
+++ b/wear/wear_stubs/api/1.txt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.wearable {
+
+ public final class WearableSharedLib {
+ method public static int version();
+ }
+
+}
+
+package com.google.android.wearable.compat {
+
+ public class WearableActivityController {
+ ctor public WearableActivityController(java.lang.String, android.app.Activity, com.google.android.wearable.compat.WearableActivityController.AmbientCallback);
+ method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public final boolean isAmbient();
+ method public void onCreate();
+ method public void onDestroy();
+ method public void onPause();
+ method public void onResume();
+ method public void onStop();
+ method public final void setAmbientEnabled();
+ method public final void setAutoResumeEnabled(boolean);
+ field public static final java.lang.String EXTRA_BURN_IN_PROTECTION = "com.google.android.wearable.compat.extra.BURN_IN_PROTECTION";
+ field public static final java.lang.String EXTRA_LOWBIT_AMBIENT = "com.google.android.wearable.compat.extra.LOWBIT_AMBIENT";
+ }
+
+ public static abstract class WearableActivityController.AmbientCallback {
+ ctor public WearableActivityController.AmbientCallback();
+ method public void onEnterAmbient(android.os.Bundle);
+ method public void onExitAmbient();
+ method public void onUpdateAmbient();
+ }
+
+}
+
+package com.google.android.wearable.input {
+
+ public class RotaryEncoderHelper {
+ method public static float getRotaryAxisValue(android.view.MotionEvent);
+ method public static float getScaledScrollFactor(android.content.Context);
+ method public static boolean isFromRotaryEncoder(android.view.MotionEvent);
+ }
+
+ public final class WearableInputDevice {
+ method public static final int[] getAvailableButtonKeyCodes(android.content.Context);
+ method public static final android.os.Bundle getButtonInfo(android.content.Context, int);
+ field public static final java.lang.String X_KEY = "x_key";
+ field public static final java.lang.String Y_KEY = "y_key";
+ }
+
+}
+
diff --git a/wear/wear_stubs/api/2.txt b/wear/wear_stubs/api/2.txt
new file mode 100644
index 0000000..2850f24
--- /dev/null
+++ b/wear/wear_stubs/api/2.txt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.wearable {
+
+ public final class WearableSharedLib {
+ method public static int version();
+ }
+
+}
+
+package com.google.android.wearable.compat {
+
+ public class WearableActivityController {
+ ctor public WearableActivityController(java.lang.String, android.app.Activity, com.google.android.wearable.compat.WearableActivityController.AmbientCallback);
+ method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public final boolean isAmbient();
+ method public void onCreate();
+ method public void onDestroy();
+ method public void onPause();
+ method public void onResume();
+ method public void onStop();
+ method public final void setAmbientEnabled();
+ method public final void setAutoResumeEnabled(boolean);
+ field public static final java.lang.String EXTRA_BURN_IN_PROTECTION = "com.google.android.wearable.compat.extra.BURN_IN_PROTECTION";
+ field public static final java.lang.String EXTRA_LOWBIT_AMBIENT = "com.google.android.wearable.compat.extra.LOWBIT_AMBIENT";
+ }
+
+ public static abstract class WearableActivityController.AmbientCallback {
+ ctor public WearableActivityController.AmbientCallback();
+ method public void onEnterAmbient(android.os.Bundle);
+ method public void onExitAmbient();
+ method public void onUpdateAmbient();
+ }
+
+}
+
+package com.google.android.wearable.display {
+
+ public final class WearableDisplayHelper {
+ method public static final android.graphics.RectF getObstruction();
+ }
+
+}
+
+package com.google.android.wearable.input {
+
+ public class RotaryEncoderHelper {
+ method public static float getRotaryAxisValue(android.view.MotionEvent);
+ method public static float getScaledScrollFactor(android.content.Context);
+ method public static boolean isFromRotaryEncoder(android.view.MotionEvent);
+ }
+
+ public final class WearableInputDevice {
+ method public static final int[] getAvailableButtonKeyCodes(android.content.Context);
+ method public static final android.os.Bundle getButtonInfo(android.content.Context, int);
+ field public static final java.lang.String X_KEY = "x_key";
+ field public static final java.lang.String Y_KEY = "y_key";
+ }
+
+}
+
diff --git a/wear/wear_stubs/api/current.txt b/wear/wear_stubs/api/current.txt
new file mode 100644
index 0000000..2850f24
--- /dev/null
+++ b/wear/wear_stubs/api/current.txt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.wearable {
+
+ public final class WearableSharedLib {
+ method public static int version();
+ }
+
+}
+
+package com.google.android.wearable.compat {
+
+ public class WearableActivityController {
+ ctor public WearableActivityController(java.lang.String, android.app.Activity, com.google.android.wearable.compat.WearableActivityController.AmbientCallback);
+ method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public final boolean isAmbient();
+ method public void onCreate();
+ method public void onDestroy();
+ method public void onPause();
+ method public void onResume();
+ method public void onStop();
+ method public final void setAmbientEnabled();
+ method public final void setAutoResumeEnabled(boolean);
+ field public static final java.lang.String EXTRA_BURN_IN_PROTECTION = "com.google.android.wearable.compat.extra.BURN_IN_PROTECTION";
+ field public static final java.lang.String EXTRA_LOWBIT_AMBIENT = "com.google.android.wearable.compat.extra.LOWBIT_AMBIENT";
+ }
+
+ public static abstract class WearableActivityController.AmbientCallback {
+ ctor public WearableActivityController.AmbientCallback();
+ method public void onEnterAmbient(android.os.Bundle);
+ method public void onExitAmbient();
+ method public void onUpdateAmbient();
+ }
+
+}
+
+package com.google.android.wearable.display {
+
+ public final class WearableDisplayHelper {
+ method public static final android.graphics.RectF getObstruction();
+ }
+
+}
+
+package com.google.android.wearable.input {
+
+ public class RotaryEncoderHelper {
+ method public static float getRotaryAxisValue(android.view.MotionEvent);
+ method public static float getScaledScrollFactor(android.content.Context);
+ method public static boolean isFromRotaryEncoder(android.view.MotionEvent);
+ }
+
+ public final class WearableInputDevice {
+ method public static final int[] getAvailableButtonKeyCodes(android.content.Context);
+ method public static final android.os.Bundle getButtonInfo(android.content.Context, int);
+ field public static final java.lang.String X_KEY = "x_key";
+ field public static final java.lang.String Y_KEY = "y_key";
+ }
+
+}
+
diff --git a/wear/wear_stubs/com.google.android.wearable-stubs.jar b/wear/wear_stubs/com.google.android.wearable-stubs.jar
new file mode 100644
index 0000000..7465f7c
--- /dev/null
+++ b/wear/wear_stubs/com.google.android.wearable-stubs.jar
Binary files differ