Merge "Cleanup AccessibilityEventCompat and AccessibilityRecordCompat after minSdk 14 bump."
diff --git a/annotations/src/android/support/annotation/GuardedBy.java b/annotations/src/android/support/annotation/GuardedBy.java
new file mode 100644
index 0000000..ee7d77c
--- /dev/null
+++ b/annotations/src/android/support/annotation/GuardedBy.java
@@ -0,0 +1,47 @@
+/*
+ * 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 java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Denotes that the annotated method or field can only be accessed when holding the referenced lock.
+ * <p>
+ * Example:
+ * <pre>
+ * final Object objectLock = new Object();
+ *
+ * {@literal @}GuardedBy("objectLock")
+ * volatile Object object;
+ *
+ * Object getObject() {
+ * synchronized (objectLock) {
+ * if (object == null) {
+ * object = new Object();
+ * }
+ * }
+ * return object;
+ * }</pre>
+ */
+@Target({ ElementType.FIELD, ElementType.METHOD })
+@Retention(RetentionPolicy.CLASS)
+public @interface GuardedBy {
+ String value();
+}
diff --git a/api/25.3.0.txt b/api/25.3.0.txt
index ac4bf65..a1ff8b4 100644
--- a/api/25.3.0.txt
+++ b/api/25.3.0.txt
@@ -1,3 +1,75 @@
+package android.support.animation {
+
+ public abstract class DynamicAnimation<T extends android.support.animation.DynamicAnimation<T>> {
+ method public T addEndListener(android.support.animation.DynamicAnimation.OnAnimationEndListener);
+ method public T addUpdateListener(android.support.animation.DynamicAnimation.OnAnimationUpdateListener);
+ method public void cancel();
+ method public boolean isRunning();
+ method public void removeEndListener(android.support.animation.DynamicAnimation.OnAnimationEndListener);
+ method public void removeUpdateListener(android.support.animation.DynamicAnimation.OnAnimationUpdateListener);
+ method public T setMaxValue(float);
+ method public T setMinValue(float);
+ method public T setStartValue(float);
+ method public T setStartVelocity(float);
+ method public void start();
+ field public static final android.support.animation.DynamicAnimation.ViewProperty ALPHA;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty ROTATION;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty ROTATION_X;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty ROTATION_Y;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty SCALE_X;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty SCALE_Y;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty SCROLL_X;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty SCROLL_Y;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty TRANSLATION_X;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty TRANSLATION_Y;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty TRANSLATION_Z;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty X;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty Y;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty Z;
+ }
+
+ public static abstract interface DynamicAnimation.OnAnimationEndListener {
+ method public abstract void onAnimationEnd(android.support.animation.DynamicAnimation, boolean, float, float);
+ }
+
+ public static abstract interface DynamicAnimation.OnAnimationUpdateListener {
+ method public abstract void onAnimationUpdate(android.support.animation.DynamicAnimation, float, float);
+ }
+
+ public static abstract class DynamicAnimation.ViewProperty {
+ }
+
+ public final class SpringAnimation extends android.support.animation.DynamicAnimation {
+ ctor public SpringAnimation(android.view.View, android.support.animation.DynamicAnimation.ViewProperty);
+ ctor public SpringAnimation(android.view.View, android.support.animation.DynamicAnimation.ViewProperty, float);
+ method public void animateToFinalPosition(float);
+ method public boolean canSkipToEnd();
+ method public android.support.animation.SpringForce getSpring();
+ method public android.support.animation.SpringAnimation setSpring(android.support.animation.SpringForce);
+ method public void skipToEnd();
+ }
+
+ public final class SpringForce {
+ ctor public SpringForce();
+ ctor public SpringForce(float);
+ method public float getDampingRatio();
+ method public float getFinalPosition();
+ method public float getStiffness();
+ method public android.support.animation.SpringForce setDampingRatio(float);
+ method public android.support.animation.SpringForce setFinalPosition(float);
+ method public android.support.animation.SpringForce setStiffness(float);
+ field public static final float DAMPING_RATIO_HIGH_BOUNCY = 0.2f;
+ field public static final float DAMPING_RATIO_LOW_BOUNCY = 0.75f;
+ field public static final float DAMPING_RATIO_MEDIUM_BOUNCY = 0.5f;
+ field public static final float DAMPING_RATIO_NO_BOUNCY = 1.0f;
+ field public static final float STIFFNESS_HIGH = 10000.0f;
+ field public static final float STIFFNESS_LOW = 200.0f;
+ field public static final float STIFFNESS_MEDIUM = 1500.0f;
+ field public static final float STIFFNESS_VERY_LOW = 50.0f;
+ }
+
+}
+
package android.support.app.recommendation {
public final class ContentRecommendation {
@@ -870,16 +942,34 @@
package android.support.graphics.drawable {
- public class AnimatedVectorDrawableCompat extends android.support.graphics.drawable.VectorDrawableCommon {
+ public abstract interface Animatable2Compat {
+ method public abstract void clearAnimationCallbacks();
+ method public abstract void registerAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+ method public abstract boolean unregisterAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+ }
+
+ public static abstract class Animatable2Compat.AnimationCallback {
+ ctor public Animatable2Compat.AnimationCallback();
+ method public void onAnimationEnd(android.graphics.drawable.Drawable);
+ method public void onAnimationStart(android.graphics.drawable.Drawable);
+ }
+
+ public class AnimatedVectorDrawableCompat extends android.support.graphics.drawable.VectorDrawableCommon implements android.support.graphics.drawable.Animatable2Compat {
+ method public void clearAnimationCallbacks();
+ method public static void clearAnimationCallbacks(android.graphics.drawable.Drawable);
method public static android.support.graphics.drawable.AnimatedVectorDrawableCompat create(android.content.Context, int);
method public static android.support.graphics.drawable.AnimatedVectorDrawableCompat createFromXmlInner(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public void draw(android.graphics.Canvas);
method public int getOpacity();
method public boolean isRunning();
+ method public void registerAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+ method public static void registerAnimationCallback(android.graphics.drawable.Drawable, android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
method public void setAlpha(int);
method public void setColorFilter(android.graphics.ColorFilter);
method public void start();
method public void stop();
+ method public boolean unregisterAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+ method public static boolean unregisterAnimationCallback(android.graphics.drawable.Drawable, android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
}
abstract class VectorDrawableCommon extends android.graphics.drawable.Drawable {
@@ -2414,10 +2504,7 @@
public class BoundsRule {
ctor public BoundsRule();
ctor public BoundsRule(android.support.v17.leanback.graphics.BoundsRule);
- method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule absoluteValue(int);
method public void calculateBounds(android.graphics.Rect, android.graphics.Rect);
- method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParent(float);
- method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParentWithOffset(float, int);
field public android.support.v17.leanback.graphics.BoundsRule.ValueRule bottom;
field public android.support.v17.leanback.graphics.BoundsRule.ValueRule left;
field public android.support.v17.leanback.graphics.BoundsRule.ValueRule right;
@@ -2425,8 +2512,11 @@
}
public static final class BoundsRule.ValueRule {
+ method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule absoluteValue(int);
method public int getAbsoluteValue();
method public float getFraction();
+ method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParent(float);
+ method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParentWithOffset(float, int);
method public void setAbsoluteValue(int);
method public void setFraction(float);
}
@@ -3532,111 +3622,79 @@
public abstract class Parallax<PropertyT extends android.util.Property> {
ctor public Parallax();
- method public void addEffect(android.support.v17.leanback.widget.ParallaxEffect);
- method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue...);
- method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue...);
- method public abstract PropertyT addProperty(java.lang.String);
+ method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.PropertyMarkerValue...);
+ method public final PropertyT addProperty(java.lang.String);
method public abstract PropertyT createProperty(java.lang.String, int);
method public java.util.List<android.support.v17.leanback.widget.ParallaxEffect> getEffects();
+ method public abstract float getMaxValue();
method public final java.util.List<PropertyT> getProperties();
method public void removeAllEffects();
method public void removeEffect(android.support.v17.leanback.widget.ParallaxEffect);
method public void updateValues();
- method public abstract void verifyProperties() throws java.lang.IllegalStateException;
- }
-
- public static abstract class Parallax.FloatParallax<FloatPropertyT extends android.support.v17.leanback.widget.Parallax.FloatProperty> extends android.support.v17.leanback.widget.Parallax {
- ctor public Parallax.FloatParallax();
- method public final FloatPropertyT addProperty(java.lang.String);
- method public abstract float getMaxValue();
- method public final float getPropertyValue(int);
- method public final void setPropertyValue(int, float);
- method public final void verifyProperties() throws java.lang.IllegalStateException;
}
public static class Parallax.FloatProperty extends android.util.Property {
ctor public Parallax.FloatProperty(java.lang.String, int);
- method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue at(float, float);
- method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue atAbsolute(float);
- method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue atFraction(float);
- method public final java.lang.Float get(android.support.v17.leanback.widget.Parallax.FloatParallax);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue at(float, float);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atAbsolute(float);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atFraction(float);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMax();
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMin();
+ method public final java.lang.Float get(android.support.v17.leanback.widget.Parallax);
method public final int getIndex();
- method public final void set(android.support.v17.leanback.widget.Parallax.FloatParallax, java.lang.Float);
+ method public final float getValue(android.support.v17.leanback.widget.Parallax);
+ method public final void set(android.support.v17.leanback.widget.Parallax, java.lang.Float);
+ method public final void setValue(android.support.v17.leanback.widget.Parallax, float);
field public static final float UNKNOWN_AFTER = 3.4028235E38f;
field public static final float UNKNOWN_BEFORE = -3.4028235E38f;
}
- public static class Parallax.FloatPropertyMarkerValue extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue {
- ctor public Parallax.FloatPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.FloatProperty, float);
- ctor public Parallax.FloatPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.FloatProperty, float, float);
- method public final float getMarkerValue(android.support.v17.leanback.widget.Parallax.FloatParallax);
- }
-
- public static abstract class Parallax.IntParallax<IntPropertyT extends android.support.v17.leanback.widget.Parallax.IntProperty> extends android.support.v17.leanback.widget.Parallax {
- ctor public Parallax.IntParallax();
- method public final IntPropertyT addProperty(java.lang.String);
- method public abstract int getMaxValue();
- method public final int getPropertyValue(int);
- method public final void setPropertyValue(int, int);
- method public final void verifyProperties() throws java.lang.IllegalStateException;
- }
-
public static class Parallax.IntProperty extends android.util.Property {
ctor public Parallax.IntProperty(java.lang.String, int);
- method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue at(int, float);
- method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue atAbsolute(int);
- method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue atFraction(float);
- method public final java.lang.Integer get(android.support.v17.leanback.widget.Parallax.IntParallax);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue at(int, float);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atAbsolute(int);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atFraction(float);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMax();
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMin();
+ method public final java.lang.Integer get(android.support.v17.leanback.widget.Parallax);
method public final int getIndex();
- method public final void set(android.support.v17.leanback.widget.Parallax.IntParallax, java.lang.Integer);
+ method public final int getValue(android.support.v17.leanback.widget.Parallax);
+ method public final void set(android.support.v17.leanback.widget.Parallax, java.lang.Integer);
+ method public final void setValue(android.support.v17.leanback.widget.Parallax, int);
field public static final int UNKNOWN_AFTER = 2147483647; // 0x7fffffff
field public static final int UNKNOWN_BEFORE = -2147483648; // 0x80000000
}
- public static class Parallax.IntPropertyMarkerValue extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue {
- ctor public Parallax.IntPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.IntProperty, int);
- ctor public Parallax.IntPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.IntProperty, int, float);
- method public final int getMarkerValue(android.support.v17.leanback.widget.Parallax.IntParallax);
- }
-
public static class Parallax.PropertyMarkerValue<PropertyT> {
ctor public Parallax.PropertyMarkerValue(PropertyT);
method public PropertyT getProperty();
}
- public abstract class ParallaxEffect<ParallaxEffectT extends android.support.v17.leanback.widget.ParallaxEffect, PropertyMarkerValueT extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue> {
- ctor public ParallaxEffect();
+ public abstract class ParallaxEffect {
method public final void addTarget(android.support.v17.leanback.widget.ParallaxTarget);
- method protected abstract float calculateFraction(android.support.v17.leanback.widget.Parallax);
- method public final java.util.List<PropertyMarkerValueT> getPropertyRanges();
+ method public final java.util.List<android.support.v17.leanback.widget.Parallax.PropertyMarkerValue> getPropertyRanges();
method public final java.util.List<android.support.v17.leanback.widget.ParallaxTarget> getTargets();
method public final void performMapping(android.support.v17.leanback.widget.Parallax);
method public final void removeTarget(android.support.v17.leanback.widget.ParallaxTarget);
- method public final void setPropertyRanges(PropertyMarkerValueT...);
+ method public final void setPropertyRanges(android.support.v17.leanback.widget.Parallax.PropertyMarkerValue...);
method public final android.support.v17.leanback.widget.ParallaxEffect target(android.support.v17.leanback.widget.ParallaxTarget);
method public final android.support.v17.leanback.widget.ParallaxEffect target(java.lang.Object, android.animation.PropertyValuesHolder);
- }
-
- public static final class ParallaxEffect.FloatEffect extends android.support.v17.leanback.widget.ParallaxEffect {
- ctor public ParallaxEffect.FloatEffect();
- method protected float calculateFraction(android.support.v17.leanback.widget.Parallax);
- }
-
- public static final class ParallaxEffect.IntEffect extends android.support.v17.leanback.widget.ParallaxEffect {
- ctor public ParallaxEffect.IntEffect();
- method protected float calculateFraction(android.support.v17.leanback.widget.Parallax);
+ method public final <T, V extends java.lang.Number> android.support.v17.leanback.widget.ParallaxEffect target(T, android.util.Property<T, V>);
}
public abstract class ParallaxTarget {
ctor public ParallaxTarget();
- method public abstract float getFraction();
- method public abstract void update(float);
+ method public void directUpdate(java.lang.Number);
+ method public boolean isDirectMapping();
+ method public void update(float);
+ }
+
+ public static final class ParallaxTarget.DirectPropertyTarget<T, V extends java.lang.Number> extends android.support.v17.leanback.widget.ParallaxTarget {
+ ctor public ParallaxTarget.DirectPropertyTarget(java.lang.Object, android.util.Property<T, V>);
}
public static final class ParallaxTarget.PropertyValuesHolderTarget extends android.support.v17.leanback.widget.ParallaxTarget {
ctor public ParallaxTarget.PropertyValuesHolderTarget(java.lang.Object, android.animation.PropertyValuesHolder);
- method public float getFraction();
- method public void update(float);
}
public class PlaybackControlsRow extends android.support.v17.leanback.widget.Row {
@@ -3828,10 +3886,10 @@
method public void unselect();
}
- public class RecyclerViewParallax extends android.support.v17.leanback.widget.Parallax.IntParallax {
+ public class RecyclerViewParallax extends android.support.v17.leanback.widget.Parallax {
ctor public RecyclerViewParallax();
method public android.support.v17.leanback.widget.RecyclerViewParallax.ChildPositionProperty createProperty(java.lang.String, int);
- method public int getMaxValue();
+ method public float getMaxValue();
method public android.support.v7.widget.RecyclerView getRecyclerView();
method public void setRecyclerView(android.support.v7.widget.RecyclerView);
}
@@ -5909,72 +5967,72 @@
field public static final int RATING_THUMB_UP_DOWN = 2; // 0x2
}
- public abstract class TransportController {
- ctor public TransportController();
- method public abstract int getBufferPercentage();
- method public abstract long getCurrentPosition();
- method public abstract long getDuration();
- method public abstract int getTransportControlFlags();
- method public abstract boolean isPlaying();
- method public abstract void pausePlaying();
- method public abstract void registerStateListener(android.support.v4.media.TransportStateListener);
- method public abstract void seekTo(long);
- method public abstract void startPlaying();
- method public abstract void stopPlaying();
- method public abstract void unregisterStateListener(android.support.v4.media.TransportStateListener);
+ public abstract deprecated class TransportController {
+ ctor public deprecated TransportController();
+ method public abstract deprecated int getBufferPercentage();
+ method public abstract deprecated long getCurrentPosition();
+ method public abstract deprecated long getDuration();
+ method public abstract deprecated int getTransportControlFlags();
+ method public abstract deprecated boolean isPlaying();
+ method public abstract deprecated void pausePlaying();
+ method public abstract deprecated void registerStateListener(android.support.v4.media.TransportStateListener);
+ method public abstract deprecated void seekTo(long);
+ method public abstract deprecated void startPlaying();
+ method public abstract deprecated void stopPlaying();
+ method public abstract deprecated void unregisterStateListener(android.support.v4.media.TransportStateListener);
}
- public class TransportMediator extends android.support.v4.media.TransportController {
- ctor public TransportMediator(android.app.Activity, android.support.v4.media.TransportPerformer);
- ctor public TransportMediator(android.view.View, android.support.v4.media.TransportPerformer);
- method public void destroy();
- method public boolean dispatchKeyEvent(android.view.KeyEvent);
- method public int getBufferPercentage();
- method public long getCurrentPosition();
- method public long getDuration();
- method public java.lang.Object getRemoteControlClient();
- method public int getTransportControlFlags();
- method public boolean isPlaying();
- method public void pausePlaying();
- method public void refreshState();
- method public void registerStateListener(android.support.v4.media.TransportStateListener);
- method public void seekTo(long);
- method public void startPlaying();
- method public void stopPlaying();
- method public void unregisterStateListener(android.support.v4.media.TransportStateListener);
- field public static final int FLAG_KEY_MEDIA_FAST_FORWARD = 64; // 0x40
- field public static final int FLAG_KEY_MEDIA_NEXT = 128; // 0x80
- field public static final int FLAG_KEY_MEDIA_PAUSE = 16; // 0x10
- field public static final int FLAG_KEY_MEDIA_PLAY = 4; // 0x4
- field public static final int FLAG_KEY_MEDIA_PLAY_PAUSE = 8; // 0x8
- field public static final int FLAG_KEY_MEDIA_PREVIOUS = 1; // 0x1
- field public static final int FLAG_KEY_MEDIA_REWIND = 2; // 0x2
- field public static final int FLAG_KEY_MEDIA_STOP = 32; // 0x20
- field public static final int KEYCODE_MEDIA_PAUSE = 127; // 0x7f
- field public static final int KEYCODE_MEDIA_PLAY = 126; // 0x7e
- field public static final int KEYCODE_MEDIA_RECORD = 130; // 0x82
+ public deprecated class TransportMediator extends android.support.v4.media.TransportController {
+ ctor public deprecated TransportMediator(android.app.Activity, android.support.v4.media.TransportPerformer);
+ ctor public deprecated TransportMediator(android.view.View, android.support.v4.media.TransportPerformer);
+ method public deprecated void destroy();
+ method public deprecated boolean dispatchKeyEvent(android.view.KeyEvent);
+ method public deprecated int getBufferPercentage();
+ method public deprecated long getCurrentPosition();
+ method public deprecated long getDuration();
+ method public deprecated java.lang.Object getRemoteControlClient();
+ method public deprecated int getTransportControlFlags();
+ method public deprecated boolean isPlaying();
+ method public deprecated void pausePlaying();
+ method public deprecated void refreshState();
+ method public deprecated void registerStateListener(android.support.v4.media.TransportStateListener);
+ method public deprecated void seekTo(long);
+ method public deprecated void startPlaying();
+ method public deprecated void stopPlaying();
+ method public deprecated void unregisterStateListener(android.support.v4.media.TransportStateListener);
+ field public static final deprecated int FLAG_KEY_MEDIA_FAST_FORWARD = 64; // 0x40
+ field public static final deprecated int FLAG_KEY_MEDIA_NEXT = 128; // 0x80
+ field public static final deprecated int FLAG_KEY_MEDIA_PAUSE = 16; // 0x10
+ field public static final deprecated int FLAG_KEY_MEDIA_PLAY = 4; // 0x4
+ field public static final deprecated int FLAG_KEY_MEDIA_PLAY_PAUSE = 8; // 0x8
+ field public static final deprecated int FLAG_KEY_MEDIA_PREVIOUS = 1; // 0x1
+ field public static final deprecated int FLAG_KEY_MEDIA_REWIND = 2; // 0x2
+ field public static final deprecated int FLAG_KEY_MEDIA_STOP = 32; // 0x20
+ field public static final deprecated int KEYCODE_MEDIA_PAUSE = 127; // 0x7f
+ field public static final deprecated int KEYCODE_MEDIA_PLAY = 126; // 0x7e
+ field public static final deprecated int KEYCODE_MEDIA_RECORD = 130; // 0x82
}
- public abstract class TransportPerformer {
- ctor public TransportPerformer();
- method public void onAudioFocusChange(int);
- method public int onGetBufferPercentage();
- method public abstract long onGetCurrentPosition();
- method public abstract long onGetDuration();
- method public int onGetTransportControlFlags();
- method public abstract boolean onIsPlaying();
- method public boolean onMediaButtonDown(int, android.view.KeyEvent);
- method public boolean onMediaButtonUp(int, android.view.KeyEvent);
- method public abstract void onPause();
- method public abstract void onSeekTo(long);
- method public abstract void onStart();
- method public abstract void onStop();
+ public abstract deprecated class TransportPerformer {
+ ctor public deprecated TransportPerformer();
+ method public deprecated void onAudioFocusChange(int);
+ method public deprecated int onGetBufferPercentage();
+ method public abstract deprecated long onGetCurrentPosition();
+ method public abstract deprecated long onGetDuration();
+ method public deprecated int onGetTransportControlFlags();
+ method public abstract deprecated boolean onIsPlaying();
+ method public deprecated boolean onMediaButtonDown(int, android.view.KeyEvent);
+ method public deprecated boolean onMediaButtonUp(int, android.view.KeyEvent);
+ method public abstract deprecated void onPause();
+ method public abstract deprecated void onSeekTo(long);
+ method public abstract deprecated void onStart();
+ method public abstract deprecated void onStop();
}
- public class TransportStateListener {
- ctor public TransportStateListener();
- method public void onPlayingChanged(android.support.v4.media.TransportController);
- method public void onTransportControlsChanged(android.support.v4.media.TransportController);
+ public deprecated class TransportStateListener {
+ ctor public deprecated TransportStateListener();
+ method public deprecated void onPlayingChanged(android.support.v4.media.TransportController);
+ method public deprecated void onTransportControlsChanged(android.support.v4.media.TransportController);
}
public abstract class VolumeProviderCompat {
@@ -6012,6 +6070,8 @@
public final class MediaControllerCompat {
ctor public MediaControllerCompat(android.content.Context, android.support.v4.media.session.MediaSessionCompat);
ctor public MediaControllerCompat(android.content.Context, android.support.v4.media.session.MediaSessionCompat.Token) throws android.os.RemoteException;
+ method public void addQueueItem(android.support.v4.media.MediaDescriptionCompat);
+ method public void addQueueItem(android.support.v4.media.MediaDescriptionCompat, int);
method public void adjustVolume(int, int);
method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
method public android.os.Bundle getExtras();
@@ -6032,6 +6092,8 @@
method public boolean isShuffleModeEnabled();
method public void registerCallback(android.support.v4.media.session.MediaControllerCompat.Callback);
method public void registerCallback(android.support.v4.media.session.MediaControllerCompat.Callback, android.os.Handler);
+ method public void removeQueueItem(android.support.v4.media.MediaDescriptionCompat);
+ method public void removeQueueItemAt(int);
method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
method public static void setMediaController(android.app.Activity, android.support.v4.media.session.MediaControllerCompat);
method public void setVolumeTo(int, int);
@@ -6118,11 +6180,14 @@
method public void setSessionActivity(android.app.PendingIntent);
method public void setShuffleModeEnabled(boolean);
field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
+ field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4
field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
}
public static abstract class MediaSessionCompat.Callback {
ctor public MediaSessionCompat.Callback();
+ method public void onAddQueueItem(android.support.v4.media.MediaDescriptionCompat);
+ method public void onAddQueueItem(android.support.v4.media.MediaDescriptionCompat, int);
method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
method public void onCustomAction(java.lang.String, android.os.Bundle);
method public void onFastForward();
@@ -6136,6 +6201,8 @@
method public void onPrepareFromMediaId(java.lang.String, android.os.Bundle);
method public void onPrepareFromSearch(java.lang.String, android.os.Bundle);
method public void onPrepareFromUri(android.net.Uri, android.os.Bundle);
+ method public void onRemoveQueueItem(android.support.v4.media.MediaDescriptionCompat);
+ method public void onRemoveQueueItemAt(int);
method public void onRewind();
method public void onSeekTo(long);
method public void onSetRating(android.support.v4.media.RatingCompat);
@@ -8463,6 +8530,7 @@
method public android.support.v7.graphics.drawable.DrawerArrowDrawable getDrawerArrowDrawable();
method public android.view.View.OnClickListener getToolbarNavigationClickListener();
method public boolean isDrawerIndicatorEnabled();
+ method public boolean isDrawerSlideAnimationEnabled();
method public void onConfigurationChanged(android.content.res.Configuration);
method public void onDrawerClosed(android.view.View);
method public void onDrawerOpened(android.view.View);
@@ -8471,6 +8539,7 @@
method public boolean onOptionsItemSelected(android.view.MenuItem);
method public void setDrawerArrowDrawable(android.support.v7.graphics.drawable.DrawerArrowDrawable);
method public void setDrawerIndicatorEnabled(boolean);
+ method public void setDrawerSlideAnimationEnabled(boolean);
method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable);
method public void setHomeAsUpIndicator(int);
method public void setToolbarNavigationClickListener(android.view.View.OnClickListener);
diff --git a/api/26.0.0-alpha1.txt b/api/26.0.0-alpha1.txt
new file mode 100644
index 0000000..920c508
--- /dev/null
+++ b/api/26.0.0-alpha1.txt
@@ -0,0 +1,11757 @@
+package android.support.app.recommendation {
+
+ public final class ContentRecommendation {
+ method public java.lang.String getBackgroundImageUri();
+ method public int getBadgeImageResourceId();
+ method public int getColor();
+ method public android.graphics.Bitmap getContentImage();
+ method public android.support.app.recommendation.ContentRecommendation.IntentData getContentIntent();
+ method public java.lang.String[] getContentTypes();
+ method public android.support.app.recommendation.ContentRecommendation.IntentData getDismissIntent();
+ method public java.lang.String[] getGenres();
+ method public java.lang.String getGroup();
+ method public java.lang.String getIdTag();
+ method public java.lang.String getMaturityRating();
+ method public android.app.Notification getNotificationObject(android.content.Context);
+ method public java.lang.String getPricingType();
+ method public java.lang.String getPricingValue();
+ method public java.lang.String getPrimaryContentType();
+ method public int getProgressMax();
+ method public int getProgressValue();
+ method public long getRunningTime();
+ method public java.lang.String getSortKey();
+ method public java.lang.String getSourceName();
+ method public int getStatus();
+ method public java.lang.String getText();
+ method public java.lang.String getTitle();
+ method public boolean hasProgressInfo();
+ method public boolean isAutoDismiss();
+ method public void setAutoDismiss(boolean);
+ method public void setGroup(java.lang.String);
+ method public void setProgress(int, int);
+ method public void setSortKey(java.lang.String);
+ method public void setStatus(int);
+ field public static final java.lang.String CONTENT_MATURITY_ALL = "android.contentMaturity.all";
+ field public static final java.lang.String CONTENT_MATURITY_HIGH = "android.contentMaturity.high";
+ field public static final java.lang.String CONTENT_MATURITY_LOW = "android.contentMaturity.low";
+ field public static final java.lang.String CONTENT_MATURITY_MEDIUM = "android.contentMaturity.medium";
+ field public static final java.lang.String CONTENT_PRICING_FREE = "android.contentPrice.free";
+ field public static final java.lang.String CONTENT_PRICING_PREORDER = "android.contentPrice.preorder";
+ field public static final java.lang.String CONTENT_PRICING_PURCHASE = "android.contentPrice.purchase";
+ field public static final java.lang.String CONTENT_PRICING_RENTAL = "android.contentPrice.rental";
+ field public static final java.lang.String CONTENT_PRICING_SUBSCRIPTION = "android.contentPrice.subscription";
+ field public static final int CONTENT_STATUS_AVAILABLE = 2; // 0x2
+ field public static final int CONTENT_STATUS_PENDING = 1; // 0x1
+ field public static final int CONTENT_STATUS_READY = 0; // 0x0
+ field public static final int CONTENT_STATUS_UNAVAILABLE = 3; // 0x3
+ field public static final java.lang.String CONTENT_TYPE_APP = "android.contentType.app";
+ field public static final java.lang.String CONTENT_TYPE_BOOK = "android.contentType.book";
+ field public static final java.lang.String CONTENT_TYPE_COMIC = "android.contentType.comic";
+ field public static final java.lang.String CONTENT_TYPE_GAME = "android.contentType.game";
+ field public static final java.lang.String CONTENT_TYPE_MAGAZINE = "android.contentType.magazine";
+ field public static final java.lang.String CONTENT_TYPE_MOVIE = "android.contentType.movie";
+ field public static final java.lang.String CONTENT_TYPE_MUSIC = "android.contentType.music";
+ field public static final java.lang.String CONTENT_TYPE_NEWS = "android.contentType.news";
+ field public static final java.lang.String CONTENT_TYPE_PODCAST = "android.contentType.podcast";
+ field public static final java.lang.String CONTENT_TYPE_RADIO = "android.contentType.radio";
+ field public static final java.lang.String CONTENT_TYPE_SERIAL = "android.contentType.serial";
+ field public static final java.lang.String CONTENT_TYPE_SPORTS = "android.contentType.sports";
+ field public static final java.lang.String CONTENT_TYPE_TRAILER = "android.contentType.trailer";
+ field public static final java.lang.String CONTENT_TYPE_VIDEO = "android.contentType.video";
+ field public static final java.lang.String CONTENT_TYPE_WEBSITE = "android.contentType.website";
+ field public static final int INTENT_TYPE_ACTIVITY = 1; // 0x1
+ field public static final int INTENT_TYPE_BROADCAST = 2; // 0x2
+ field public static final int INTENT_TYPE_SERVICE = 3; // 0x3
+ }
+
+ public static final class ContentRecommendation.Builder {
+ ctor public ContentRecommendation.Builder();
+ method public android.support.app.recommendation.ContentRecommendation build();
+ method public android.support.app.recommendation.ContentRecommendation.Builder setAutoDismiss(boolean);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setBackgroundImageUri(java.lang.String);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setBadgeIcon(int);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setColor(int);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setContentImage(android.graphics.Bitmap);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setContentIntentData(int, android.content.Intent, int, android.os.Bundle);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setContentTypes(java.lang.String[]);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setDismissIntentData(int, android.content.Intent, int, android.os.Bundle);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setGenres(java.lang.String[]);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setGroup(java.lang.String);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setIdTag(java.lang.String);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setMaturityRating(java.lang.String);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setPricingInformation(java.lang.String, java.lang.String);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setProgress(int, int);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setRunningTime(long);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setSortKey(java.lang.String);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setSourceName(java.lang.String);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setStatus(int);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setText(java.lang.String);
+ method public android.support.app.recommendation.ContentRecommendation.Builder setTitle(java.lang.String);
+ }
+
+ public static abstract class ContentRecommendation.ContentMaturity implements java.lang.annotation.Annotation {
+ }
+
+ public static abstract class ContentRecommendation.ContentPricing implements java.lang.annotation.Annotation {
+ }
+
+ public static abstract class ContentRecommendation.ContentStatus implements java.lang.annotation.Annotation {
+ }
+
+ public static abstract class ContentRecommendation.ContentType implements java.lang.annotation.Annotation {
+ }
+
+ public static class ContentRecommendation.IntentData {
+ ctor public ContentRecommendation.IntentData();
+ }
+
+ public static abstract class ContentRecommendation.IntentType implements java.lang.annotation.Annotation {
+ }
+
+ public final class RecommendationExtender implements android.app.Notification.Extender {
+ ctor public RecommendationExtender();
+ ctor public RecommendationExtender(android.app.Notification);
+ method public android.app.Notification.Builder extend(android.app.Notification.Builder);
+ method public java.lang.String[] getContentTypes();
+ method public java.lang.String[] getGenres();
+ method public java.lang.String getMaturityRating();
+ method public java.lang.String getPricingType();
+ method public java.lang.String getPricingValue();
+ method public java.lang.String getPrimaryContentType();
+ method public long getRunningTime();
+ method public int getStatus();
+ method public android.support.app.recommendation.RecommendationExtender setContentTypes(java.lang.String[]);
+ method public android.support.app.recommendation.RecommendationExtender setGenres(java.lang.String[]);
+ method public android.support.app.recommendation.RecommendationExtender setMaturityRating(java.lang.String);
+ method public android.support.app.recommendation.RecommendationExtender setPricingInformation(java.lang.String, java.lang.String);
+ method public android.support.app.recommendation.RecommendationExtender setRunningTime(long);
+ method public android.support.app.recommendation.RecommendationExtender setStatus(int);
+ }
+
+}
+
+package android.support.customtabs {
+
+ public class CustomTabsCallback {
+ ctor public CustomTabsCallback();
+ method public void extraCallback(java.lang.String, android.os.Bundle);
+ method public void onMessageChannelReady(android.os.Bundle);
+ method public void onNavigationEvent(int, android.os.Bundle);
+ method public void onPostMessage(java.lang.String, android.os.Bundle);
+ field public static final int NAVIGATION_ABORTED = 4; // 0x4
+ field public static final int NAVIGATION_FAILED = 3; // 0x3
+ field public static final int NAVIGATION_FINISHED = 2; // 0x2
+ field public static final int NAVIGATION_STARTED = 1; // 0x1
+ field public static final int TAB_HIDDEN = 6; // 0x6
+ field public static final int TAB_SHOWN = 5; // 0x5
+ }
+
+ public class CustomTabsClient {
+ method public static boolean bindCustomTabsService(android.content.Context, java.lang.String, android.support.customtabs.CustomTabsServiceConnection);
+ method public static boolean connectAndInitialize(android.content.Context, java.lang.String);
+ method public android.os.Bundle extraCommand(java.lang.String, android.os.Bundle);
+ method public static java.lang.String getPackageName(android.content.Context, java.util.List<java.lang.String>);
+ method public static java.lang.String getPackageName(android.content.Context, java.util.List<java.lang.String>, boolean);
+ method public android.support.customtabs.CustomTabsSession newSession(android.support.customtabs.CustomTabsCallback);
+ method public boolean warmup(long);
+ }
+
+ public final class CustomTabsIntent {
+ method public static int getMaxToolbarItems();
+ method public void launchUrl(android.content.Context, android.net.Uri);
+ method public static android.content.Intent setAlwaysUseBrowserUI(android.content.Intent);
+ method public static boolean shouldAlwaysUseBrowserUI(android.content.Intent);
+ field public static final java.lang.String EXTRA_ACTION_BUTTON_BUNDLE = "android.support.customtabs.extra.ACTION_BUTTON_BUNDLE";
+ field public static final java.lang.String EXTRA_CLOSE_BUTTON_ICON = "android.support.customtabs.extra.CLOSE_BUTTON_ICON";
+ field public static final java.lang.String EXTRA_DEFAULT_SHARE_MENU_ITEM = "android.support.customtabs.extra.SHARE_MENU_ITEM";
+ field public static final java.lang.String EXTRA_ENABLE_INSTANT_APPS = "android.support.customtabs.extra.EXTRA_ENABLE_INSTANT_APPS";
+ field public static final java.lang.String EXTRA_ENABLE_URLBAR_HIDING = "android.support.customtabs.extra.ENABLE_URLBAR_HIDING";
+ field public static final java.lang.String EXTRA_EXIT_ANIMATION_BUNDLE = "android.support.customtabs.extra.EXIT_ANIMATION_BUNDLE";
+ field public static final java.lang.String EXTRA_MENU_ITEMS = "android.support.customtabs.extra.MENU_ITEMS";
+ field public static final java.lang.String EXTRA_REMOTEVIEWS = "android.support.customtabs.extra.EXTRA_REMOTEVIEWS";
+ field public static final java.lang.String EXTRA_REMOTEVIEWS_CLICKED_ID = "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_CLICKED_ID";
+ field public static final java.lang.String EXTRA_REMOTEVIEWS_PENDINGINTENT = "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_PENDINGINTENT";
+ field public static final java.lang.String EXTRA_REMOTEVIEWS_VIEW_IDS = "android.support.customtabs.extra.EXTRA_REMOTEVIEWS_VIEW_IDS";
+ field public static final java.lang.String EXTRA_SECONDARY_TOOLBAR_COLOR = "android.support.customtabs.extra.SECONDARY_TOOLBAR_COLOR";
+ field public static final java.lang.String EXTRA_SESSION = "android.support.customtabs.extra.SESSION";
+ field public static final java.lang.String EXTRA_TINT_ACTION_BUTTON = "android.support.customtabs.extra.TINT_ACTION_BUTTON";
+ field public static final java.lang.String EXTRA_TITLE_VISIBILITY_STATE = "android.support.customtabs.extra.TITLE_VISIBILITY";
+ field public static final java.lang.String EXTRA_TOOLBAR_COLOR = "android.support.customtabs.extra.TOOLBAR_COLOR";
+ field public static final java.lang.String EXTRA_TOOLBAR_ITEMS = "android.support.customtabs.extra.TOOLBAR_ITEMS";
+ field public static final java.lang.String KEY_DESCRIPTION = "android.support.customtabs.customaction.DESCRIPTION";
+ field public static final java.lang.String KEY_ICON = "android.support.customtabs.customaction.ICON";
+ field public static final java.lang.String KEY_ID = "android.support.customtabs.customaction.ID";
+ field public static final java.lang.String KEY_MENU_ITEM_TITLE = "android.support.customtabs.customaction.MENU_ITEM_TITLE";
+ field public static final java.lang.String KEY_PENDING_INTENT = "android.support.customtabs.customaction.PENDING_INTENT";
+ field public static final int NO_TITLE = 0; // 0x0
+ field public static final int SHOW_PAGE_TITLE = 1; // 0x1
+ field public static final int TOOLBAR_ACTION_BUTTON_ID = 0; // 0x0
+ field public final android.content.Intent intent;
+ field public final android.os.Bundle startAnimationBundle;
+ }
+
+ public static final class CustomTabsIntent.Builder {
+ ctor public CustomTabsIntent.Builder();
+ ctor public CustomTabsIntent.Builder(android.support.customtabs.CustomTabsSession);
+ method public android.support.customtabs.CustomTabsIntent.Builder addDefaultShareMenuItem();
+ method public android.support.customtabs.CustomTabsIntent.Builder addMenuItem(java.lang.String, android.app.PendingIntent);
+ method public deprecated android.support.customtabs.CustomTabsIntent.Builder addToolbarItem(int, android.graphics.Bitmap, java.lang.String, android.app.PendingIntent) throws java.lang.IllegalStateException;
+ method public android.support.customtabs.CustomTabsIntent build();
+ method public android.support.customtabs.CustomTabsIntent.Builder enableUrlBarHiding();
+ method public android.support.customtabs.CustomTabsIntent.Builder setActionButton(android.graphics.Bitmap, java.lang.String, android.app.PendingIntent, boolean);
+ method public android.support.customtabs.CustomTabsIntent.Builder setActionButton(android.graphics.Bitmap, java.lang.String, android.app.PendingIntent);
+ method public android.support.customtabs.CustomTabsIntent.Builder setCloseButtonIcon(android.graphics.Bitmap);
+ method public android.support.customtabs.CustomTabsIntent.Builder setExitAnimations(android.content.Context, int, int);
+ method public android.support.customtabs.CustomTabsIntent.Builder setInstantAppsEnabled(boolean);
+ method public android.support.customtabs.CustomTabsIntent.Builder setSecondaryToolbarColor(int);
+ method public android.support.customtabs.CustomTabsIntent.Builder setSecondaryToolbarViews(android.widget.RemoteViews, int[], android.app.PendingIntent);
+ method public android.support.customtabs.CustomTabsIntent.Builder setShowTitle(boolean);
+ method public android.support.customtabs.CustomTabsIntent.Builder setStartAnimations(android.content.Context, int, int);
+ method public android.support.customtabs.CustomTabsIntent.Builder setToolbarColor(int);
+ }
+
+ public abstract class CustomTabsService extends android.app.Service {
+ ctor public CustomTabsService();
+ method protected boolean cleanUpSession(android.support.customtabs.CustomTabsSessionToken);
+ method protected abstract android.os.Bundle extraCommand(java.lang.String, android.os.Bundle);
+ method protected abstract boolean mayLaunchUrl(android.support.customtabs.CustomTabsSessionToken, android.net.Uri, android.os.Bundle, java.util.List<android.os.Bundle>);
+ method protected abstract boolean newSession(android.support.customtabs.CustomTabsSessionToken);
+ method public android.os.IBinder onBind(android.content.Intent);
+ method protected abstract int postMessage(android.support.customtabs.CustomTabsSessionToken, java.lang.String, android.os.Bundle);
+ method protected abstract boolean requestPostMessageChannel(android.support.customtabs.CustomTabsSessionToken, android.net.Uri);
+ method protected abstract boolean updateVisuals(android.support.customtabs.CustomTabsSessionToken, android.os.Bundle);
+ method protected abstract boolean warmup(long);
+ field public static final java.lang.String ACTION_CUSTOM_TABS_CONNECTION = "android.support.customtabs.action.CustomTabsService";
+ field public static final java.lang.String KEY_URL = "android.support.customtabs.otherurls.URL";
+ field public static final int RESULT_FAILURE_DISALLOWED = -1; // 0xffffffff
+ field public static final int RESULT_FAILURE_MESSAGING_ERROR = -3; // 0xfffffffd
+ field public static final int RESULT_FAILURE_REMOTE_ERROR = -2; // 0xfffffffe
+ field public static final int RESULT_SUCCESS = 0; // 0x0
+ }
+
+ public static abstract class CustomTabsService.Result implements java.lang.annotation.Annotation {
+ }
+
+ public abstract class CustomTabsServiceConnection implements android.content.ServiceConnection {
+ ctor public CustomTabsServiceConnection();
+ method public abstract void onCustomTabsServiceConnected(android.content.ComponentName, android.support.customtabs.CustomTabsClient);
+ method public final void onServiceConnected(android.content.ComponentName, android.os.IBinder);
+ }
+
+ public final class CustomTabsSession {
+ 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);
+ method public boolean setActionButton(android.graphics.Bitmap, java.lang.String);
+ method public boolean setSecondaryToolbarViews(android.widget.RemoteViews, int[], android.app.PendingIntent);
+ method public deprecated boolean setToolbarItem(int, android.graphics.Bitmap, java.lang.String);
+ }
+
+ public class CustomTabsSessionToken {
+ 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);
+ }
+
+ public class PostMessageService extends android.app.Service {
+ ctor public PostMessageService();
+ method public android.os.IBinder onBind(android.content.Intent);
+ }
+
+ public abstract class PostMessageServiceConnection implements android.content.ServiceConnection {
+ ctor public PostMessageServiceConnection(android.support.customtabs.CustomTabsSessionToken);
+ method public boolean bindSessionToPostMessageService(android.content.Context, java.lang.String);
+ method public final boolean notifyMessageChannelReady(android.os.Bundle);
+ method public void onPostMessageServiceConnected();
+ method public void onPostMessageServiceDisconnected();
+ method public final void onServiceConnected(android.content.ComponentName, android.os.IBinder);
+ method public final void onServiceDisconnected(android.content.ComponentName);
+ method public final boolean postMessage(java.lang.String, android.os.Bundle);
+ method public void unbindFromContext(android.content.Context);
+ }
+
+}
+
+package android.support.design.widget {
+
+ public class AppBarLayout extends android.widget.LinearLayout {
+ ctor public AppBarLayout(android.content.Context);
+ ctor public AppBarLayout(android.content.Context, android.util.AttributeSet);
+ method public void addOnOffsetChangedListener(android.support.design.widget.AppBarLayout.OnOffsetChangedListener);
+ method public deprecated float getTargetElevation();
+ method public final int getTotalScrollRange();
+ method public void removeOnOffsetChangedListener(android.support.design.widget.AppBarLayout.OnOffsetChangedListener);
+ method public void setExpanded(boolean);
+ method public void setExpanded(boolean, boolean);
+ method public deprecated void setTargetElevation(float);
+ }
+
+ public static class AppBarLayout.Behavior extends android.support.design.widget.HeaderBehavior {
+ ctor public AppBarLayout.Behavior();
+ ctor public AppBarLayout.Behavior(android.content.Context, android.util.AttributeSet);
+ method public boolean onLayoutChild(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout, int);
+ method public boolean onMeasureChild(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout, int, int, int, int);
+ method public boolean onNestedFling(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout, android.view.View, float, float, boolean);
+ method public void onNestedPreScroll(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout, android.view.View, int, int, int[]);
+ method public void onNestedScroll(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout, android.view.View, int, int, int, int);
+ method public void onRestoreInstanceState(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout, android.os.Parcelable);
+ method public android.os.Parcelable onSaveInstanceState(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout);
+ method public boolean onStartNestedScroll(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout, android.view.View, android.view.View, int);
+ method public void onStopNestedScroll(android.support.design.widget.CoordinatorLayout, android.support.design.widget.AppBarLayout, android.view.View);
+ method public void setDragCallback(android.support.design.widget.AppBarLayout.Behavior.DragCallback);
+ }
+
+ public static abstract class AppBarLayout.Behavior.DragCallback {
+ ctor public AppBarLayout.Behavior.DragCallback();
+ method public abstract boolean canDrag(android.support.design.widget.AppBarLayout);
+ }
+
+ protected static class AppBarLayout.Behavior.SavedState extends android.support.v4.view.AbsSavedState {
+ ctor public AppBarLayout.Behavior.SavedState(android.os.Parcel, java.lang.ClassLoader);
+ ctor public AppBarLayout.Behavior.SavedState(android.os.Parcelable);
+ field public static final android.os.Parcelable.Creator<android.support.design.widget.AppBarLayout.Behavior.SavedState> CREATOR;
+ }
+
+ public static class AppBarLayout.LayoutParams extends android.widget.LinearLayout.LayoutParams {
+ ctor public AppBarLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+ ctor public AppBarLayout.LayoutParams(int, int);
+ ctor public AppBarLayout.LayoutParams(int, int, float);
+ ctor public AppBarLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+ ctor public AppBarLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ ctor public AppBarLayout.LayoutParams(android.widget.LinearLayout.LayoutParams);
+ ctor public AppBarLayout.LayoutParams(android.support.design.widget.AppBarLayout.LayoutParams);
+ method public int getScrollFlags();
+ method public android.view.animation.Interpolator getScrollInterpolator();
+ method public void setScrollFlags(int);
+ method public void setScrollInterpolator(android.view.animation.Interpolator);
+ field public static final int SCROLL_FLAG_ENTER_ALWAYS = 4; // 0x4
+ field public static final int SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED = 8; // 0x8
+ field public static final int SCROLL_FLAG_EXIT_UNTIL_COLLAPSED = 2; // 0x2
+ field public static final int SCROLL_FLAG_SCROLL = 1; // 0x1
+ field public static final int SCROLL_FLAG_SNAP = 16; // 0x10
+ }
+
+ public static abstract interface AppBarLayout.OnOffsetChangedListener {
+ method public abstract void onOffsetChanged(android.support.design.widget.AppBarLayout, int);
+ }
+
+ public static class AppBarLayout.ScrollingViewBehavior extends android.support.design.widget.HeaderScrollingViewBehavior {
+ ctor public AppBarLayout.ScrollingViewBehavior();
+ ctor public AppBarLayout.ScrollingViewBehavior(android.content.Context, android.util.AttributeSet);
+ method public boolean layoutDependsOn(android.support.design.widget.CoordinatorLayout, android.view.View, android.view.View);
+ method public boolean onDependentViewChanged(android.support.design.widget.CoordinatorLayout, android.view.View, android.view.View);
+ method public boolean onRequestChildRectangleOnScreen(android.support.design.widget.CoordinatorLayout, android.view.View, android.graphics.Rect, boolean);
+ }
+
+ public abstract class BaseTransientBottomBar<B extends android.support.design.widget.BaseTransientBottomBar<B>> {
+ ctor protected BaseTransientBottomBar(android.view.ViewGroup, android.view.View, android.support.design.widget.BaseTransientBottomBar.ContentViewCallback);
+ method public B addCallback(android.support.design.widget.BaseTransientBottomBar.BaseCallback<B>);
+ method public void dismiss();
+ method public android.content.Context getContext();
+ method public int getDuration();
+ method public android.view.View getView();
+ method public boolean isShown();
+ method public boolean isShownOrQueued();
+ method public B removeCallback(android.support.design.widget.BaseTransientBottomBar.BaseCallback<B>);
+ method public B setDuration(int);
+ method public void show();
+ field public static final int LENGTH_INDEFINITE = -2; // 0xfffffffe
+ field public static final int LENGTH_LONG = 0; // 0x0
+ field public static final int LENGTH_SHORT = -1; // 0xffffffff
+ }
+
+ public static abstract class BaseTransientBottomBar.BaseCallback<B> {
+ ctor public BaseTransientBottomBar.BaseCallback();
+ method public void onDismissed(B, int);
+ method public void onShown(B);
+ field public static final int DISMISS_EVENT_ACTION = 1; // 0x1
+ field public static final int DISMISS_EVENT_CONSECUTIVE = 4; // 0x4
+ field public static final int DISMISS_EVENT_MANUAL = 3; // 0x3
+ field public static final int DISMISS_EVENT_SWIPE = 0; // 0x0
+ field public static final int DISMISS_EVENT_TIMEOUT = 2; // 0x2
+ }
+
+ public static abstract interface BaseTransientBottomBar.ContentViewCallback {
+ method public abstract void animateContentIn(int, int);
+ method public abstract void animateContentOut(int, int);
+ }
+
+ public class BottomNavigationView extends android.widget.FrameLayout {
+ ctor public BottomNavigationView(android.content.Context);
+ ctor public BottomNavigationView(android.content.Context, android.util.AttributeSet);
+ ctor public BottomNavigationView(android.content.Context, android.util.AttributeSet, int);
+ method public int getItemBackgroundResource();
+ method public android.content.res.ColorStateList getItemIconTintList();
+ method public android.content.res.ColorStateList getItemTextColor();
+ method public int getMaxItemCount();
+ method public android.view.Menu getMenu();
+ method public int getSelectedItemId();
+ method public void inflateMenu(int);
+ method public void setItemBackgroundResource(int);
+ method public void setItemIconTintList(android.content.res.ColorStateList);
+ method public void setItemTextColor(android.content.res.ColorStateList);
+ method public void setOnNavigationItemReselectedListener(android.support.design.widget.BottomNavigationView.OnNavigationItemReselectedListener);
+ method public void setOnNavigationItemSelectedListener(android.support.design.widget.BottomNavigationView.OnNavigationItemSelectedListener);
+ method public void setSelectedItemId(int);
+ }
+
+ public static abstract interface BottomNavigationView.OnNavigationItemReselectedListener {
+ method public abstract void onNavigationItemReselected(android.view.MenuItem);
+ }
+
+ public static abstract interface BottomNavigationView.OnNavigationItemSelectedListener {
+ method public abstract boolean onNavigationItemSelected(android.view.MenuItem);
+ }
+
+ public class BottomSheetBehavior<V extends android.view.View> extends android.support.design.widget.CoordinatorLayout.Behavior {
+ ctor public BottomSheetBehavior();
+ ctor public BottomSheetBehavior(android.content.Context, android.util.AttributeSet);
+ method public static <V extends android.view.View> android.support.design.widget.BottomSheetBehavior<V> from(V);
+ method public final int getPeekHeight();
+ method public boolean getSkipCollapsed();
+ method public final int getState();
+ method public boolean isHideable();
+ method public void setBottomSheetCallback(android.support.design.widget.BottomSheetBehavior.BottomSheetCallback);
+ method public void setHideable(boolean);
+ method public final void setPeekHeight(int);
+ method public void setSkipCollapsed(boolean);
+ method public final void setState(int);
+ field public static final int PEEK_HEIGHT_AUTO = -1; // 0xffffffff
+ field public static final int STATE_COLLAPSED = 4; // 0x4
+ field public static final int STATE_DRAGGING = 1; // 0x1
+ field public static final int STATE_EXPANDED = 3; // 0x3
+ field public static final int STATE_HIDDEN = 5; // 0x5
+ field public static final int STATE_SETTLING = 2; // 0x2
+ }
+
+ public static abstract class BottomSheetBehavior.BottomSheetCallback {
+ ctor public BottomSheetBehavior.BottomSheetCallback();
+ method public abstract void onSlide(android.view.View, float);
+ method public abstract void onStateChanged(android.view.View, int);
+ }
+
+ protected static class BottomSheetBehavior.SavedState extends android.support.v4.view.AbsSavedState {
+ ctor public BottomSheetBehavior.SavedState(android.os.Parcel);
+ ctor public BottomSheetBehavior.SavedState(android.os.Parcel, java.lang.ClassLoader);
+ ctor public BottomSheetBehavior.SavedState(android.os.Parcelable, int);
+ field public static final android.os.Parcelable.Creator<android.support.design.widget.BottomSheetBehavior.SavedState> CREATOR;
+ }
+
+ public class BottomSheetDialog extends android.support.v7.app.AppCompatDialog {
+ ctor public BottomSheetDialog(android.content.Context);
+ ctor public BottomSheetDialog(android.content.Context, int);
+ ctor protected BottomSheetDialog(android.content.Context, boolean, android.content.DialogInterface.OnCancelListener);
+ }
+
+ public class BottomSheetDialogFragment extends android.support.v7.app.AppCompatDialogFragment {
+ ctor public BottomSheetDialogFragment();
+ }
+
+ public class CollapsingToolbarLayout extends android.widget.FrameLayout {
+ ctor public CollapsingToolbarLayout(android.content.Context);
+ ctor public CollapsingToolbarLayout(android.content.Context, android.util.AttributeSet);
+ ctor public CollapsingToolbarLayout(android.content.Context, android.util.AttributeSet, int);
+ method public int getCollapsedTitleGravity();
+ method public android.graphics.Typeface getCollapsedTitleTypeface();
+ method public android.graphics.drawable.Drawable getContentScrim();
+ method public int getExpandedTitleGravity();
+ method public int getExpandedTitleMarginBottom();
+ method public int getExpandedTitleMarginEnd();
+ method public int getExpandedTitleMarginStart();
+ method public int getExpandedTitleMarginTop();
+ method public android.graphics.Typeface getExpandedTitleTypeface();
+ method public long getScrimAnimationDuration();
+ method public int getScrimVisibleHeightTrigger();
+ method public android.graphics.drawable.Drawable getStatusBarScrim();
+ method public java.lang.CharSequence getTitle();
+ method public boolean isTitleEnabled();
+ method public void setCollapsedTitleGravity(int);
+ method public void setCollapsedTitleTextAppearance(int);
+ method public void setCollapsedTitleTextColor(int);
+ method public void setCollapsedTitleTextColor(android.content.res.ColorStateList);
+ method public void setCollapsedTitleTypeface(android.graphics.Typeface);
+ method public void setContentScrim(android.graphics.drawable.Drawable);
+ method public void setContentScrimColor(int);
+ method public void setContentScrimResource(int);
+ method public void setExpandedTitleColor(int);
+ method public void setExpandedTitleGravity(int);
+ method public void setExpandedTitleMargin(int, int, int, int);
+ method public void setExpandedTitleMarginBottom(int);
+ method public void setExpandedTitleMarginEnd(int);
+ method public void setExpandedTitleMarginStart(int);
+ method public void setExpandedTitleMarginTop(int);
+ method public void setExpandedTitleTextAppearance(int);
+ method public void setExpandedTitleTextColor(android.content.res.ColorStateList);
+ method public void setExpandedTitleTypeface(android.graphics.Typeface);
+ method public void setScrimAnimationDuration(long);
+ method public void setScrimVisibleHeightTrigger(int);
+ method public void setScrimsShown(boolean);
+ method public void setScrimsShown(boolean, boolean);
+ method public void setStatusBarScrim(android.graphics.drawable.Drawable);
+ method public void setStatusBarScrimColor(int);
+ method public void setStatusBarScrimResource(int);
+ method public void setTitle(java.lang.CharSequence);
+ method public void setTitleEnabled(boolean);
+ }
+
+ public static class CollapsingToolbarLayout.LayoutParams extends android.widget.FrameLayout.LayoutParams {
+ ctor public CollapsingToolbarLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+ ctor public CollapsingToolbarLayout.LayoutParams(int, int);
+ ctor public CollapsingToolbarLayout.LayoutParams(int, int, int);
+ ctor public CollapsingToolbarLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+ ctor public CollapsingToolbarLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ ctor public CollapsingToolbarLayout.LayoutParams(android.widget.FrameLayout.LayoutParams);
+ method public int getCollapseMode();
+ method public float getParallaxMultiplier();
+ method public void setCollapseMode(int);
+ method public void setParallaxMultiplier(float);
+ field public static final int COLLAPSE_MODE_OFF = 0; // 0x0
+ field public static final int COLLAPSE_MODE_PARALLAX = 2; // 0x2
+ field public static final int COLLAPSE_MODE_PIN = 1; // 0x1
+ }
+
+ public class CoordinatorLayout extends android.view.ViewGroup implements android.support.v4.view.NestedScrollingParent {
+ ctor public CoordinatorLayout(android.content.Context);
+ ctor public CoordinatorLayout(android.content.Context, android.util.AttributeSet);
+ ctor public CoordinatorLayout(android.content.Context, android.util.AttributeSet, int);
+ method public void dispatchDependentViewsChanged(android.view.View);
+ method public boolean doViewsOverlap(android.view.View, android.view.View);
+ method public java.util.List<android.view.View> getDependencies(android.view.View);
+ method public java.util.List<android.view.View> getDependents(android.view.View);
+ method public android.graphics.drawable.Drawable getStatusBarBackground();
+ method public boolean isPointInChildBounds(android.view.View, int, int);
+ method public void onAttachedToWindow();
+ method public void onDetachedFromWindow();
+ method public void onDraw(android.graphics.Canvas);
+ method protected void onLayout(boolean, int, int, int, int);
+ method public void onLayoutChild(android.view.View, int);
+ method public void onMeasureChild(android.view.View, int, int, int, int);
+ method public void setStatusBarBackground(android.graphics.drawable.Drawable);
+ method public void setStatusBarBackgroundColor(int);
+ method public void setStatusBarBackgroundResource(int);
+ }
+
+ public static abstract class CoordinatorLayout.Behavior<V extends android.view.View> {
+ ctor public CoordinatorLayout.Behavior();
+ ctor public CoordinatorLayout.Behavior(android.content.Context, android.util.AttributeSet);
+ method public boolean blocksInteractionBelow(android.support.design.widget.CoordinatorLayout, V);
+ method public boolean getInsetDodgeRect(android.support.design.widget.CoordinatorLayout, V, android.graphics.Rect);
+ method public int getScrimColor(android.support.design.widget.CoordinatorLayout, V);
+ method public float getScrimOpacity(android.support.design.widget.CoordinatorLayout, V);
+ method public static java.lang.Object getTag(android.view.View);
+ method public boolean layoutDependsOn(android.support.design.widget.CoordinatorLayout, V, android.view.View);
+ method public android.support.v4.view.WindowInsetsCompat onApplyWindowInsets(android.support.design.widget.CoordinatorLayout, V, android.support.v4.view.WindowInsetsCompat);
+ method public void onAttachedToLayoutParams(android.support.design.widget.CoordinatorLayout.LayoutParams);
+ method public boolean onDependentViewChanged(android.support.design.widget.CoordinatorLayout, V, android.view.View);
+ method public void onDependentViewRemoved(android.support.design.widget.CoordinatorLayout, V, android.view.View);
+ method public void onDetachedFromLayoutParams();
+ method public boolean onInterceptTouchEvent(android.support.design.widget.CoordinatorLayout, V, android.view.MotionEvent);
+ method public boolean onLayoutChild(android.support.design.widget.CoordinatorLayout, V, int);
+ method public boolean onMeasureChild(android.support.design.widget.CoordinatorLayout, V, int, int, int, int);
+ method public boolean onNestedFling(android.support.design.widget.CoordinatorLayout, V, android.view.View, float, float, boolean);
+ method public boolean onNestedPreFling(android.support.design.widget.CoordinatorLayout, V, android.view.View, float, float);
+ method public void onNestedPreScroll(android.support.design.widget.CoordinatorLayout, V, android.view.View, int, int, int[]);
+ method public void onNestedScroll(android.support.design.widget.CoordinatorLayout, V, android.view.View, int, int, int, int);
+ method public void onNestedScrollAccepted(android.support.design.widget.CoordinatorLayout, V, android.view.View, android.view.View, int);
+ method public boolean onRequestChildRectangleOnScreen(android.support.design.widget.CoordinatorLayout, V, android.graphics.Rect, boolean);
+ method public void onRestoreInstanceState(android.support.design.widget.CoordinatorLayout, V, android.os.Parcelable);
+ method public android.os.Parcelable onSaveInstanceState(android.support.design.widget.CoordinatorLayout, V);
+ method public boolean onStartNestedScroll(android.support.design.widget.CoordinatorLayout, V, android.view.View, android.view.View, int);
+ method public void onStopNestedScroll(android.support.design.widget.CoordinatorLayout, V, android.view.View);
+ method public boolean onTouchEvent(android.support.design.widget.CoordinatorLayout, V, android.view.MotionEvent);
+ method public static void setTag(android.view.View, java.lang.Object);
+ }
+
+ public static abstract class CoordinatorLayout.DefaultBehavior implements java.lang.annotation.Annotation {
+ }
+
+ public static class CoordinatorLayout.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+ ctor public CoordinatorLayout.LayoutParams(int, int);
+ ctor public CoordinatorLayout.LayoutParams(android.support.design.widget.CoordinatorLayout.LayoutParams);
+ ctor public CoordinatorLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ ctor public CoordinatorLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+ method public int getAnchorId();
+ method public android.support.design.widget.CoordinatorLayout.Behavior getBehavior();
+ method public void setAnchorId(int);
+ method public void setBehavior(android.support.design.widget.CoordinatorLayout.Behavior);
+ field public int anchorGravity;
+ field public int dodgeInsetEdges;
+ field public int gravity;
+ field public int insetEdge;
+ field public int keyline;
+ }
+
+ protected static class CoordinatorLayout.SavedState extends android.support.v4.view.AbsSavedState {
+ ctor public CoordinatorLayout.SavedState(android.os.Parcel, java.lang.ClassLoader);
+ ctor public CoordinatorLayout.SavedState(android.os.Parcelable);
+ field public static final android.os.Parcelable.Creator<android.support.design.widget.CoordinatorLayout.SavedState> CREATOR;
+ }
+
+ public class FloatingActionButton extends android.support.design.widget.VisibilityAwareImageButton {
+ ctor public FloatingActionButton(android.content.Context);
+ ctor public FloatingActionButton(android.content.Context, android.util.AttributeSet);
+ ctor public FloatingActionButton(android.content.Context, android.util.AttributeSet, int);
+ method public float getCompatElevation();
+ method public android.graphics.drawable.Drawable getContentBackground();
+ method public boolean getContentRect(android.graphics.Rect);
+ method public int getRippleColor();
+ method public int getSize();
+ method public boolean getUseCompatPadding();
+ method public void hide();
+ method public void hide(android.support.design.widget.FloatingActionButton.OnVisibilityChangedListener);
+ method public void setCompatElevation(float);
+ method public void setRippleColor(int);
+ method public void setSize(int);
+ method public void setUseCompatPadding(boolean);
+ method public void show();
+ method public void show(android.support.design.widget.FloatingActionButton.OnVisibilityChangedListener);
+ field public static final int SIZE_AUTO = -1; // 0xffffffff
+ field public static final int SIZE_MINI = 1; // 0x1
+ field public static final int SIZE_NORMAL = 0; // 0x0
+ }
+
+ public static class FloatingActionButton.Behavior extends android.support.design.widget.CoordinatorLayout.Behavior {
+ ctor public FloatingActionButton.Behavior();
+ ctor public FloatingActionButton.Behavior(android.content.Context, android.util.AttributeSet);
+ method public boolean getInsetDodgeRect(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, android.graphics.Rect);
+ method public boolean isAutoHideEnabled();
+ method public boolean onDependentViewChanged(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, android.view.View);
+ method public boolean onLayoutChild(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, int);
+ method public void setAutoHideEnabled(boolean);
+ }
+
+ public static abstract class FloatingActionButton.OnVisibilityChangedListener {
+ ctor public FloatingActionButton.OnVisibilityChangedListener();
+ method public void onHidden(android.support.design.widget.FloatingActionButton);
+ method public void onShown(android.support.design.widget.FloatingActionButton);
+ }
+
+ abstract class HeaderBehavior<V extends android.view.View> extends android.support.design.widget.ViewOffsetBehavior {
+ ctor public HeaderBehavior();
+ ctor public HeaderBehavior(android.content.Context, android.util.AttributeSet);
+ }
+
+ abstract class HeaderScrollingViewBehavior extends android.support.design.widget.ViewOffsetBehavior {
+ ctor public HeaderScrollingViewBehavior();
+ ctor public HeaderScrollingViewBehavior(android.content.Context, android.util.AttributeSet);
+ method public final int getOverlayTop();
+ method protected void layoutChild(android.support.design.widget.CoordinatorLayout, android.view.View, int);
+ method public boolean onMeasureChild(android.support.design.widget.CoordinatorLayout, android.view.View, int, int, int, int);
+ method public final void setOverlayTop(int);
+ }
+
+ public class NavigationView extends android.widget.FrameLayout {
+ ctor public NavigationView(android.content.Context);
+ ctor public NavigationView(android.content.Context, android.util.AttributeSet);
+ ctor public NavigationView(android.content.Context, android.util.AttributeSet, int);
+ method public void addHeaderView(android.view.View);
+ method public int getHeaderCount();
+ method public android.view.View getHeaderView(int);
+ method public android.graphics.drawable.Drawable getItemBackground();
+ method public android.content.res.ColorStateList getItemIconTintList();
+ method public android.content.res.ColorStateList getItemTextColor();
+ method public android.view.Menu getMenu();
+ method public android.view.View inflateHeaderView(int);
+ method public void inflateMenu(int);
+ method public void removeHeaderView(android.view.View);
+ method public void setCheckedItem(int);
+ method public void setItemBackground(android.graphics.drawable.Drawable);
+ method public void setItemBackgroundResource(int);
+ method public void setItemIconTintList(android.content.res.ColorStateList);
+ method public void setItemTextAppearance(int);
+ method public void setItemTextColor(android.content.res.ColorStateList);
+ method public void setNavigationItemSelectedListener(android.support.design.widget.NavigationView.OnNavigationItemSelectedListener);
+ }
+
+ public static abstract interface NavigationView.OnNavigationItemSelectedListener {
+ method public abstract boolean onNavigationItemSelected(android.view.MenuItem);
+ }
+
+ public static class NavigationView.SavedState extends android.support.v4.view.AbsSavedState {
+ ctor public NavigationView.SavedState(android.os.Parcel, java.lang.ClassLoader);
+ ctor public NavigationView.SavedState(android.os.Parcelable);
+ field public static final android.os.Parcelable.Creator<android.support.design.widget.NavigationView.SavedState> CREATOR;
+ field public android.os.Bundle menuState;
+ }
+
+ public final class Snackbar extends android.support.design.widget.BaseTransientBottomBar {
+ method public static android.support.design.widget.Snackbar make(android.view.View, java.lang.CharSequence, int);
+ method public static android.support.design.widget.Snackbar make(android.view.View, int, int);
+ method public android.support.design.widget.Snackbar setAction(int, android.view.View.OnClickListener);
+ method public android.support.design.widget.Snackbar setAction(java.lang.CharSequence, android.view.View.OnClickListener);
+ method public android.support.design.widget.Snackbar setActionTextColor(android.content.res.ColorStateList);
+ method public android.support.design.widget.Snackbar setActionTextColor(int);
+ method public deprecated android.support.design.widget.Snackbar setCallback(android.support.design.widget.Snackbar.Callback);
+ method public android.support.design.widget.Snackbar setText(java.lang.CharSequence);
+ method public android.support.design.widget.Snackbar setText(int);
+ field public static final int LENGTH_INDEFINITE = -2; // 0xfffffffe
+ field public static final int LENGTH_LONG = 0; // 0x0
+ field public static final int LENGTH_SHORT = -1; // 0xffffffff
+ }
+
+ public static class Snackbar.Callback extends android.support.design.widget.BaseTransientBottomBar.BaseCallback {
+ ctor public Snackbar.Callback();
+ method public void onDismissed(android.support.design.widget.Snackbar, int);
+ method public void onShown(android.support.design.widget.Snackbar);
+ field public static final int DISMISS_EVENT_ACTION = 1; // 0x1
+ field public static final int DISMISS_EVENT_CONSECUTIVE = 4; // 0x4
+ field public static final int DISMISS_EVENT_MANUAL = 3; // 0x3
+ field public static final int DISMISS_EVENT_SWIPE = 0; // 0x0
+ field public static final int DISMISS_EVENT_TIMEOUT = 2; // 0x2
+ }
+
+ public class SwipeDismissBehavior<V extends android.view.View> extends android.support.design.widget.CoordinatorLayout.Behavior {
+ ctor public SwipeDismissBehavior();
+ method public boolean canSwipeDismissView(android.view.View);
+ method public int getDragState();
+ method public void setDragDismissDistance(float);
+ method public void setEndAlphaSwipeDistance(float);
+ method public void setListener(android.support.design.widget.SwipeDismissBehavior.OnDismissListener);
+ method public void setSensitivity(float);
+ method public void setStartAlphaSwipeDistance(float);
+ method public void setSwipeDirection(int);
+ field public static final int STATE_DRAGGING = 1; // 0x1
+ field public static final int STATE_IDLE = 0; // 0x0
+ field public static final int STATE_SETTLING = 2; // 0x2
+ field public static final int SWIPE_DIRECTION_ANY = 2; // 0x2
+ field public static final int SWIPE_DIRECTION_END_TO_START = 1; // 0x1
+ field public static final int SWIPE_DIRECTION_START_TO_END = 0; // 0x0
+ }
+
+ public static abstract interface SwipeDismissBehavior.OnDismissListener {
+ method public abstract void onDismiss(android.view.View);
+ method public abstract void onDragStateChanged(int);
+ }
+
+ public final class TabItem extends android.view.View {
+ ctor public TabItem(android.content.Context);
+ ctor public TabItem(android.content.Context, android.util.AttributeSet);
+ }
+
+ public class TabLayout extends android.widget.HorizontalScrollView {
+ ctor public TabLayout(android.content.Context);
+ ctor public TabLayout(android.content.Context, android.util.AttributeSet);
+ ctor public TabLayout(android.content.Context, android.util.AttributeSet, int);
+ method public void addOnTabSelectedListener(android.support.design.widget.TabLayout.OnTabSelectedListener);
+ method public void addTab(android.support.design.widget.TabLayout.Tab);
+ method public void addTab(android.support.design.widget.TabLayout.Tab, int);
+ method public void addTab(android.support.design.widget.TabLayout.Tab, boolean);
+ method public void addTab(android.support.design.widget.TabLayout.Tab, int, boolean);
+ method public void clearOnTabSelectedListeners();
+ method public int getSelectedTabPosition();
+ method public android.support.design.widget.TabLayout.Tab getTabAt(int);
+ method public int getTabCount();
+ method public int getTabGravity();
+ method public int getTabMode();
+ method public android.content.res.ColorStateList getTabTextColors();
+ method public android.support.design.widget.TabLayout.Tab newTab();
+ method public void removeAllTabs();
+ method public void removeOnTabSelectedListener(android.support.design.widget.TabLayout.OnTabSelectedListener);
+ method public void removeTab(android.support.design.widget.TabLayout.Tab);
+ method public void removeTabAt(int);
+ method public deprecated void setOnTabSelectedListener(android.support.design.widget.TabLayout.OnTabSelectedListener);
+ method public void setScrollPosition(int, float, boolean);
+ method public void setSelectedTabIndicatorColor(int);
+ method public void setSelectedTabIndicatorHeight(int);
+ method public void setTabGravity(int);
+ method public void setTabMode(int);
+ method public void setTabTextColors(android.content.res.ColorStateList);
+ method public void setTabTextColors(int, int);
+ method public deprecated void setTabsFromPagerAdapter(android.support.v4.view.PagerAdapter);
+ method public void setupWithViewPager(android.support.v4.view.ViewPager);
+ method public void setupWithViewPager(android.support.v4.view.ViewPager, boolean);
+ field public static final int GRAVITY_CENTER = 1; // 0x1
+ field public static final int GRAVITY_FILL = 0; // 0x0
+ field public static final int MODE_FIXED = 1; // 0x1
+ field public static final int MODE_SCROLLABLE = 0; // 0x0
+ }
+
+ public static abstract interface TabLayout.OnTabSelectedListener {
+ method public abstract void onTabReselected(android.support.design.widget.TabLayout.Tab);
+ method public abstract void onTabSelected(android.support.design.widget.TabLayout.Tab);
+ method public abstract void onTabUnselected(android.support.design.widget.TabLayout.Tab);
+ }
+
+ public static final class TabLayout.Tab {
+ method public java.lang.CharSequence getContentDescription();
+ method public android.view.View getCustomView();
+ method public android.graphics.drawable.Drawable getIcon();
+ method public int getPosition();
+ method public java.lang.Object getTag();
+ method public java.lang.CharSequence getText();
+ method public boolean isSelected();
+ method public void select();
+ method public android.support.design.widget.TabLayout.Tab setContentDescription(int);
+ method public android.support.design.widget.TabLayout.Tab setContentDescription(java.lang.CharSequence);
+ method public android.support.design.widget.TabLayout.Tab setCustomView(android.view.View);
+ method public android.support.design.widget.TabLayout.Tab setCustomView(int);
+ method public android.support.design.widget.TabLayout.Tab setIcon(android.graphics.drawable.Drawable);
+ method public android.support.design.widget.TabLayout.Tab setIcon(int);
+ method public android.support.design.widget.TabLayout.Tab setTag(java.lang.Object);
+ method public android.support.design.widget.TabLayout.Tab setText(java.lang.CharSequence);
+ method public android.support.design.widget.TabLayout.Tab setText(int);
+ field public static final int INVALID_POSITION = -1; // 0xffffffff
+ }
+
+ public static class TabLayout.TabLayoutOnPageChangeListener implements android.support.v4.view.ViewPager.OnPageChangeListener {
+ ctor public TabLayout.TabLayoutOnPageChangeListener(android.support.design.widget.TabLayout);
+ method public void onPageScrollStateChanged(int);
+ method public void onPageScrolled(int, float, int);
+ method public void onPageSelected(int);
+ }
+
+ public static class TabLayout.ViewPagerOnTabSelectedListener implements android.support.design.widget.TabLayout.OnTabSelectedListener {
+ ctor public TabLayout.ViewPagerOnTabSelectedListener(android.support.v4.view.ViewPager);
+ method public void onTabReselected(android.support.design.widget.TabLayout.Tab);
+ method public void onTabSelected(android.support.design.widget.TabLayout.Tab);
+ method public void onTabUnselected(android.support.design.widget.TabLayout.Tab);
+ }
+
+ public class TextInputEditText extends android.support.v7.widget.AppCompatEditText {
+ ctor public TextInputEditText(android.content.Context);
+ ctor public TextInputEditText(android.content.Context, android.util.AttributeSet);
+ ctor public TextInputEditText(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public class TextInputLayout extends android.widget.LinearLayout {
+ ctor public TextInputLayout(android.content.Context);
+ ctor public TextInputLayout(android.content.Context, android.util.AttributeSet);
+ ctor public TextInputLayout(android.content.Context, android.util.AttributeSet, int);
+ method public int getCounterMaxLength();
+ method public android.widget.EditText getEditText();
+ method public java.lang.CharSequence getError();
+ method public java.lang.CharSequence getHint();
+ method public java.lang.CharSequence getPasswordVisibilityToggleContentDescription();
+ method public android.graphics.drawable.Drawable getPasswordVisibilityToggleDrawable();
+ method public android.graphics.Typeface getTypeface();
+ method public boolean isCounterEnabled();
+ method public boolean isErrorEnabled();
+ method public boolean isHintAnimationEnabled();
+ method public boolean isHintEnabled();
+ method public boolean isPasswordVisibilityToggleEnabled();
+ method public android.os.Parcelable onSaveInstanceState();
+ method public void setCounterEnabled(boolean);
+ method public void setCounterMaxLength(int);
+ method public void setError(java.lang.CharSequence);
+ method public void setErrorEnabled(boolean);
+ method public void setErrorTextAppearance(int);
+ method public void setHint(java.lang.CharSequence);
+ method public void setHintAnimationEnabled(boolean);
+ method public void setHintEnabled(boolean);
+ method public void setHintTextAppearance(int);
+ method public void setPasswordVisibilityToggleContentDescription(int);
+ method public void setPasswordVisibilityToggleContentDescription(java.lang.CharSequence);
+ method public void setPasswordVisibilityToggleDrawable(int);
+ method public void setPasswordVisibilityToggleDrawable(android.graphics.drawable.Drawable);
+ method public void setPasswordVisibilityToggleEnabled(boolean);
+ method public void setPasswordVisibilityToggleTintList(android.content.res.ColorStateList);
+ method public void setPasswordVisibilityToggleTintMode(android.graphics.PorterDuff.Mode);
+ method public void setTypeface(android.graphics.Typeface);
+ }
+
+ class ViewOffsetBehavior<V extends android.view.View> extends android.support.design.widget.CoordinatorLayout.Behavior {
+ ctor public ViewOffsetBehavior();
+ ctor public ViewOffsetBehavior(android.content.Context, android.util.AttributeSet);
+ method public int getLeftAndRightOffset();
+ method public int getTopAndBottomOffset();
+ method protected void layoutChild(android.support.design.widget.CoordinatorLayout, V, int);
+ method public boolean setLeftAndRightOffset(int);
+ method public boolean setTopAndBottomOffset(int);
+ }
+
+ class VisibilityAwareImageButton extends android.widget.ImageButton {
+ ctor public VisibilityAwareImageButton(android.content.Context);
+ ctor public VisibilityAwareImageButton(android.content.Context, android.util.AttributeSet);
+ ctor public VisibilityAwareImageButton(android.content.Context, android.util.AttributeSet, int);
+ }
+
+}
+
+package android.support.graphics.drawable {
+
+ public class AnimatedVectorDrawableCompat extends android.support.graphics.drawable.VectorDrawableCommon {
+ method public static android.support.graphics.drawable.AnimatedVectorDrawableCompat create(android.content.Context, int);
+ method public static android.support.graphics.drawable.AnimatedVectorDrawableCompat createFromXmlInner(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public void draw(android.graphics.Canvas);
+ method public int getOpacity();
+ method public boolean isRunning();
+ method public void setAlpha(int);
+ method public void setColorFilter(android.graphics.ColorFilter);
+ method public void start();
+ method public void stop();
+ }
+
+ abstract class VectorDrawableCommon extends android.graphics.drawable.Drawable {
+ }
+
+ public class VectorDrawableCompat extends android.support.graphics.drawable.VectorDrawableCommon {
+ method public static android.support.graphics.drawable.VectorDrawableCompat create(android.content.res.Resources, int, android.content.res.Resources.Theme);
+ method public static android.support.graphics.drawable.VectorDrawableCompat createFromXmlInner(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public void draw(android.graphics.Canvas);
+ method public int getOpacity();
+ method public void setAlpha(int);
+ method public void setColorFilter(android.graphics.ColorFilter);
+ }
+
+}
+
+package android.support.media {
+
+ public class ExifInterface {
+ ctor public ExifInterface(java.lang.String) throws java.io.IOException;
+ ctor public ExifInterface(java.io.InputStream) throws java.io.IOException;
+ method public double getAltitude(double);
+ method public java.lang.String getAttribute(java.lang.String);
+ method public double getAttributeDouble(java.lang.String, double);
+ method public int getAttributeInt(java.lang.String, int);
+ method public deprecated boolean getLatLong(float[]);
+ method public double[] getLatLong();
+ method public byte[] getThumbnail();
+ method public android.graphics.Bitmap getThumbnailBitmap();
+ method public byte[] getThumbnailBytes();
+ method public long[] getThumbnailRange();
+ method public boolean hasThumbnail();
+ method public boolean isThumbnailCompressed();
+ method public void saveAttributes() throws java.io.IOException;
+ method public void setAttribute(java.lang.String, java.lang.String);
+ method public void setLatLong(double, double);
+ field public static final int ORIENTATION_FLIP_HORIZONTAL = 2; // 0x2
+ field public static final int ORIENTATION_FLIP_VERTICAL = 4; // 0x4
+ field public static final int ORIENTATION_NORMAL = 1; // 0x1
+ field public static final int ORIENTATION_ROTATE_180 = 3; // 0x3
+ field public static final int ORIENTATION_ROTATE_270 = 8; // 0x8
+ field public static final int ORIENTATION_ROTATE_90 = 6; // 0x6
+ field public static final int ORIENTATION_TRANSPOSE = 5; // 0x5
+ field public static final int ORIENTATION_TRANSVERSE = 7; // 0x7
+ field public static final int ORIENTATION_UNDEFINED = 0; // 0x0
+ field public static final java.lang.String TAG_APERTURE_VALUE = "ApertureValue";
+ field public static final java.lang.String TAG_ARTIST = "Artist";
+ field public static final java.lang.String TAG_BITS_PER_SAMPLE = "BitsPerSample";
+ field public static final java.lang.String TAG_BRIGHTNESS_VALUE = "BrightnessValue";
+ field public static final java.lang.String TAG_CFA_PATTERN = "CFAPattern";
+ field public static final java.lang.String TAG_COLOR_SPACE = "ColorSpace";
+ field public static final java.lang.String TAG_COMPONENTS_CONFIGURATION = "ComponentsConfiguration";
+ field public static final java.lang.String TAG_COMPRESSED_BITS_PER_PIXEL = "CompressedBitsPerPixel";
+ field public static final java.lang.String TAG_COMPRESSION = "Compression";
+ field public static final java.lang.String TAG_CONTRAST = "Contrast";
+ field public static final java.lang.String TAG_COPYRIGHT = "Copyright";
+ field public static final java.lang.String TAG_CUSTOM_RENDERED = "CustomRendered";
+ field public static final java.lang.String TAG_DATETIME = "DateTime";
+ field public static final java.lang.String TAG_DATETIME_DIGITIZED = "DateTimeDigitized";
+ field public static final java.lang.String TAG_DATETIME_ORIGINAL = "DateTimeOriginal";
+ field public static final java.lang.String TAG_DEFAULT_CROP_SIZE = "DefaultCropSize";
+ field public static final java.lang.String TAG_DEVICE_SETTING_DESCRIPTION = "DeviceSettingDescription";
+ field public static final java.lang.String TAG_DIGITAL_ZOOM_RATIO = "DigitalZoomRatio";
+ field public static final java.lang.String TAG_DNG_VERSION = "DNGVersion";
+ field public static final java.lang.String TAG_EXIF_VERSION = "ExifVersion";
+ field public static final java.lang.String TAG_EXPOSURE_BIAS_VALUE = "ExposureBiasValue";
+ field public static final java.lang.String TAG_EXPOSURE_INDEX = "ExposureIndex";
+ field public static final java.lang.String TAG_EXPOSURE_MODE = "ExposureMode";
+ field public static final java.lang.String TAG_EXPOSURE_PROGRAM = "ExposureProgram";
+ field public static final java.lang.String TAG_EXPOSURE_TIME = "ExposureTime";
+ field public static final java.lang.String TAG_FILE_SOURCE = "FileSource";
+ field public static final java.lang.String TAG_FLASH = "Flash";
+ field public static final java.lang.String TAG_FLASHPIX_VERSION = "FlashpixVersion";
+ field public static final java.lang.String TAG_FLASH_ENERGY = "FlashEnergy";
+ field public static final java.lang.String TAG_FOCAL_LENGTH = "FocalLength";
+ field public static final java.lang.String TAG_FOCAL_LENGTH_IN_35MM_FILM = "FocalLengthIn35mmFilm";
+ field public static final java.lang.String TAG_FOCAL_PLANE_RESOLUTION_UNIT = "FocalPlaneResolutionUnit";
+ field public static final java.lang.String TAG_FOCAL_PLANE_X_RESOLUTION = "FocalPlaneXResolution";
+ field public static final java.lang.String TAG_FOCAL_PLANE_Y_RESOLUTION = "FocalPlaneYResolution";
+ field public static final java.lang.String TAG_F_NUMBER = "FNumber";
+ field public static final java.lang.String TAG_GAIN_CONTROL = "GainControl";
+ field public static final java.lang.String TAG_GPS_ALTITUDE = "GPSAltitude";
+ field public static final java.lang.String TAG_GPS_ALTITUDE_REF = "GPSAltitudeRef";
+ field public static final java.lang.String TAG_GPS_AREA_INFORMATION = "GPSAreaInformation";
+ field public static final java.lang.String TAG_GPS_DATESTAMP = "GPSDateStamp";
+ field public static final java.lang.String TAG_GPS_DEST_BEARING = "GPSDestBearing";
+ field public static final java.lang.String TAG_GPS_DEST_BEARING_REF = "GPSDestBearingRef";
+ field public static final java.lang.String TAG_GPS_DEST_DISTANCE = "GPSDestDistance";
+ field public static final java.lang.String TAG_GPS_DEST_DISTANCE_REF = "GPSDestDistanceRef";
+ field public static final java.lang.String TAG_GPS_DEST_LATITUDE = "GPSDestLatitude";
+ field public static final java.lang.String TAG_GPS_DEST_LATITUDE_REF = "GPSDestLatitudeRef";
+ field public static final java.lang.String TAG_GPS_DEST_LONGITUDE = "GPSDestLongitude";
+ field public static final java.lang.String TAG_GPS_DEST_LONGITUDE_REF = "GPSDestLongitudeRef";
+ field public static final java.lang.String TAG_GPS_DIFFERENTIAL = "GPSDifferential";
+ field public static final java.lang.String TAG_GPS_DOP = "GPSDOP";
+ field public static final java.lang.String TAG_GPS_IMG_DIRECTION = "GPSImgDirection";
+ field public static final java.lang.String TAG_GPS_IMG_DIRECTION_REF = "GPSImgDirectionRef";
+ field public static final java.lang.String TAG_GPS_LATITUDE = "GPSLatitude";
+ field public static final java.lang.String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef";
+ field public static final java.lang.String TAG_GPS_LONGITUDE = "GPSLongitude";
+ field public static final java.lang.String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef";
+ field public static final java.lang.String TAG_GPS_MAP_DATUM = "GPSMapDatum";
+ field public static final java.lang.String TAG_GPS_MEASURE_MODE = "GPSMeasureMode";
+ field public static final java.lang.String TAG_GPS_PROCESSING_METHOD = "GPSProcessingMethod";
+ field public static final java.lang.String TAG_GPS_SATELLITES = "GPSSatellites";
+ field public static final java.lang.String TAG_GPS_SPEED = "GPSSpeed";
+ field public static final java.lang.String TAG_GPS_SPEED_REF = "GPSSpeedRef";
+ field public static final java.lang.String TAG_GPS_STATUS = "GPSStatus";
+ field public static final java.lang.String TAG_GPS_TIMESTAMP = "GPSTimeStamp";
+ field public static final java.lang.String TAG_GPS_TRACK = "GPSTrack";
+ field public static final java.lang.String TAG_GPS_TRACK_REF = "GPSTrackRef";
+ field public static final java.lang.String TAG_GPS_VERSION_ID = "GPSVersionID";
+ field public static final java.lang.String TAG_IMAGE_DESCRIPTION = "ImageDescription";
+ field public static final java.lang.String TAG_IMAGE_LENGTH = "ImageLength";
+ field public static final java.lang.String TAG_IMAGE_UNIQUE_ID = "ImageUniqueID";
+ field public static final java.lang.String TAG_IMAGE_WIDTH = "ImageWidth";
+ field public static final java.lang.String TAG_INTEROPERABILITY_INDEX = "InteroperabilityIndex";
+ field public static final java.lang.String TAG_ISO_SPEED_RATINGS = "ISOSpeedRatings";
+ field public static final java.lang.String TAG_JPEG_INTERCHANGE_FORMAT = "JPEGInterchangeFormat";
+ field public static final java.lang.String TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = "JPEGInterchangeFormatLength";
+ field public static final java.lang.String TAG_LIGHT_SOURCE = "LightSource";
+ field public static final java.lang.String TAG_MAKE = "Make";
+ field public static final java.lang.String TAG_MAKER_NOTE = "MakerNote";
+ field public static final java.lang.String TAG_MAX_APERTURE_VALUE = "MaxApertureValue";
+ field public static final java.lang.String TAG_METERING_MODE = "MeteringMode";
+ field public static final java.lang.String TAG_MODEL = "Model";
+ field public static final java.lang.String TAG_NEW_SUBFILE_TYPE = "NewSubfileType";
+ field public static final java.lang.String TAG_OECF = "OECF";
+ field public static final java.lang.String TAG_ORF_ASPECT_FRAME = "AspectFrame";
+ field public static final java.lang.String TAG_ORF_PREVIEW_IMAGE_LENGTH = "PreviewImageLength";
+ field public static final java.lang.String TAG_ORF_PREVIEW_IMAGE_START = "PreviewImageStart";
+ field public static final java.lang.String TAG_ORF_THUMBNAIL_IMAGE = "ThumbnailImage";
+ field public static final java.lang.String TAG_ORIENTATION = "Orientation";
+ field public static final java.lang.String TAG_PHOTOMETRIC_INTERPRETATION = "PhotometricInterpretation";
+ field public static final java.lang.String TAG_PIXEL_X_DIMENSION = "PixelXDimension";
+ field public static final java.lang.String TAG_PIXEL_Y_DIMENSION = "PixelYDimension";
+ field public static final java.lang.String TAG_PLANAR_CONFIGURATION = "PlanarConfiguration";
+ field public static final java.lang.String TAG_PRIMARY_CHROMATICITIES = "PrimaryChromaticities";
+ field public static final java.lang.String TAG_REFERENCE_BLACK_WHITE = "ReferenceBlackWhite";
+ field public static final java.lang.String TAG_RELATED_SOUND_FILE = "RelatedSoundFile";
+ field public static final java.lang.String TAG_RESOLUTION_UNIT = "ResolutionUnit";
+ field public static final java.lang.String TAG_ROWS_PER_STRIP = "RowsPerStrip";
+ field public static final java.lang.String TAG_RW2_ISO = "ISO";
+ field public static final java.lang.String TAG_RW2_JPG_FROM_RAW = "JpgFromRaw";
+ field public static final java.lang.String TAG_RW2_SENSOR_BOTTOM_BORDER = "SensorBottomBorder";
+ field public static final java.lang.String TAG_RW2_SENSOR_LEFT_BORDER = "SensorLeftBorder";
+ field public static final java.lang.String TAG_RW2_SENSOR_RIGHT_BORDER = "SensorRightBorder";
+ field public static final java.lang.String TAG_RW2_SENSOR_TOP_BORDER = "SensorTopBorder";
+ field public static final java.lang.String TAG_SAMPLES_PER_PIXEL = "SamplesPerPixel";
+ field public static final java.lang.String TAG_SATURATION = "Saturation";
+ field public static final java.lang.String TAG_SCENE_CAPTURE_TYPE = "SceneCaptureType";
+ field public static final java.lang.String TAG_SCENE_TYPE = "SceneType";
+ field public static final java.lang.String TAG_SENSING_METHOD = "SensingMethod";
+ field public static final java.lang.String TAG_SHARPNESS = "Sharpness";
+ field public static final java.lang.String TAG_SHUTTER_SPEED_VALUE = "ShutterSpeedValue";
+ field public static final java.lang.String TAG_SOFTWARE = "Software";
+ field public static final java.lang.String TAG_SPATIAL_FREQUENCY_RESPONSE = "SpatialFrequencyResponse";
+ field public static final java.lang.String TAG_SPECTRAL_SENSITIVITY = "SpectralSensitivity";
+ field public static final java.lang.String TAG_STRIP_BYTE_COUNTS = "StripByteCounts";
+ field public static final java.lang.String TAG_STRIP_OFFSETS = "StripOffsets";
+ field public static final java.lang.String TAG_SUBFILE_TYPE = "SubfileType";
+ field public static final java.lang.String TAG_SUBJECT_AREA = "SubjectArea";
+ field public static final java.lang.String TAG_SUBJECT_DISTANCE = "SubjectDistance";
+ field public static final java.lang.String TAG_SUBJECT_DISTANCE_RANGE = "SubjectDistanceRange";
+ field public static final java.lang.String TAG_SUBJECT_LOCATION = "SubjectLocation";
+ field public static final java.lang.String TAG_SUBSEC_TIME = "SubSecTime";
+ field public static final java.lang.String TAG_SUBSEC_TIME_DIGITIZED = "SubSecTimeDigitized";
+ field public static final java.lang.String TAG_SUBSEC_TIME_ORIGINAL = "SubSecTimeOriginal";
+ field public static final java.lang.String TAG_THUMBNAIL_IMAGE_LENGTH = "ThumbnailImageLength";
+ field public static final java.lang.String TAG_THUMBNAIL_IMAGE_WIDTH = "ThumbnailImageWidth";
+ field public static final java.lang.String TAG_TRANSFER_FUNCTION = "TransferFunction";
+ field public static final java.lang.String TAG_USER_COMMENT = "UserComment";
+ field public static final java.lang.String TAG_WHITE_BALANCE = "WhiteBalance";
+ field public static final java.lang.String TAG_WHITE_POINT = "WhitePoint";
+ field public static final java.lang.String TAG_X_RESOLUTION = "XResolution";
+ field public static final java.lang.String TAG_Y_CB_CR_COEFFICIENTS = "YCbCrCoefficients";
+ field public static final java.lang.String TAG_Y_CB_CR_POSITIONING = "YCbCrPositioning";
+ field public static final java.lang.String TAG_Y_CB_CR_SUB_SAMPLING = "YCbCrSubSampling";
+ field public static final java.lang.String TAG_Y_RESOLUTION = "YResolution";
+ field public static final int WHITEBALANCE_AUTO = 0; // 0x0
+ field public static final int WHITEBALANCE_MANUAL = 1; // 0x1
+ }
+
+}
+
+package android.support.media.instantvideo.preload {
+
+ public class InstantVideoPreloadManager {
+ method public void clearCache();
+ method public static synchronized android.support.media.instantvideo.preload.InstantVideoPreloadManager getInstance(android.content.Context);
+ method public void preload(android.net.Uri);
+ method public void setMaxCacheSize(int);
+ method public void setMaxPreloadVideoCount(int);
+ }
+
+}
+
+package android.support.media.instantvideo.widget {
+
+ public class InstantVideoView extends android.widget.FrameLayout {
+ ctor public InstantVideoView(android.content.Context);
+ ctor public InstantVideoView(android.content.Context, android.util.AttributeSet);
+ ctor public InstantVideoView(android.content.Context, android.util.AttributeSet, int);
+ method public int getCurrentPosition();
+ method public void seekTo(int);
+ method public void setImageDrawable(android.graphics.drawable.Drawable);
+ method public void setVideoUri(android.net.Uri);
+ method public void start();
+ method public void stop();
+ }
+
+}
+
+package android.support.media.tv {
+
+ public final class Channel {
+ method public static android.support.media.tv.Channel fromCursor(android.database.Cursor);
+ method public int getAppLinkColor();
+ method public android.net.Uri getAppLinkIconUri();
+ method public android.content.Intent getAppLinkIntent() throws java.net.URISyntaxException;
+ method public android.net.Uri getAppLinkIntentUri();
+ method public android.net.Uri getAppLinkPosterArtUri();
+ method public java.lang.String getAppLinkText();
+ method public java.lang.String getChannelLogo();
+ method public java.lang.String getDescription();
+ method public java.lang.String getDisplayName();
+ method public java.lang.String getDisplayNumber();
+ method public long getId();
+ method public java.lang.String getInputId();
+ method public byte[] getInternalProviderDataByteArray();
+ method public java.lang.Long getInternalProviderFlag1();
+ method public java.lang.Long getInternalProviderFlag2();
+ method public java.lang.Long getInternalProviderFlag3();
+ method public java.lang.Long getInternalProviderFlag4();
+ method public java.lang.String getNetworkAffiliation();
+ method public int getOriginalNetworkId();
+ method public java.lang.String getPackageName();
+ method public int getServiceId();
+ method public java.lang.String getServiceType();
+ method public int getTransportStreamId();
+ method public java.lang.String getType();
+ method public java.lang.String getVideoFormat();
+ method public boolean isSearchable();
+ method public android.content.ContentValues toContentValues();
+ }
+
+ public static final class Channel.Builder {
+ ctor public Channel.Builder();
+ ctor public Channel.Builder(android.support.media.tv.Channel);
+ method public android.support.media.tv.Channel build();
+ method public android.support.media.tv.Channel.Builder setAppLinkColor(int);
+ method public android.support.media.tv.Channel.Builder setAppLinkIconUri(android.net.Uri);
+ method public android.support.media.tv.Channel.Builder setAppLinkIntent(android.content.Intent);
+ method public android.support.media.tv.Channel.Builder setAppLinkIntentUri(android.net.Uri);
+ method public android.support.media.tv.Channel.Builder setAppLinkPosterArtUri(android.net.Uri);
+ method public android.support.media.tv.Channel.Builder setAppLinkText(java.lang.String);
+ method public android.support.media.tv.Channel.Builder setChannelLogo(java.lang.String);
+ method public android.support.media.tv.Channel.Builder setDescription(java.lang.String);
+ method public android.support.media.tv.Channel.Builder setDisplayName(java.lang.String);
+ method public android.support.media.tv.Channel.Builder setDisplayNumber(java.lang.String);
+ method public android.support.media.tv.Channel.Builder setInputId(java.lang.String);
+ method public android.support.media.tv.Channel.Builder setInternalProviderData(byte[]);
+ method public android.support.media.tv.Channel.Builder setInternalProviderData(java.lang.String);
+ method public android.support.media.tv.Channel.Builder setInternalProviderFlag1(long);
+ method public android.support.media.tv.Channel.Builder setInternalProviderFlag2(long);
+ method public android.support.media.tv.Channel.Builder setInternalProviderFlag3(long);
+ method public android.support.media.tv.Channel.Builder setInternalProviderFlag4(long);
+ method public android.support.media.tv.Channel.Builder setNetworkAffiliation(java.lang.String);
+ method public android.support.media.tv.Channel.Builder setOriginalNetworkId(int);
+ method public android.support.media.tv.Channel.Builder setPackageName(java.lang.String);
+ method public android.support.media.tv.Channel.Builder setSearchable(boolean);
+ method public android.support.media.tv.Channel.Builder setServiceId(int);
+ method public android.support.media.tv.Channel.Builder setServiceType(java.lang.String);
+ method public android.support.media.tv.Channel.Builder setTransportStreamId(int);
+ method public android.support.media.tv.Channel.Builder setType(java.lang.String);
+ method public android.support.media.tv.Channel.Builder setVideoFormat(java.lang.String);
+ }
+
+ public final class Program implements java.lang.Comparable {
+ method public int compareTo(android.support.media.tv.Program);
+ method public static android.support.media.tv.Program fromCursor(android.database.Cursor);
+ method public android.content.Intent getAppLinkIntent() throws java.net.URISyntaxException;
+ method public android.net.Uri getAppLinkIntentUri();
+ method public java.lang.String[] getAudioLanguages();
+ method public java.lang.String getAuthor();
+ method public java.lang.String getAvailability();
+ method public java.lang.String[] getBroadcastGenres();
+ method public java.lang.String[] getCanonicalGenres();
+ method public long getChannelId();
+ method public android.media.tv.TvContentRating[] getContentRatings();
+ method public java.lang.String getDescription();
+ method public int getDurationMillis();
+ method public long getEndTimeUtcMillis();
+ method public java.lang.String getEpisodeNumber();
+ method public java.lang.String getEpisodeTitle();
+ method public long getId();
+ method public int getInteractionCount();
+ method public java.lang.String getInteractionType();
+ method public byte[] getInternalProviderDataByteArray();
+ method public java.lang.Long getInternalProviderFlag1();
+ method public java.lang.Long getInternalProviderFlag2();
+ method public java.lang.Long getInternalProviderFlag3();
+ method public java.lang.Long getInternalProviderFlag4();
+ method public java.lang.String getInternalProviderId();
+ method public int getItemCount();
+ method public int getLastPlaybackPositionMillis();
+ method public android.net.Uri getLogoUri();
+ method public java.lang.String getLongDescription();
+ method public java.lang.String getOfferPrice();
+ method public java.lang.String getPosterArtAspectRatio();
+ method public android.net.Uri getPosterArtUri();
+ method public android.net.Uri getPreviewVideoUri();
+ method public java.lang.String getReleaseDate();
+ method public java.lang.String getReviewRating();
+ method public java.lang.String getReviewRatingStyle();
+ method public java.lang.String getSeasonNumber();
+ method public java.lang.String getSeasonTitle();
+ method public long getStartTimeUtcMillis();
+ method public java.lang.String getStartingPrice();
+ method public java.lang.String getThumbnailAspectRatio();
+ method public android.net.Uri getThumbnailUri();
+ method public java.lang.String getTitle();
+ method public java.lang.String getType();
+ method public int getVideoHeight();
+ method public int getVideoWidth();
+ method public java.lang.String getWatchNextType();
+ method public int getWeight();
+ method public boolean isLive();
+ method public boolean isRecordingProhibited();
+ method public boolean isSearchable();
+ method public android.content.ContentValues toContentValues();
+ }
+
+ public static final class Program.Builder {
+ ctor public Program.Builder();
+ ctor public Program.Builder(android.support.media.tv.Program);
+ method public android.support.media.tv.Program build();
+ method public android.support.media.tv.Program.Builder setAppLinkIntent(android.content.Intent);
+ method public android.support.media.tv.Program.Builder setAppLinkIntentUri(android.net.Uri);
+ method public android.support.media.tv.Program.Builder setAudioLanguages(java.lang.String[]);
+ method public android.support.media.tv.Program.Builder setAuthor(java.lang.String);
+ method public android.support.media.tv.Program.Builder setAvailability(java.lang.String);
+ method public android.support.media.tv.Program.Builder setBroadcastGenres(java.lang.String[]);
+ method public android.support.media.tv.Program.Builder setCanonicalGenres(java.lang.String[]);
+ method public android.support.media.tv.Program.Builder setChannelId(long);
+ method public android.support.media.tv.Program.Builder setContentRatings(android.media.tv.TvContentRating[]);
+ method public android.support.media.tv.Program.Builder setDescription(java.lang.String);
+ method public android.support.media.tv.Program.Builder setDurationMillis(int);
+ method public android.support.media.tv.Program.Builder setEndTimeUtcMillis(long);
+ method public android.support.media.tv.Program.Builder setEpisodeNumber(int);
+ method public android.support.media.tv.Program.Builder setEpisodeNumber(java.lang.String, int);
+ method public android.support.media.tv.Program.Builder setEpisodeTitle(java.lang.String);
+ method public android.support.media.tv.Program.Builder setId(long);
+ method public android.support.media.tv.Program.Builder setInteractionCount(int);
+ method public android.support.media.tv.Program.Builder setInteractionType(java.lang.String);
+ method public android.support.media.tv.Program.Builder setInternalProviderData(byte[]);
+ method public android.support.media.tv.Program.Builder setInternalProviderFlag1(long);
+ method public android.support.media.tv.Program.Builder setInternalProviderFlag2(long);
+ method public android.support.media.tv.Program.Builder setInternalProviderFlag3(long);
+ method public android.support.media.tv.Program.Builder setInternalProviderFlag4(long);
+ method public android.support.media.tv.Program.Builder setInternalProviderId(java.lang.String);
+ method public android.support.media.tv.Program.Builder setItemCount(int);
+ method public android.support.media.tv.Program.Builder setLastPlaybackPositionMillis(int);
+ method public android.support.media.tv.Program.Builder setLive(boolean);
+ method public android.support.media.tv.Program.Builder setLogoUri(android.net.Uri);
+ method public android.support.media.tv.Program.Builder setLongDescription(java.lang.String);
+ method public android.support.media.tv.Program.Builder setOfferPrice(java.lang.String);
+ method public android.support.media.tv.Program.Builder setPosterArtAspectRatio(java.lang.String);
+ method public android.support.media.tv.Program.Builder setPosterArtUri(android.net.Uri);
+ method public android.support.media.tv.Program.Builder setPreviewVideoUri(android.net.Uri);
+ method public android.support.media.tv.Program.Builder setRecordingProhibited(boolean);
+ method public android.support.media.tv.Program.Builder setReleaseDate(java.lang.String);
+ method public android.support.media.tv.Program.Builder setReleaseDate(java.util.Date);
+ method public android.support.media.tv.Program.Builder setReviewRating(java.lang.String);
+ method public android.support.media.tv.Program.Builder setReviewRatingStyle(java.lang.String);
+ method public android.support.media.tv.Program.Builder setSearchable(boolean);
+ method public android.support.media.tv.Program.Builder setSeasonNumber(int);
+ method public android.support.media.tv.Program.Builder setSeasonNumber(java.lang.String, int);
+ method public android.support.media.tv.Program.Builder setSeasonTitle(java.lang.String);
+ method public android.support.media.tv.Program.Builder setStartTimeUtcMillis(long);
+ method public android.support.media.tv.Program.Builder setStartingPrice(java.lang.String);
+ method public android.support.media.tv.Program.Builder setThumbnailAspectRatio(java.lang.String);
+ method public android.support.media.tv.Program.Builder setThumbnailUri(android.net.Uri);
+ method public android.support.media.tv.Program.Builder setTitle(java.lang.String);
+ method public android.support.media.tv.Program.Builder setType(java.lang.String);
+ method public android.support.media.tv.Program.Builder setVideoHeight(int);
+ method public android.support.media.tv.Program.Builder setVideoWidth(int);
+ method public android.support.media.tv.Program.Builder setWatchNextType(java.lang.String);
+ method public android.support.media.tv.Program.Builder setWeight(int);
+ }
+
+ public final class TvContractCompat {
+ method public static android.net.Uri buildChannelLogoUri(long);
+ method public static android.net.Uri buildChannelLogoUri(android.net.Uri);
+ method public static android.net.Uri buildChannelUri(long);
+ method public static android.net.Uri buildChannelUriForPassthroughInput(java.lang.String);
+ method public static android.net.Uri buildChannelsUriForInput(java.lang.String);
+ method public static java.lang.String buildInputId(android.content.ComponentName);
+ method public static android.net.Uri buildProgramUri(long);
+ method public static android.net.Uri buildProgramsUriForChannel(long);
+ method public static android.net.Uri buildProgramsUriForChannel(android.net.Uri);
+ method public static android.net.Uri buildProgramsUriForChannel(long, long, long);
+ method public static android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
+ method public static android.net.Uri buildRecordedProgramUri(long);
+ method public static boolean isChannelUri(android.net.Uri);
+ method public static boolean isChannelUriForPassthroughInput(android.net.Uri);
+ method public static boolean isChannelUriForTunerInput(android.net.Uri);
+ method public static boolean isProgramUri(android.net.Uri);
+ field public static final java.lang.String AUTHORITY = "android.media.tv";
+ }
+
+ public static abstract interface TvContractCompat.BaseTvColumns {
+ field public static final java.lang.String COLUMN_PACKAGE_NAME = "package_name";
+ }
+
+ public static final class TvContractCompat.Channels implements android.support.media.tv.TvContractCompat.BaseTvColumns {
+ method public static java.lang.String getVideoResolution(java.lang.String);
+ field public static final java.lang.String COLUMN_APP_LINK_COLOR = "app_link_color";
+ field public static final java.lang.String COLUMN_APP_LINK_ICON_URI = "app_link_icon_uri";
+ field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
+ field public static final java.lang.String COLUMN_APP_LINK_POSTER_ART_URI = "app_link_poster_art_uri";
+ field public static final java.lang.String COLUMN_APP_LINK_TEXT = "app_link_text";
+ field public static final java.lang.String COLUMN_DESCRIPTION = "description";
+ field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name";
+ field public static final java.lang.String COLUMN_DISPLAY_NUMBER = "display_number";
+ field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+ field public static final java.lang.String COLUMN_NETWORK_AFFILIATION = "network_affiliation";
+ field public static final java.lang.String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id";
+ field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+ field public static final java.lang.String COLUMN_SERVICE_ID = "service_id";
+ field public static final java.lang.String COLUMN_SERVICE_TYPE = "service_type";
+ field public static final java.lang.String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id";
+ field public static final java.lang.String COLUMN_TYPE = "type";
+ field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+ field public static final java.lang.String COLUMN_VIDEO_FORMAT = "video_format";
+ field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel";
+ field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/channel";
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String SERVICE_TYPE_AUDIO = "SERVICE_TYPE_AUDIO";
+ field public static final java.lang.String SERVICE_TYPE_AUDIO_VIDEO = "SERVICE_TYPE_AUDIO_VIDEO";
+ field public static final java.lang.String SERVICE_TYPE_OTHER = "SERVICE_TYPE_OTHER";
+ field public static final java.lang.String TYPE_1SEG = "TYPE_1SEG";
+ field public static final java.lang.String TYPE_ATSC_C = "TYPE_ATSC_C";
+ field public static final java.lang.String TYPE_ATSC_M_H = "TYPE_ATSC_M_H";
+ field public static final java.lang.String TYPE_ATSC_T = "TYPE_ATSC_T";
+ field public static final java.lang.String TYPE_CMMB = "TYPE_CMMB";
+ field public static final java.lang.String TYPE_DTMB = "TYPE_DTMB";
+ field public static final java.lang.String TYPE_DVB_C = "TYPE_DVB_C";
+ field public static final java.lang.String TYPE_DVB_C2 = "TYPE_DVB_C2";
+ field public static final java.lang.String TYPE_DVB_H = "TYPE_DVB_H";
+ field public static final java.lang.String TYPE_DVB_S = "TYPE_DVB_S";
+ field public static final java.lang.String TYPE_DVB_S2 = "TYPE_DVB_S2";
+ field public static final java.lang.String TYPE_DVB_SH = "TYPE_DVB_SH";
+ field public static final java.lang.String TYPE_DVB_T = "TYPE_DVB_T";
+ field public static final java.lang.String TYPE_DVB_T2 = "TYPE_DVB_T2";
+ field public static final java.lang.String TYPE_ISDB_C = "TYPE_ISDB_C";
+ field public static final java.lang.String TYPE_ISDB_S = "TYPE_ISDB_S";
+ field public static final java.lang.String TYPE_ISDB_T = "TYPE_ISDB_T";
+ field public static final java.lang.String TYPE_ISDB_TB = "TYPE_ISDB_TB";
+ field public static final java.lang.String TYPE_NTSC = "TYPE_NTSC";
+ field public static final java.lang.String TYPE_OTHER = "TYPE_OTHER";
+ field public static final java.lang.String TYPE_PAL = "TYPE_PAL";
+ field public static final java.lang.String TYPE_PREVIEW = "TYPE_PREVIEW";
+ field public static final java.lang.String TYPE_SECAM = "TYPE_SECAM";
+ field public static final java.lang.String TYPE_S_DMB = "TYPE_S_DMB";
+ field public static final java.lang.String TYPE_T_DMB = "TYPE_T_DMB";
+ field public static final java.lang.String VIDEO_FORMAT_1080I = "VIDEO_FORMAT_1080I";
+ field public static final java.lang.String VIDEO_FORMAT_1080P = "VIDEO_FORMAT_1080P";
+ field public static final java.lang.String VIDEO_FORMAT_2160P = "VIDEO_FORMAT_2160P";
+ field public static final java.lang.String VIDEO_FORMAT_240P = "VIDEO_FORMAT_240P";
+ field public static final java.lang.String VIDEO_FORMAT_360P = "VIDEO_FORMAT_360P";
+ field public static final java.lang.String VIDEO_FORMAT_4320P = "VIDEO_FORMAT_4320P";
+ field public static final java.lang.String VIDEO_FORMAT_480I = "VIDEO_FORMAT_480I";
+ field public static final java.lang.String VIDEO_FORMAT_480P = "VIDEO_FORMAT_480P";
+ field public static final java.lang.String VIDEO_FORMAT_576I = "VIDEO_FORMAT_576I";
+ field public static final java.lang.String VIDEO_FORMAT_576P = "VIDEO_FORMAT_576P";
+ field public static final java.lang.String VIDEO_FORMAT_720P = "VIDEO_FORMAT_720P";
+ field public static final java.lang.String VIDEO_RESOLUTION_ED = "VIDEO_RESOLUTION_ED";
+ field public static final java.lang.String VIDEO_RESOLUTION_FHD = "VIDEO_RESOLUTION_FHD";
+ field public static final java.lang.String VIDEO_RESOLUTION_HD = "VIDEO_RESOLUTION_HD";
+ field public static final java.lang.String VIDEO_RESOLUTION_SD = "VIDEO_RESOLUTION_SD";
+ field public static final java.lang.String VIDEO_RESOLUTION_UHD = "VIDEO_RESOLUTION_UHD";
+ }
+
+ public static final class TvContractCompat.Channels.Logo {
+ field public static final java.lang.String CONTENT_DIRECTORY = "logo";
+ }
+
+ public static final class TvContractCompat.Programs implements android.support.media.tv.TvContractCompat.BaseTvColumns {
+ field public static final java.lang.String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
+ field public static final java.lang.String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
+ field public static final java.lang.String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
+ field public static final java.lang.String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
+ field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
+ field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
+ field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+ field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
+ field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
+ field public static final java.lang.String COLUMN_AUTHOR = "author";
+ field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
+ field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
+ field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
+ field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
+ field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+ field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
+ field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+ field public static final java.lang.String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
+ field public static final deprecated java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
+ field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
+ field public static final java.lang.String COLUMN_INTERACTION_COUNT = "interaction_count";
+ field public static final java.lang.String COLUMN_INTERACTION_TYPE = "interaction_type";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
+ field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
+ field public static final java.lang.String COLUMN_LAST_PLAYBACK_POSITION_MILLIS = "last_playback_position_millis";
+ field public static final java.lang.String COLUMN_LIVE = "live";
+ field public static final java.lang.String COLUMN_LOGO_URI = "logo_uri";
+ field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+ field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
+ field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
+ field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
+ field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
+ field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
+ field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
+ field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
+ field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
+ field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+ field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+ field public static final deprecated java.lang.String COLUMN_SEASON_NUMBER = "season_number";
+ field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
+ field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+ field public static final java.lang.String COLUMN_STARTING_PRICE = "starting_price";
+ field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+ field public static final java.lang.String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
+ field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+ field public static final java.lang.String COLUMN_TITLE = "title";
+ field public static final java.lang.String COLUMN_TYPE = "type";
+ field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+ field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+ field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
+ field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+ field public static final java.lang.String COLUMN_WEIGHT = "weight";
+ field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
+ field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
+ field public static final java.lang.String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
+ field public static final java.lang.String INTERACTION_TYPE_LIKES = "INTERACTION_TYPE_LIKES";
+ field public static final java.lang.String INTERACTION_TYPE_LISTENS = "INTERACTION_TYPE_LISTENS";
+ field public static final java.lang.String INTERACTION_TYPE_THUMBS = "INTERACTION_TYPE_THUMBS";
+ field public static final java.lang.String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
+ field public static final java.lang.String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
+ field public static final java.lang.String REVIEW_RATING_STYLE_PERCENTAGE = "REVIEW_RATING_STYLE_PERCENTAGE";
+ field public static final java.lang.String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
+ field public static final java.lang.String REVIEW_RATING_STYLE_THUMBS_UP_DOWN = "REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
+ field public static final java.lang.String TYPE_ALBUM = "TYPE_ALBUM";
+ field public static final java.lang.String TYPE_ARTIST = "TYPE_ARTIST";
+ field public static final java.lang.String TYPE_CHANNEL = "TYPE_CHANNEL";
+ field public static final java.lang.String TYPE_CLIP = "TYPE_CLIP";
+ field public static final java.lang.String TYPE_EVENT = "TYPE_EVENT";
+ field public static final java.lang.String TYPE_MOVIE = "TYPE_MOVIE";
+ field public static final java.lang.String TYPE_PLAYLIST = "TYPE_PLAYLIST";
+ field public static final java.lang.String TYPE_STATION = "TYPE_STATION";
+ field public static final java.lang.String TYPE_TRACK = "TYPE_TRACK";
+ field public static final java.lang.String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
+ field public static final java.lang.String TYPE_TV_SEASON = "TYPE_TV_SEASON";
+ field public static final java.lang.String TYPE_TV_SERIES = "TYPE_TV_SERIES";
+ field public static final java.lang.String WATCH_NEXT_TYPE_CONTINUE = "WATCH_NEXT_TYPE_CONTINUE";
+ field public static final java.lang.String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
+ field public static final java.lang.String WATCH_NEXT_TYPE_NEXT = "WATCH_NEXT_TYPE_NEXT";
+ }
+
+ public static final class TvContractCompat.Programs.Genres {
+ method public static java.lang.String[] decode(java.lang.String);
+ method public static java.lang.String encode(java.lang.String...);
+ method public static boolean isCanonical(java.lang.String);
+ field public static final java.lang.String ANIMAL_WILDLIFE = "ANIMAL_WILDLIFE";
+ field public static final java.lang.String ARTS = "ARTS";
+ field public static final java.lang.String COMEDY = "COMEDY";
+ field public static final java.lang.String DRAMA = "DRAMA";
+ field public static final java.lang.String EDUCATION = "EDUCATION";
+ field public static final java.lang.String ENTERTAINMENT = "ENTERTAINMENT";
+ field public static final java.lang.String FAMILY_KIDS = "FAMILY_KIDS";
+ field public static final java.lang.String GAMING = "GAMING";
+ field public static final java.lang.String LIFE_STYLE = "LIFE_STYLE";
+ field public static final java.lang.String MOVIES = "MOVIES";
+ field public static final java.lang.String MUSIC = "MUSIC";
+ field public static final java.lang.String NEWS = "NEWS";
+ field public static final java.lang.String PREMIER = "PREMIER";
+ field public static final java.lang.String SHOPPING = "SHOPPING";
+ field public static final java.lang.String SPORTS = "SPORTS";
+ field public static final java.lang.String TECH_SCIENCE = "TECH_SCIENCE";
+ field public static final java.lang.String TRAVEL = "TRAVEL";
+ }
+
+ public static final class TvContractCompat.RecordedPrograms implements android.support.media.tv.TvContractCompat.BaseTvColumns {
+ field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
+ field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
+ field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
+ field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
+ field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+ field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+ field public static final java.lang.String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
+ field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
+ field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+ field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+ field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
+ field public static final java.lang.String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes";
+ field public static final java.lang.String COLUMN_RECORDING_DATA_URI = "recording_data_uri";
+ field public static final java.lang.String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis";
+ field public static final java.lang.String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS = "recording_expire_time_utc_millis";
+ field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+ field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+ field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
+ field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+ field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+ field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+ field public static final java.lang.String COLUMN_TITLE = "title";
+ field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+ field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+ field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
+ field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program";
+ field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program";
+ field public static final android.net.Uri CONTENT_URI;
+ }
+
+}
+
+package android.support.percent {
+
+ public class PercentFrameLayout extends android.widget.FrameLayout {
+ ctor public PercentFrameLayout(android.content.Context);
+ ctor public PercentFrameLayout(android.content.Context, android.util.AttributeSet);
+ ctor public PercentFrameLayout(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public static class PercentFrameLayout.LayoutParams extends android.widget.FrameLayout.LayoutParams implements android.support.percent.PercentLayoutHelper.PercentLayoutParams {
+ ctor public PercentFrameLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+ ctor public PercentFrameLayout.LayoutParams(int, int);
+ ctor public PercentFrameLayout.LayoutParams(int, int, int);
+ ctor public PercentFrameLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+ ctor public PercentFrameLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ ctor public PercentFrameLayout.LayoutParams(android.widget.FrameLayout.LayoutParams);
+ ctor public PercentFrameLayout.LayoutParams(android.support.percent.PercentFrameLayout.LayoutParams);
+ method public android.support.percent.PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo();
+ }
+
+ public class PercentLayoutHelper {
+ ctor public PercentLayoutHelper(android.view.ViewGroup);
+ method public void adjustChildren(int, int);
+ method public static void fetchWidthAndHeight(android.view.ViewGroup.LayoutParams, android.content.res.TypedArray, int, int);
+ method public static android.support.percent.PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo(android.content.Context, android.util.AttributeSet);
+ method public boolean handleMeasuredStateTooSmall();
+ method public void restoreOriginalParams();
+ }
+
+ public static class PercentLayoutHelper.PercentLayoutInfo {
+ ctor public PercentLayoutHelper.PercentLayoutInfo();
+ method public void fillLayoutParams(android.view.ViewGroup.LayoutParams, int, int);
+ method public deprecated void fillMarginLayoutParams(android.view.ViewGroup.MarginLayoutParams, int, int);
+ method public void fillMarginLayoutParams(android.view.View, android.view.ViewGroup.MarginLayoutParams, int, int);
+ method public void restoreLayoutParams(android.view.ViewGroup.LayoutParams);
+ method public void restoreMarginLayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ field public float aspectRatio;
+ field public float bottomMarginPercent;
+ field public float endMarginPercent;
+ field public float heightPercent;
+ field public float leftMarginPercent;
+ field public float rightMarginPercent;
+ field public float startMarginPercent;
+ field public float topMarginPercent;
+ field public float widthPercent;
+ }
+
+ public static abstract interface PercentLayoutHelper.PercentLayoutParams {
+ method public abstract android.support.percent.PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo();
+ }
+
+ public class PercentRelativeLayout extends android.widget.RelativeLayout {
+ ctor public PercentRelativeLayout(android.content.Context);
+ ctor public PercentRelativeLayout(android.content.Context, android.util.AttributeSet);
+ ctor public PercentRelativeLayout(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public static class PercentRelativeLayout.LayoutParams extends android.widget.RelativeLayout.LayoutParams implements android.support.percent.PercentLayoutHelper.PercentLayoutParams {
+ ctor public PercentRelativeLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+ ctor public PercentRelativeLayout.LayoutParams(int, int);
+ ctor public PercentRelativeLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+ ctor public PercentRelativeLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ method public android.support.percent.PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo();
+ }
+
+}
+
+package android.support.transition {
+
+ public class AutoTransition extends android.support.transition.TransitionSet {
+ ctor public AutoTransition();
+ }
+
+ public class ChangeBounds extends android.support.transition.Transition {
+ ctor public ChangeBounds();
+ method public void captureEndValues(android.support.transition.TransitionValues);
+ method public void captureStartValues(android.support.transition.TransitionValues);
+ method public void setResizeClip(boolean);
+ }
+
+ public class Fade extends android.support.transition.Visibility {
+ ctor public Fade(int);
+ ctor public Fade();
+ field public static final int IN = 1; // 0x1
+ field public static final int OUT = 2; // 0x2
+ }
+
+ public class Scene {
+ ctor public Scene(android.view.ViewGroup);
+ ctor public Scene(android.view.ViewGroup, android.view.View);
+ method public void enter();
+ method public void exit();
+ method public static android.support.transition.Scene getSceneForLayout(android.view.ViewGroup, int, android.content.Context);
+ method public android.view.ViewGroup getSceneRoot();
+ method public void setEnterAction(java.lang.Runnable);
+ method public void setExitAction(java.lang.Runnable);
+ }
+
+ public abstract class Transition {
+ ctor public Transition();
+ method public android.support.transition.Transition addListener(android.support.transition.Transition.TransitionListener);
+ method public android.support.transition.Transition addTarget(android.view.View);
+ method public android.support.transition.Transition addTarget(int);
+ method public android.support.transition.Transition addTarget(java.lang.String);
+ method public android.support.transition.Transition addTarget(java.lang.Class);
+ method public abstract void captureEndValues(android.support.transition.TransitionValues);
+ method public abstract void captureStartValues(android.support.transition.TransitionValues);
+ method public android.support.transition.Transition clone();
+ method public android.animation.Animator createAnimator(android.view.ViewGroup, android.support.transition.TransitionValues, android.support.transition.TransitionValues);
+ method public android.support.transition.Transition excludeChildren(android.view.View, boolean);
+ method public android.support.transition.Transition excludeChildren(int, boolean);
+ method public android.support.transition.Transition excludeChildren(java.lang.Class, boolean);
+ method public android.support.transition.Transition excludeTarget(android.view.View, boolean);
+ method public android.support.transition.Transition excludeTarget(int, boolean);
+ method public android.support.transition.Transition excludeTarget(java.lang.String, boolean);
+ method public android.support.transition.Transition excludeTarget(java.lang.Class, boolean);
+ method public long getDuration();
+ method public android.animation.TimeInterpolator getInterpolator();
+ method public java.lang.String getName();
+ method public long getStartDelay();
+ method public java.util.List<java.lang.Integer> getTargetIds();
+ method public java.util.List<java.lang.String> getTargetNames();
+ method public java.util.List<java.lang.Class> getTargetTypes();
+ method public java.util.List<android.view.View> getTargets();
+ method public java.lang.String[] getTransitionProperties();
+ method public android.support.transition.TransitionValues getTransitionValues(android.view.View, boolean);
+ method public android.support.transition.Transition removeListener(android.support.transition.Transition.TransitionListener);
+ method public android.support.transition.Transition removeTarget(android.view.View);
+ method public android.support.transition.Transition removeTarget(int);
+ method public android.support.transition.Transition removeTarget(java.lang.String);
+ method public android.support.transition.Transition removeTarget(java.lang.Class);
+ method public android.support.transition.Transition setDuration(long);
+ method public android.support.transition.Transition setInterpolator(android.animation.TimeInterpolator);
+ method public void setMatchOrder(int...);
+ method public android.support.transition.Transition setStartDelay(long);
+ field public static final int MATCH_ID = 3; // 0x3
+ field public static final int MATCH_INSTANCE = 1; // 0x1
+ field public static final int MATCH_ITEM_ID = 4; // 0x4
+ field public static final int MATCH_NAME = 2; // 0x2
+ }
+
+ public static abstract interface Transition.TransitionListener {
+ method public abstract void onTransitionCancel(android.support.transition.Transition);
+ method public abstract void onTransitionEnd(android.support.transition.Transition);
+ method public abstract void onTransitionPause(android.support.transition.Transition);
+ method public abstract void onTransitionResume(android.support.transition.Transition);
+ method public abstract void onTransitionStart(android.support.transition.Transition);
+ }
+
+ public class TransitionManager {
+ ctor public TransitionManager();
+ method public static void beginDelayedTransition(android.view.ViewGroup);
+ method public static void beginDelayedTransition(android.view.ViewGroup, android.support.transition.Transition);
+ method public static void go(android.support.transition.Scene);
+ method public static void go(android.support.transition.Scene, android.support.transition.Transition);
+ method public void setTransition(android.support.transition.Scene, android.support.transition.Transition);
+ method public void setTransition(android.support.transition.Scene, android.support.transition.Scene, android.support.transition.Transition);
+ method public void transitionTo(android.support.transition.Scene);
+ }
+
+ public class TransitionSet extends android.support.transition.Transition {
+ ctor public TransitionSet();
+ method public android.support.transition.TransitionSet addTransition(android.support.transition.Transition);
+ method public void captureEndValues(android.support.transition.TransitionValues);
+ method public void captureStartValues(android.support.transition.TransitionValues);
+ method public int getOrdering();
+ method public android.support.transition.Transition getTransitionAt(int);
+ method public int getTransitionCount();
+ method public android.support.transition.TransitionSet removeTransition(android.support.transition.Transition);
+ method public android.support.transition.TransitionSet setOrdering(int);
+ field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
+ field public static final int ORDERING_TOGETHER = 0; // 0x0
+ }
+
+ public class TransitionValues {
+ ctor public TransitionValues();
+ field public final java.util.Map<java.lang.String, java.lang.Object> values;
+ field public android.view.View view;
+ }
+
+ public abstract class Visibility extends android.support.transition.Transition {
+ ctor public Visibility();
+ method public void captureEndValues(android.support.transition.TransitionValues);
+ method public void captureStartValues(android.support.transition.TransitionValues);
+ method public boolean isVisible(android.support.transition.TransitionValues);
+ method public android.animation.Animator onAppear(android.view.ViewGroup, android.support.transition.TransitionValues, int, android.support.transition.TransitionValues, int);
+ method public android.animation.Animator onDisappear(android.view.ViewGroup, android.support.transition.TransitionValues, int, android.support.transition.TransitionValues, int);
+ }
+
+}
+
+package android.support.v13.app {
+
+ public class ActivityCompat extends android.support.v4.app.ActivityCompat {
+ ctor protected ActivityCompat();
+ method public static android.support.v13.view.DragAndDropPermissionsCompat requestDragAndDropPermissions(android.app.Activity, android.view.DragEvent);
+ }
+
+ public class FragmentCompat {
+ ctor public FragmentCompat();
+ method public static void requestPermissions(android.app.Fragment, java.lang.String[], int);
+ method public static void setMenuVisibility(android.app.Fragment, boolean);
+ method public static void setUserVisibleHint(android.app.Fragment, boolean);
+ method public static boolean shouldShowRequestPermissionRationale(android.app.Fragment, java.lang.String);
+ }
+
+ public static abstract interface FragmentCompat.OnRequestPermissionsResultCallback {
+ method public abstract void onRequestPermissionsResult(int, java.lang.String[], int[]);
+ }
+
+ public abstract class FragmentPagerAdapter extends android.support.v4.view.PagerAdapter {
+ ctor public FragmentPagerAdapter(android.app.FragmentManager);
+ method public abstract android.app.Fragment getItem(int);
+ method public long getItemId(int);
+ method public boolean isViewFromObject(android.view.View, java.lang.Object);
+ }
+
+ public abstract class FragmentStatePagerAdapter extends android.support.v4.view.PagerAdapter {
+ ctor public FragmentStatePagerAdapter(android.app.FragmentManager);
+ method public abstract android.app.Fragment getItem(int);
+ method public boolean isViewFromObject(android.view.View, java.lang.Object);
+ }
+
+ public class FragmentTabHost extends android.widget.TabHost implements android.widget.TabHost.OnTabChangeListener {
+ ctor public FragmentTabHost(android.content.Context);
+ ctor public FragmentTabHost(android.content.Context, android.util.AttributeSet);
+ method public void addTab(android.widget.TabHost.TabSpec, java.lang.Class<?>, android.os.Bundle);
+ method public void onTabChanged(java.lang.String);
+ method public void setup(android.content.Context, android.app.FragmentManager);
+ method public void setup(android.content.Context, android.app.FragmentManager, int);
+ }
+
+}
+
+package android.support.v13.view {
+
+ public final class DragAndDropPermissionsCompat {
+ method public void release();
+ }
+
+ public class DragStartHelper {
+ ctor public DragStartHelper(android.view.View, android.support.v13.view.DragStartHelper.OnDragStartListener);
+ method public void attach();
+ method public void detach();
+ method public void getTouchPosition(android.graphics.Point);
+ method public boolean onLongClick(android.view.View);
+ method public boolean onTouch(android.view.View, android.view.MotionEvent);
+ }
+
+ public static abstract interface DragStartHelper.OnDragStartListener {
+ method public abstract boolean onDragStart(android.view.View, android.support.v13.view.DragStartHelper);
+ }
+
+ public class ViewCompat extends android.support.v4.view.ViewCompat {
+ method public static void cancelDragAndDrop(android.view.View);
+ method public static boolean startDragAndDrop(android.view.View, android.content.ClipData, android.view.View.DragShadowBuilder, java.lang.Object, int);
+ method public static void updateDragShadow(android.view.View, android.view.View.DragShadowBuilder);
+ }
+
+}
+
+package android.support.v13.view.inputmethod {
+
+ public final class EditorInfoCompat {
+ ctor public EditorInfoCompat();
+ method public static java.lang.String[] getContentMimeTypes(android.view.inputmethod.EditorInfo);
+ method public static void setContentMimeTypes(android.view.inputmethod.EditorInfo, java.lang.String[]);
+ field public static final int IME_FLAG_FORCE_ASCII = -2147483648; // 0x80000000
+ field public static final int IME_FLAG_NO_PERSONALIZED_LEARNING = 16777216; // 0x1000000
+ }
+
+ public final class InputConnectionCompat {
+ ctor public InputConnectionCompat();
+ method public static boolean commitContent(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, android.support.v13.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle);
+ method public static android.view.inputmethod.InputConnection createWrapper(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, android.support.v13.view.inputmethod.InputConnectionCompat.OnCommitContentListener);
+ field public static int INPUT_CONTENT_GRANT_READ_URI_PERMISSION;
+ }
+
+ public static abstract interface InputConnectionCompat.OnCommitContentListener {
+ method public abstract boolean onCommitContent(android.support.v13.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle);
+ }
+
+ public final class InputContentInfoCompat {
+ ctor public InputContentInfoCompat(android.net.Uri, android.content.ClipDescription, android.net.Uri);
+ method public android.net.Uri getContentUri();
+ method public android.content.ClipDescription getDescription();
+ method public android.net.Uri getLinkUri();
+ method public void releasePermission();
+ method public void requestPermission();
+ method public java.lang.Object unwrap();
+ method public static android.support.v13.view.inputmethod.InputContentInfoCompat wrap(java.lang.Object);
+ }
+
+}
+
+package android.support.v14.preference {
+
+ public class EditTextPreferenceDialogFragment extends android.support.v14.preference.PreferenceDialogFragment {
+ ctor public EditTextPreferenceDialogFragment();
+ method public static android.support.v14.preference.EditTextPreferenceDialogFragment newInstance(java.lang.String);
+ method public void onDialogClosed(boolean);
+ }
+
+ public class ListPreferenceDialogFragment extends android.support.v14.preference.PreferenceDialogFragment {
+ ctor public ListPreferenceDialogFragment();
+ method public static android.support.v14.preference.ListPreferenceDialogFragment newInstance(java.lang.String);
+ method public void onDialogClosed(boolean);
+ }
+
+ public class MultiSelectListPreference extends android.support.v7.preference.DialogPreference {
+ ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet, int);
+ ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet);
+ ctor public MultiSelectListPreference(android.content.Context);
+ method public int findIndexOfValue(java.lang.String);
+ method public java.lang.CharSequence[] getEntries();
+ method public java.lang.CharSequence[] getEntryValues();
+ method protected boolean[] getSelectedItems();
+ method public java.util.Set<java.lang.String> getValues();
+ method public void setEntries(java.lang.CharSequence[]);
+ method public void setEntries(int);
+ method public void setEntryValues(java.lang.CharSequence[]);
+ method public void setEntryValues(int);
+ method public void setValues(java.util.Set<java.lang.String>);
+ }
+
+ public class MultiSelectListPreferenceDialogFragment extends android.support.v14.preference.PreferenceDialogFragment {
+ ctor public MultiSelectListPreferenceDialogFragment();
+ method public static android.support.v14.preference.MultiSelectListPreferenceDialogFragment newInstance(java.lang.String);
+ method public void onDialogClosed(boolean);
+ }
+
+ public abstract class PreferenceDialogFragment extends android.app.DialogFragment implements android.content.DialogInterface.OnClickListener {
+ ctor public PreferenceDialogFragment();
+ method public android.support.v7.preference.DialogPreference getPreference();
+ method protected void onBindDialogView(android.view.View);
+ method public void onClick(android.content.DialogInterface, int);
+ method protected android.view.View onCreateDialogView(android.content.Context);
+ method public abstract void onDialogClosed(boolean);
+ method protected void onPrepareDialogBuilder(android.app.AlertDialog.Builder);
+ field protected static final java.lang.String ARG_KEY = "key";
+ }
+
+ public abstract class PreferenceFragment extends android.app.Fragment implements android.support.v7.preference.DialogPreference.TargetFragment android.support.v7.preference.PreferenceManager.OnDisplayPreferenceDialogListener android.support.v7.preference.PreferenceManager.OnNavigateToScreenListener android.support.v7.preference.PreferenceManager.OnPreferenceTreeClickListener {
+ ctor public PreferenceFragment();
+ method public void addPreferencesFromResource(int);
+ method public android.support.v7.preference.Preference findPreference(java.lang.CharSequence);
+ method public final android.support.v7.widget.RecyclerView getListView();
+ method public android.support.v7.preference.PreferenceManager getPreferenceManager();
+ method public android.support.v7.preference.PreferenceScreen getPreferenceScreen();
+ method protected android.support.v7.widget.RecyclerView.Adapter onCreateAdapter(android.support.v7.preference.PreferenceScreen);
+ method public android.support.v7.widget.RecyclerView.LayoutManager onCreateLayoutManager();
+ method public abstract void onCreatePreferences(android.os.Bundle, java.lang.String);
+ method public android.support.v7.widget.RecyclerView onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+ method public void onDisplayPreferenceDialog(android.support.v7.preference.Preference);
+ method public void onNavigateToScreen(android.support.v7.preference.PreferenceScreen);
+ method public boolean onPreferenceTreeClick(android.support.v7.preference.Preference);
+ method public void scrollToPreference(java.lang.String);
+ method public void scrollToPreference(android.support.v7.preference.Preference);
+ method public void setDivider(android.graphics.drawable.Drawable);
+ method public void setDividerHeight(int);
+ method public void setPreferenceScreen(android.support.v7.preference.PreferenceScreen);
+ method public void setPreferencesFromResource(int, java.lang.String);
+ field public static final java.lang.String ARG_PREFERENCE_ROOT = "android.support.v7.preference.PreferenceFragmentCompat.PREFERENCE_ROOT";
+ }
+
+ public static abstract interface PreferenceFragment.OnPreferenceDisplayDialogCallback {
+ method public abstract boolean onPreferenceDisplayDialog(android.support.v14.preference.PreferenceFragment, android.support.v7.preference.Preference);
+ }
+
+ public static abstract interface PreferenceFragment.OnPreferenceStartFragmentCallback {
+ method public abstract boolean onPreferenceStartFragment(android.support.v14.preference.PreferenceFragment, android.support.v7.preference.Preference);
+ }
+
+ public static abstract interface PreferenceFragment.OnPreferenceStartScreenCallback {
+ method public abstract boolean onPreferenceStartScreen(android.support.v14.preference.PreferenceFragment, android.support.v7.preference.PreferenceScreen);
+ }
+
+ public class SwitchPreference extends android.support.v7.preference.TwoStatePreference {
+ ctor public SwitchPreference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public SwitchPreference(android.content.Context, android.util.AttributeSet, int);
+ ctor public SwitchPreference(android.content.Context, android.util.AttributeSet);
+ ctor public SwitchPreference(android.content.Context);
+ method public java.lang.CharSequence getSwitchTextOff();
+ method public java.lang.CharSequence getSwitchTextOn();
+ method public void setSwitchTextOff(java.lang.CharSequence);
+ method public void setSwitchTextOff(int);
+ method public void setSwitchTextOn(java.lang.CharSequence);
+ method public void setSwitchTextOn(int);
+ }
+
+}
+
+package android.support.v17.leanback.app {
+
+ public final class BackgroundManager {
+ method public void attach(android.view.Window);
+ method public void attachToView(android.view.View);
+ method public void clearDrawable();
+ method public final int getColor();
+ method public deprecated android.graphics.drawable.Drawable getDefaultDimLayer();
+ method public deprecated android.graphics.drawable.Drawable getDimLayer();
+ method public android.graphics.drawable.Drawable getDrawable();
+ method public static android.support.v17.leanback.app.BackgroundManager getInstance(android.app.Activity);
+ method public boolean isAttached();
+ method public boolean isAutoReleaseOnStop();
+ method public void release();
+ method public void setAutoReleaseOnStop(boolean);
+ method public void setBitmap(android.graphics.Bitmap);
+ method public void setColor(int);
+ method public deprecated void setDimLayer(android.graphics.drawable.Drawable);
+ method public void setDrawable(android.graphics.drawable.Drawable);
+ method public void setThemeDrawableResourceId(int);
+ }
+
+ abstract class BaseRowFragment extends android.app.Fragment {
+ method public final android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+ method public final android.support.v17.leanback.widget.PresenterSelector getPresenterSelector();
+ method public int getSelectedPosition();
+ method public final android.support.v17.leanback.widget.VerticalGridView getVerticalGridView();
+ method public void onTransitionEnd();
+ method public boolean onTransitionPrepare();
+ method public void onTransitionStart();
+ method public final void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ method public void setAlignment(int);
+ method public final void setPresenterSelector(android.support.v17.leanback.widget.PresenterSelector);
+ method public void setSelectedPosition(int);
+ method public void setSelectedPosition(int, boolean);
+ }
+
+ abstract class BaseRowSupportFragment extends android.support.v4.app.Fragment {
+ method public final android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+ method public final android.support.v17.leanback.widget.PresenterSelector getPresenterSelector();
+ method public int getSelectedPosition();
+ method public final android.support.v17.leanback.widget.VerticalGridView getVerticalGridView();
+ method public void onTransitionEnd();
+ method public boolean onTransitionPrepare();
+ method public void onTransitionStart();
+ method public final void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ method public void setAlignment(int);
+ method public final void setPresenterSelector(android.support.v17.leanback.widget.PresenterSelector);
+ method public void setSelectedPosition(int);
+ method public void setSelectedPosition(int, boolean);
+ }
+
+ public class BrandedFragment extends android.app.Fragment {
+ ctor public BrandedFragment();
+ method public android.graphics.drawable.Drawable getBadgeDrawable();
+ method public int getSearchAffordanceColor();
+ method public android.support.v17.leanback.widget.SearchOrbView.Colors getSearchAffordanceColors();
+ method public java.lang.CharSequence getTitle();
+ method public android.view.View getTitleView();
+ method public android.support.v17.leanback.widget.TitleViewAdapter getTitleViewAdapter();
+ method public void installTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+ method public final boolean isShowingTitle();
+ method public android.view.View onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+ method public void setBadgeDrawable(android.graphics.drawable.Drawable);
+ method public void setOnSearchClickedListener(android.view.View.OnClickListener);
+ method public void setSearchAffordanceColor(int);
+ method public void setSearchAffordanceColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+ method public void setTitle(java.lang.CharSequence);
+ method public void setTitleView(android.view.View);
+ method public void showTitle(boolean);
+ method public void showTitle(int);
+ }
+
+ public class BrandedSupportFragment extends android.support.v4.app.Fragment {
+ ctor public BrandedSupportFragment();
+ method public android.graphics.drawable.Drawable getBadgeDrawable();
+ method public int getSearchAffordanceColor();
+ method public android.support.v17.leanback.widget.SearchOrbView.Colors getSearchAffordanceColors();
+ method public java.lang.CharSequence getTitle();
+ method public android.view.View getTitleView();
+ method public android.support.v17.leanback.widget.TitleViewAdapter getTitleViewAdapter();
+ method public void installTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+ method public final boolean isShowingTitle();
+ method public android.view.View onInflateTitleView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+ method public void setBadgeDrawable(android.graphics.drawable.Drawable);
+ method public void setOnSearchClickedListener(android.view.View.OnClickListener);
+ method public void setSearchAffordanceColor(int);
+ method public void setSearchAffordanceColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+ method public void setTitle(java.lang.CharSequence);
+ method public void setTitleView(android.view.View);
+ method public void showTitle(boolean);
+ method public void showTitle(int);
+ }
+
+ public class BrowseFragment extends android.support.v17.leanback.app.BrandedFragment {
+ ctor public BrowseFragment();
+ method public static android.os.Bundle createArgs(android.os.Bundle, java.lang.String, int);
+ method protected java.lang.Object createEntranceTransition();
+ method public void enableMainFragmentScaling(boolean);
+ method public deprecated void enableRowScaling(boolean);
+ method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+ method public int getBrandColor();
+ method public android.support.v17.leanback.app.HeadersFragment getHeadersFragment();
+ method public int getHeadersState();
+ method public android.app.Fragment getMainFragment();
+ method public final android.support.v17.leanback.app.BrowseFragment.MainFragmentAdapterRegistry getMainFragmentRegistry();
+ method public android.support.v17.leanback.widget.OnItemViewClickedListener getOnItemViewClickedListener();
+ method public android.support.v17.leanback.widget.OnItemViewSelectedListener getOnItemViewSelectedListener();
+ method public android.support.v17.leanback.app.RowsFragment getRowsFragment();
+ method public int getSelectedPosition();
+ method public android.support.v17.leanback.widget.RowPresenter.ViewHolder getSelectedRowViewHolder();
+ method public final boolean isHeadersTransitionOnBackEnabled();
+ method public boolean isInHeadersTransition();
+ method public boolean isShowingHeaders();
+ method public android.support.v17.leanback.app.HeadersFragment onCreateHeadersFragment();
+ method protected void onEntranceTransitionEnd();
+ method protected void onEntranceTransitionPrepare();
+ method protected void onEntranceTransitionStart();
+ method protected void runEntranceTransition(java.lang.Object);
+ method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ method public void setBrandColor(int);
+ method public void setBrowseTransitionListener(android.support.v17.leanback.app.BrowseFragment.BrowseTransitionListener);
+ method public void setHeaderPresenterSelector(android.support.v17.leanback.widget.PresenterSelector);
+ method public void setHeadersState(int);
+ method public final void setHeadersTransitionOnBackEnabled(boolean);
+ method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+ method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+ method public void setSelectedPosition(int);
+ method public void setSelectedPosition(int, boolean);
+ method public void setSelectedPosition(int, boolean, android.support.v17.leanback.widget.Presenter.ViewHolderTask);
+ method public void startHeadersTransition(boolean);
+ field public static final int HEADERS_DISABLED = 3; // 0x3
+ field public static final int HEADERS_ENABLED = 1; // 0x1
+ field public static final int HEADERS_HIDDEN = 2; // 0x2
+ }
+
+ public static class BrowseFragment.BrowseTransitionListener {
+ ctor public BrowseFragment.BrowseTransitionListener();
+ method public void onHeadersTransitionStart(boolean);
+ method public void onHeadersTransitionStop(boolean);
+ }
+
+ public static abstract class BrowseFragment.FragmentFactory<T extends android.app.Fragment> {
+ ctor public BrowseFragment.FragmentFactory();
+ method public abstract T createFragment(java.lang.Object);
+ }
+
+ public static abstract interface BrowseFragment.FragmentHost {
+ method public abstract void notifyDataReady(android.support.v17.leanback.app.BrowseFragment.MainFragmentAdapter);
+ method public abstract void notifyViewCreated(android.support.v17.leanback.app.BrowseFragment.MainFragmentAdapter);
+ method public abstract void showTitleView(boolean);
+ }
+
+ public static class BrowseFragment.ListRowFragmentFactory extends android.support.v17.leanback.app.BrowseFragment.FragmentFactory {
+ ctor public BrowseFragment.ListRowFragmentFactory();
+ method public android.support.v17.leanback.app.RowsFragment createFragment(java.lang.Object);
+ }
+
+ public static class BrowseFragment.MainFragmentAdapter<T extends android.app.Fragment> {
+ ctor public BrowseFragment.MainFragmentAdapter(T);
+ method public final T getFragment();
+ method public final android.support.v17.leanback.app.BrowseFragment.FragmentHost getFragmentHost();
+ method public boolean isScalingEnabled();
+ method public boolean isScrolling();
+ method public void onTransitionEnd();
+ method public boolean onTransitionPrepare();
+ method public void onTransitionStart();
+ method public void setAlignment(int);
+ method public void setEntranceTransitionState(boolean);
+ method public void setExpand(boolean);
+ method public void setScalingEnabled(boolean);
+ }
+
+ public static abstract interface BrowseFragment.MainFragmentAdapterProvider {
+ method public abstract android.support.v17.leanback.app.BrowseFragment.MainFragmentAdapter getMainFragmentAdapter();
+ }
+
+ public static final class BrowseFragment.MainFragmentAdapterRegistry {
+ ctor public BrowseFragment.MainFragmentAdapterRegistry();
+ method public android.app.Fragment createFragment(java.lang.Object);
+ method public void registerFragment(java.lang.Class, android.support.v17.leanback.app.BrowseFragment.FragmentFactory);
+ }
+
+ public static class BrowseFragment.MainFragmentRowsAdapter<T extends android.app.Fragment> {
+ ctor public BrowseFragment.MainFragmentRowsAdapter(T);
+ method public android.support.v17.leanback.widget.RowPresenter.ViewHolder findRowViewHolderByPosition(int);
+ method public final T getFragment();
+ method public int getSelectedPosition();
+ method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+ method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+ method public void setSelectedPosition(int, boolean, android.support.v17.leanback.widget.Presenter.ViewHolderTask);
+ method public void setSelectedPosition(int, boolean);
+ }
+
+ public static abstract interface BrowseFragment.MainFragmentRowsAdapterProvider {
+ method public abstract android.support.v17.leanback.app.BrowseFragment.MainFragmentRowsAdapter getMainFragmentRowsAdapter();
+ }
+
+ public class BrowseSupportFragment extends android.support.v17.leanback.app.BrandedSupportFragment {
+ ctor public BrowseSupportFragment();
+ method public static android.os.Bundle createArgs(android.os.Bundle, java.lang.String, int);
+ method protected java.lang.Object createEntranceTransition();
+ method public void enableMainFragmentScaling(boolean);
+ method public deprecated void enableRowScaling(boolean);
+ method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+ method public int getBrandColor();
+ method public int getHeadersState();
+ method public android.support.v17.leanback.app.HeadersSupportFragment getHeadersSupportFragment();
+ method public android.support.v4.app.Fragment getMainFragment();
+ method public final android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentAdapterRegistry getMainFragmentRegistry();
+ method public android.support.v17.leanback.widget.OnItemViewClickedListener getOnItemViewClickedListener();
+ method public android.support.v17.leanback.widget.OnItemViewSelectedListener getOnItemViewSelectedListener();
+ method public android.support.v17.leanback.app.RowsSupportFragment getRowsSupportFragment();
+ method public int getSelectedPosition();
+ method public android.support.v17.leanback.widget.RowPresenter.ViewHolder getSelectedRowViewHolder();
+ method public final boolean isHeadersTransitionOnBackEnabled();
+ method public boolean isInHeadersTransition();
+ method public boolean isShowingHeaders();
+ method public android.support.v17.leanback.app.HeadersSupportFragment onCreateHeadersSupportFragment();
+ method protected void onEntranceTransitionEnd();
+ method protected void onEntranceTransitionPrepare();
+ method protected void onEntranceTransitionStart();
+ method protected void runEntranceTransition(java.lang.Object);
+ method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ method public void setBrandColor(int);
+ method public void setBrowseTransitionListener(android.support.v17.leanback.app.BrowseSupportFragment.BrowseTransitionListener);
+ method public void setHeaderPresenterSelector(android.support.v17.leanback.widget.PresenterSelector);
+ method public void setHeadersState(int);
+ method public final void setHeadersTransitionOnBackEnabled(boolean);
+ method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+ method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+ method public void setSelectedPosition(int);
+ method public void setSelectedPosition(int, boolean);
+ method public void setSelectedPosition(int, boolean, android.support.v17.leanback.widget.Presenter.ViewHolderTask);
+ method public void startHeadersTransition(boolean);
+ field public static final int HEADERS_DISABLED = 3; // 0x3
+ field public static final int HEADERS_ENABLED = 1; // 0x1
+ field public static final int HEADERS_HIDDEN = 2; // 0x2
+ }
+
+ public static class BrowseSupportFragment.BrowseTransitionListener {
+ ctor public BrowseSupportFragment.BrowseTransitionListener();
+ method public void onHeadersTransitionStart(boolean);
+ method public void onHeadersTransitionStop(boolean);
+ }
+
+ public static abstract class BrowseSupportFragment.FragmentFactory<T extends android.support.v4.app.Fragment> {
+ ctor public BrowseSupportFragment.FragmentFactory();
+ method public abstract T createFragment(java.lang.Object);
+ }
+
+ public static abstract interface BrowseSupportFragment.FragmentHost {
+ method public abstract void notifyDataReady(android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentAdapter);
+ method public abstract void notifyViewCreated(android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentAdapter);
+ method public abstract void showTitleView(boolean);
+ }
+
+ public static class BrowseSupportFragment.ListRowFragmentFactory extends android.support.v17.leanback.app.BrowseSupportFragment.FragmentFactory {
+ ctor public BrowseSupportFragment.ListRowFragmentFactory();
+ method public android.support.v17.leanback.app.RowsSupportFragment createFragment(java.lang.Object);
+ }
+
+ public static class BrowseSupportFragment.MainFragmentAdapter<T extends android.support.v4.app.Fragment> {
+ ctor public BrowseSupportFragment.MainFragmentAdapter(T);
+ method public final T getFragment();
+ method public final android.support.v17.leanback.app.BrowseSupportFragment.FragmentHost getFragmentHost();
+ method public boolean isScalingEnabled();
+ method public boolean isScrolling();
+ method public void onTransitionEnd();
+ method public boolean onTransitionPrepare();
+ method public void onTransitionStart();
+ method public void setAlignment(int);
+ method public void setEntranceTransitionState(boolean);
+ method public void setExpand(boolean);
+ method public void setScalingEnabled(boolean);
+ }
+
+ public static abstract interface BrowseSupportFragment.MainFragmentAdapterProvider {
+ method public abstract android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentAdapter getMainFragmentAdapter();
+ }
+
+ public static final class BrowseSupportFragment.MainFragmentAdapterRegistry {
+ ctor public BrowseSupportFragment.MainFragmentAdapterRegistry();
+ method public android.support.v4.app.Fragment createFragment(java.lang.Object);
+ method public void registerFragment(java.lang.Class, android.support.v17.leanback.app.BrowseSupportFragment.FragmentFactory);
+ }
+
+ public static class BrowseSupportFragment.MainFragmentRowsAdapter<T extends android.support.v4.app.Fragment> {
+ ctor public BrowseSupportFragment.MainFragmentRowsAdapter(T);
+ method public android.support.v17.leanback.widget.RowPresenter.ViewHolder findRowViewHolderByPosition(int);
+ method public final T getFragment();
+ method public int getSelectedPosition();
+ method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+ method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+ method public void setSelectedPosition(int, boolean, android.support.v17.leanback.widget.Presenter.ViewHolderTask);
+ method public void setSelectedPosition(int, boolean);
+ }
+
+ public static abstract interface BrowseSupportFragment.MainFragmentRowsAdapterProvider {
+ method public abstract android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentRowsAdapter getMainFragmentRowsAdapter();
+ }
+
+ public class DetailsFragment extends android.support.v17.leanback.app.BrandedFragment {
+ ctor public DetailsFragment();
+ method protected java.lang.Object createEntranceTransition();
+ method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+ method public android.support.v17.leanback.widget.BaseOnItemViewClickedListener getOnItemViewClickedListener();
+ method public android.support.v17.leanback.widget.DetailsParallax getParallax();
+ method public android.support.v17.leanback.app.RowsFragment getRowsFragment();
+ method protected deprecated android.view.View inflateTitle(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+ method protected void onEntranceTransitionEnd();
+ method protected void onEntranceTransitionPrepare();
+ method protected void onEntranceTransitionStart();
+ method protected void onSetDetailsOverviewRowStatus(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int);
+ method protected void onSetRowStatus(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int);
+ method protected void runEntranceTransition(java.lang.Object);
+ method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+ method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.BaseOnItemViewSelectedListener);
+ method public void setSelectedPosition(int);
+ method public void setSelectedPosition(int, boolean);
+ method protected void setupDetailsOverviewRowPresenter(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter);
+ method protected void setupPresenter(android.support.v17.leanback.widget.Presenter);
+ }
+
+ public class DetailsFragmentBackgroundController {
+ ctor public DetailsFragmentBackgroundController(android.support.v17.leanback.app.DetailsFragment);
+ method public void enableParallax();
+ method public void enableParallax(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.support.v17.leanback.widget.ParallaxTarget.PropertyValuesHolderTarget);
+ method public final android.app.Fragment findOrCreateVideoFragment();
+ method public final android.graphics.drawable.Drawable getBottomDrawable();
+ method public final android.graphics.Bitmap getCoverBitmap();
+ method public final android.graphics.drawable.Drawable getCoverDrawable();
+ method public final int getParallaxDrawableMaxOffset();
+ method public final int getSolidColor();
+ method public android.support.v17.leanback.media.PlaybackGlueHost onCreateGlueHost();
+ method public android.app.Fragment onCreateVideoFragment();
+ method public final void setCoverBitmap(android.graphics.Bitmap);
+ method public final void setParallaxDrawableMaxOffset(int);
+ method public final void setSolidColor(int);
+ method public void setupVideoPlayback(android.support.v17.leanback.media.PlaybackGlue);
+ }
+
+ public class DetailsSupportFragment extends android.support.v17.leanback.app.BrandedSupportFragment {
+ ctor public DetailsSupportFragment();
+ method protected java.lang.Object createEntranceTransition();
+ method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+ method public android.support.v17.leanback.widget.BaseOnItemViewClickedListener getOnItemViewClickedListener();
+ method public android.support.v17.leanback.widget.DetailsParallax getParallax();
+ method public android.support.v17.leanback.app.RowsSupportFragment getRowsSupportFragment();
+ method protected deprecated android.view.View inflateTitle(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+ method protected void onEntranceTransitionEnd();
+ method protected void onEntranceTransitionPrepare();
+ method protected void onEntranceTransitionStart();
+ method protected void onSetDetailsOverviewRowStatus(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int);
+ method protected void onSetRowStatus(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int);
+ method protected void runEntranceTransition(java.lang.Object);
+ method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+ method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.BaseOnItemViewSelectedListener);
+ method public void setSelectedPosition(int);
+ method public void setSelectedPosition(int, boolean);
+ method protected void setupDetailsOverviewRowPresenter(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter);
+ method protected void setupPresenter(android.support.v17.leanback.widget.Presenter);
+ }
+
+ public class DetailsSupportFragmentBackgroundController {
+ ctor public DetailsSupportFragmentBackgroundController(android.support.v17.leanback.app.DetailsSupportFragment);
+ method public void enableParallax();
+ method public void enableParallax(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.support.v17.leanback.widget.ParallaxTarget.PropertyValuesHolderTarget);
+ method public final android.support.v4.app.Fragment findOrCreateVideoSupportFragment();
+ method public final android.graphics.drawable.Drawable getBottomDrawable();
+ method public final android.graphics.Bitmap getCoverBitmap();
+ method public final android.graphics.drawable.Drawable getCoverDrawable();
+ method public final int getParallaxDrawableMaxOffset();
+ method public final int getSolidColor();
+ method public android.support.v17.leanback.media.PlaybackGlueHost onCreateGlueHost();
+ method public android.support.v4.app.Fragment onCreateVideoSupportFragment();
+ method public final void setCoverBitmap(android.graphics.Bitmap);
+ method public final void setParallaxDrawableMaxOffset(int);
+ method public final void setSolidColor(int);
+ method public void setupVideoPlayback(android.support.v17.leanback.media.PlaybackGlue);
+ }
+
+ public class ErrorFragment extends android.support.v17.leanback.app.BrandedFragment {
+ ctor public ErrorFragment();
+ method public android.graphics.drawable.Drawable getBackgroundDrawable();
+ method public android.view.View.OnClickListener getButtonClickListener();
+ method public java.lang.String getButtonText();
+ method public android.graphics.drawable.Drawable getImageDrawable();
+ method public java.lang.CharSequence getMessage();
+ method public boolean isBackgroundTranslucent();
+ method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
+ method public void setButtonClickListener(android.view.View.OnClickListener);
+ method public void setButtonText(java.lang.String);
+ method public void setDefaultBackground(boolean);
+ method public void setImageDrawable(android.graphics.drawable.Drawable);
+ method public void setMessage(java.lang.CharSequence);
+ }
+
+ public class ErrorSupportFragment extends android.support.v17.leanback.app.BrandedSupportFragment {
+ ctor public ErrorSupportFragment();
+ method public android.graphics.drawable.Drawable getBackgroundDrawable();
+ method public android.view.View.OnClickListener getButtonClickListener();
+ method public java.lang.String getButtonText();
+ method public android.graphics.drawable.Drawable getImageDrawable();
+ method public java.lang.CharSequence getMessage();
+ method public boolean isBackgroundTranslucent();
+ method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
+ method public void setButtonClickListener(android.view.View.OnClickListener);
+ method public void setButtonText(java.lang.String);
+ method public void setDefaultBackground(boolean);
+ method public void setImageDrawable(android.graphics.drawable.Drawable);
+ method public void setMessage(java.lang.CharSequence);
+ }
+
+ public class GuidedStepFragment extends android.app.Fragment {
+ ctor public GuidedStepFragment();
+ method public static int add(android.app.FragmentManager, android.support.v17.leanback.app.GuidedStepFragment);
+ method public static int add(android.app.FragmentManager, android.support.v17.leanback.app.GuidedStepFragment, int);
+ method public static int addAsRoot(android.app.Activity, android.support.v17.leanback.app.GuidedStepFragment, int);
+ method public void collapseAction(boolean);
+ method public void collapseSubActions();
+ method public void expandAction(android.support.v17.leanback.widget.GuidedAction, boolean);
+ method public void expandSubActions(android.support.v17.leanback.widget.GuidedAction);
+ method public android.support.v17.leanback.widget.GuidedAction findActionById(long);
+ method public int findActionPositionById(long);
+ method public android.support.v17.leanback.widget.GuidedAction findButtonActionById(long);
+ method public int findButtonActionPositionById(long);
+ method public void finishGuidedStepFragments();
+ method public android.view.View getActionItemView(int);
+ method public java.util.List<android.support.v17.leanback.widget.GuidedAction> getActions();
+ method public android.view.View getButtonActionItemView(int);
+ method public java.util.List<android.support.v17.leanback.widget.GuidedAction> getButtonActions();
+ method public static android.support.v17.leanback.app.GuidedStepFragment getCurrentGuidedStepFragment(android.app.FragmentManager);
+ method public android.support.v17.leanback.widget.GuidanceStylist getGuidanceStylist();
+ method public android.support.v17.leanback.widget.GuidedActionsStylist getGuidedActionsStylist();
+ method public android.support.v17.leanback.widget.GuidedActionsStylist getGuidedButtonActionsStylist();
+ method public int getSelectedActionPosition();
+ method public int getSelectedButtonActionPosition();
+ method public int getUiStyle();
+ method public boolean isExpanded();
+ method public boolean isFocusOutEndAllowed();
+ method public boolean isFocusOutStartAllowed();
+ method public boolean isSubActionsExpanded();
+ method public void notifyActionChanged(int);
+ method public void notifyButtonActionChanged(int);
+ method protected void onAddSharedElementTransition(android.app.FragmentTransaction, android.support.v17.leanback.app.GuidedStepFragment);
+ method public void onCreateActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>, android.os.Bundle);
+ method public android.support.v17.leanback.widget.GuidedActionsStylist onCreateActionsStylist();
+ method public android.view.View onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+ method public void onCreateButtonActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>, android.os.Bundle);
+ method public android.support.v17.leanback.widget.GuidedActionsStylist onCreateButtonActionsStylist();
+ method public android.support.v17.leanback.widget.GuidanceStylist.Guidance onCreateGuidance(android.os.Bundle);
+ method public android.support.v17.leanback.widget.GuidanceStylist onCreateGuidanceStylist();
+ method public void onGuidedActionClicked(android.support.v17.leanback.widget.GuidedAction);
+ method public void onGuidedActionEditCanceled(android.support.v17.leanback.widget.GuidedAction);
+ method public deprecated void onGuidedActionEdited(android.support.v17.leanback.widget.GuidedAction);
+ method public long onGuidedActionEditedAndProceed(android.support.v17.leanback.widget.GuidedAction);
+ method public void onGuidedActionFocused(android.support.v17.leanback.widget.GuidedAction);
+ method protected void onProvideFragmentTransitions();
+ method public int onProvideTheme();
+ method public boolean onSubGuidedActionClicked(android.support.v17.leanback.widget.GuidedAction);
+ method public void popBackStackToGuidedStepFragment(java.lang.Class, int);
+ method public void setActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>);
+ method public void setButtonActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>);
+ method public void setSelectedActionPosition(int);
+ method public void setSelectedButtonActionPosition(int);
+ method public void setUiStyle(int);
+ field public static final java.lang.String EXTRA_UI_STYLE = "uiStyle";
+ field public static final int UI_STYLE_ACTIVITY_ROOT = 2; // 0x2
+ field public static final deprecated int UI_STYLE_DEFAULT = 0; // 0x0
+ field public static final int UI_STYLE_ENTRANCE = 1; // 0x1
+ field public static final int UI_STYLE_REPLACE = 0; // 0x0
+ }
+
+ public class GuidedStepSupportFragment extends android.support.v4.app.Fragment {
+ ctor public GuidedStepSupportFragment();
+ method public static int add(android.support.v4.app.FragmentManager, android.support.v17.leanback.app.GuidedStepSupportFragment);
+ method public static int add(android.support.v4.app.FragmentManager, android.support.v17.leanback.app.GuidedStepSupportFragment, int);
+ method public static int addAsRoot(android.support.v4.app.FragmentActivity, android.support.v17.leanback.app.GuidedStepSupportFragment, int);
+ method public void collapseAction(boolean);
+ method public void collapseSubActions();
+ method public void expandAction(android.support.v17.leanback.widget.GuidedAction, boolean);
+ method public void expandSubActions(android.support.v17.leanback.widget.GuidedAction);
+ method public android.support.v17.leanback.widget.GuidedAction findActionById(long);
+ method public int findActionPositionById(long);
+ method public android.support.v17.leanback.widget.GuidedAction findButtonActionById(long);
+ method public int findButtonActionPositionById(long);
+ method public void finishGuidedStepSupportFragments();
+ method public android.view.View getActionItemView(int);
+ method public java.util.List<android.support.v17.leanback.widget.GuidedAction> getActions();
+ method public android.view.View getButtonActionItemView(int);
+ method public java.util.List<android.support.v17.leanback.widget.GuidedAction> getButtonActions();
+ method public static android.support.v17.leanback.app.GuidedStepSupportFragment getCurrentGuidedStepSupportFragment(android.support.v4.app.FragmentManager);
+ method public android.support.v17.leanback.widget.GuidanceStylist getGuidanceStylist();
+ method public android.support.v17.leanback.widget.GuidedActionsStylist getGuidedActionsStylist();
+ method public android.support.v17.leanback.widget.GuidedActionsStylist getGuidedButtonActionsStylist();
+ method public int getSelectedActionPosition();
+ method public int getSelectedButtonActionPosition();
+ method public int getUiStyle();
+ method public boolean isExpanded();
+ method public boolean isFocusOutEndAllowed();
+ method public boolean isFocusOutStartAllowed();
+ method public boolean isSubActionsExpanded();
+ method public void notifyActionChanged(int);
+ method public void notifyButtonActionChanged(int);
+ method protected void onAddSharedElementTransition(android.support.v4.app.FragmentTransaction, android.support.v17.leanback.app.GuidedStepSupportFragment);
+ method public void onCreateActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>, android.os.Bundle);
+ method public android.support.v17.leanback.widget.GuidedActionsStylist onCreateActionsStylist();
+ method public android.view.View onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+ method public void onCreateButtonActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>, android.os.Bundle);
+ method public android.support.v17.leanback.widget.GuidedActionsStylist onCreateButtonActionsStylist();
+ method public android.support.v17.leanback.widget.GuidanceStylist.Guidance onCreateGuidance(android.os.Bundle);
+ method public android.support.v17.leanback.widget.GuidanceStylist onCreateGuidanceStylist();
+ method public void onGuidedActionClicked(android.support.v17.leanback.widget.GuidedAction);
+ method public void onGuidedActionEditCanceled(android.support.v17.leanback.widget.GuidedAction);
+ method public deprecated void onGuidedActionEdited(android.support.v17.leanback.widget.GuidedAction);
+ method public long onGuidedActionEditedAndProceed(android.support.v17.leanback.widget.GuidedAction);
+ method public void onGuidedActionFocused(android.support.v17.leanback.widget.GuidedAction);
+ method protected void onProvideFragmentTransitions();
+ method public int onProvideTheme();
+ method public boolean onSubGuidedActionClicked(android.support.v17.leanback.widget.GuidedAction);
+ method public void popBackStackToGuidedStepSupportFragment(java.lang.Class, int);
+ method public void setActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>);
+ method public void setButtonActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>);
+ method public void setSelectedActionPosition(int);
+ method public void setSelectedButtonActionPosition(int);
+ method public void setUiStyle(int);
+ field public static final java.lang.String EXTRA_UI_STYLE = "uiStyle";
+ field public static final int UI_STYLE_ACTIVITY_ROOT = 2; // 0x2
+ field public static final deprecated int UI_STYLE_DEFAULT = 0; // 0x0
+ field public static final int UI_STYLE_ENTRANCE = 1; // 0x1
+ field public static final int UI_STYLE_REPLACE = 0; // 0x0
+ }
+
+ public class HeadersFragment extends android.support.v17.leanback.app.BaseRowFragment {
+ ctor public HeadersFragment();
+ method public boolean isScrolling();
+ method public void setOnHeaderClickedListener(android.support.v17.leanback.app.HeadersFragment.OnHeaderClickedListener);
+ method public void setOnHeaderViewSelectedListener(android.support.v17.leanback.app.HeadersFragment.OnHeaderViewSelectedListener);
+ }
+
+ public static abstract interface HeadersFragment.OnHeaderClickedListener {
+ method public abstract void onHeaderClicked(android.support.v17.leanback.widget.RowHeaderPresenter.ViewHolder, android.support.v17.leanback.widget.Row);
+ }
+
+ public static abstract interface HeadersFragment.OnHeaderViewSelectedListener {
+ method public abstract void onHeaderSelected(android.support.v17.leanback.widget.RowHeaderPresenter.ViewHolder, android.support.v17.leanback.widget.Row);
+ }
+
+ public class HeadersSupportFragment extends android.support.v17.leanback.app.BaseRowSupportFragment {
+ ctor public HeadersSupportFragment();
+ method public boolean isScrolling();
+ method public void setOnHeaderClickedListener(android.support.v17.leanback.app.HeadersSupportFragment.OnHeaderClickedListener);
+ method public void setOnHeaderViewSelectedListener(android.support.v17.leanback.app.HeadersSupportFragment.OnHeaderViewSelectedListener);
+ }
+
+ public static abstract interface HeadersSupportFragment.OnHeaderClickedListener {
+ method public abstract void onHeaderClicked(android.support.v17.leanback.widget.RowHeaderPresenter.ViewHolder, android.support.v17.leanback.widget.Row);
+ }
+
+ public static abstract interface HeadersSupportFragment.OnHeaderViewSelectedListener {
+ method public abstract void onHeaderSelected(android.support.v17.leanback.widget.RowHeaderPresenter.ViewHolder, android.support.v17.leanback.widget.Row);
+ }
+
+ public abstract deprecated class MediaControllerGlue extends android.support.v17.leanback.app.PlaybackControlGlue {
+ ctor public MediaControllerGlue(android.content.Context, android.support.v17.leanback.app.PlaybackOverlayFragment, int[]);
+ ctor public MediaControllerGlue(android.content.Context, android.support.v17.leanback.app.PlaybackOverlayFragment, int[], int[]);
+ method public void attachToMediaController(android.support.v4.media.session.MediaControllerCompat);
+ method public void detach();
+ method public int getCurrentPosition();
+ method public int getCurrentSpeedId();
+ method public android.graphics.drawable.Drawable getMediaArt();
+ method public final android.support.v4.media.session.MediaControllerCompat getMediaController();
+ method public int getMediaDuration();
+ method public java.lang.CharSequence getMediaSubtitle();
+ method public java.lang.CharSequence getMediaTitle();
+ method public long getSupportedActions();
+ method public boolean hasValidMedia();
+ method public boolean isMediaPlaying();
+ }
+
+ public abstract class OnboardingFragment extends android.app.Fragment {
+ ctor public OnboardingFragment();
+ method protected final int getCurrentPageIndex();
+ method public final int getIconResourceId();
+ method public final int getLogoResourceId();
+ method protected abstract int getPageCount();
+ method protected abstract java.lang.CharSequence getPageDescription(int);
+ method protected abstract java.lang.CharSequence getPageTitle(int);
+ method protected abstract android.view.View onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup);
+ method protected abstract android.view.View onCreateContentView(android.view.LayoutInflater, android.view.ViewGroup);
+ method protected android.animation.Animator onCreateDescriptionAnimator();
+ method protected android.animation.Animator onCreateEnterAnimation();
+ method protected abstract android.view.View onCreateForegroundView(android.view.LayoutInflater, android.view.ViewGroup);
+ method protected android.animation.Animator onCreateLogoAnimation();
+ method protected android.animation.Animator onCreateTitleAnimator();
+ method protected void onFinishFragment();
+ method protected void onPageChanged(int, int);
+ method public int onProvideTheme();
+ method public final void setIconResouceId(int);
+ method public final void setLogoResourceId(int);
+ }
+
+ public abstract class OnboardingSupportFragment extends android.support.v4.app.Fragment {
+ ctor public OnboardingSupportFragment();
+ method protected final int getCurrentPageIndex();
+ method public final int getIconResourceId();
+ method public final int getLogoResourceId();
+ method protected abstract int getPageCount();
+ method protected abstract java.lang.CharSequence getPageDescription(int);
+ method protected abstract java.lang.CharSequence getPageTitle(int);
+ method protected abstract android.view.View onCreateBackgroundView(android.view.LayoutInflater, android.view.ViewGroup);
+ method protected abstract android.view.View onCreateContentView(android.view.LayoutInflater, android.view.ViewGroup);
+ method protected android.animation.Animator onCreateDescriptionAnimator();
+ method protected android.animation.Animator onCreateEnterAnimation();
+ method protected abstract android.view.View onCreateForegroundView(android.view.LayoutInflater, android.view.ViewGroup);
+ method protected android.animation.Animator onCreateLogoAnimation();
+ method protected android.animation.Animator onCreateTitleAnimator();
+ method protected void onFinishFragment();
+ method protected void onPageChanged(int, int);
+ method public int onProvideTheme();
+ method public final void setIconResouceId(int);
+ method public final void setLogoResourceId(int);
+ }
+
+ 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 void fadeOut();
+ method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+ method public int getBackgroundType();
+ method public boolean isFadingEnabled();
+ method public void notifyPlaybackRowChanged();
+ method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ method public void setBackgroundType(int);
+ method public void setFadingEnabled(boolean);
+ method public void setHostCallback(android.support.v17.leanback.media.PlaybackGlueHost.HostCallback);
+ method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+ method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.BaseOnItemViewSelectedListener);
+ method public final void setOnKeyInterceptListener(android.view.View.OnKeyListener);
+ method public void setOnPlaybackItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+ method public void setPlaybackRow(android.support.v17.leanback.widget.Row);
+ method public void setPlaybackRowPresenter(android.support.v17.leanback.widget.PlaybackRowPresenter);
+ method public void setSelectedPosition(int);
+ method public void setSelectedPosition(int, boolean);
+ 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 class PlaybackFragmentGlueHost extends android.support.v17.leanback.media.PlaybackGlueHost {
+ ctor public PlaybackFragmentGlueHost(android.support.v17.leanback.app.PlaybackFragment);
+ }
+
+ 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 void fadeOut();
+ method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+ method public int getBackgroundType();
+ method public boolean isFadingEnabled();
+ method public void notifyPlaybackRowChanged();
+ method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ method public void setBackgroundType(int);
+ method public void setFadingEnabled(boolean);
+ method public void setHostCallback(android.support.v17.leanback.media.PlaybackGlueHost.HostCallback);
+ method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+ method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.BaseOnItemViewSelectedListener);
+ method public final void setOnKeyInterceptListener(android.view.View.OnKeyListener);
+ method public void setOnPlaybackItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+ method public void setPlaybackRow(android.support.v17.leanback.widget.Row);
+ method public void setPlaybackRowPresenter(android.support.v17.leanback.widget.PlaybackRowPresenter);
+ method public void setSelectedPosition(int);
+ method public void setSelectedPosition(int, boolean);
+ 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 class PlaybackSupportFragmentGlueHost extends android.support.v17.leanback.media.PlaybackGlueHost {
+ ctor public PlaybackSupportFragmentGlueHost(android.support.v17.leanback.app.PlaybackSupportFragment);
+ }
+
+ public final class ProgressBarManager {
+ ctor public ProgressBarManager();
+ method public void disableProgressBar();
+ method public void enableProgressBar();
+ method public long getInitialDelay();
+ method public void hide();
+ method public void setInitialDelay(long);
+ method public void setProgressBarView(android.view.View);
+ method public void setRootView(android.view.ViewGroup);
+ method public void show();
+ }
+
+ public class RowsFragment extends android.support.v17.leanback.app.BaseRowFragment implements android.support.v17.leanback.app.BrowseFragment.MainFragmentAdapterProvider android.support.v17.leanback.app.BrowseFragment.MainFragmentRowsAdapterProvider {
+ ctor public RowsFragment();
+ method public deprecated void enableRowScaling(boolean);
+ method protected android.support.v17.leanback.widget.VerticalGridView findGridViewFromRoot(android.view.View);
+ method public android.support.v17.leanback.widget.RowPresenter.ViewHolder findRowViewHolderByPosition(int);
+ method public android.support.v17.leanback.app.BrowseFragment.MainFragmentAdapter getMainFragmentAdapter();
+ method public android.support.v17.leanback.app.BrowseFragment.MainFragmentRowsAdapter getMainFragmentRowsAdapter();
+ method public android.support.v17.leanback.widget.BaseOnItemViewClickedListener getOnItemViewClickedListener();
+ method public android.support.v17.leanback.widget.BaseOnItemViewSelectedListener getOnItemViewSelectedListener();
+ method public android.support.v17.leanback.widget.RowPresenter.ViewHolder getRowViewHolder(int);
+ method public boolean isScrolling();
+ method public void setEntranceTransitionState(boolean);
+ method public void setExpand(boolean);
+ method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+ method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.BaseOnItemViewSelectedListener);
+ method public void setSelectedPosition(int, boolean, android.support.v17.leanback.widget.Presenter.ViewHolderTask);
+ }
+
+ public static class RowsFragment.MainFragmentAdapter extends android.support.v17.leanback.app.BrowseFragment.MainFragmentAdapter {
+ ctor public RowsFragment.MainFragmentAdapter(android.support.v17.leanback.app.RowsFragment);
+ }
+
+ public static class RowsFragment.MainFragmentRowsAdapter extends android.support.v17.leanback.app.BrowseFragment.MainFragmentRowsAdapter {
+ ctor public RowsFragment.MainFragmentRowsAdapter(android.support.v17.leanback.app.RowsFragment);
+ }
+
+ public class RowsSupportFragment extends android.support.v17.leanback.app.BaseRowSupportFragment implements android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentAdapterProvider android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentRowsAdapterProvider {
+ ctor public RowsSupportFragment();
+ method public deprecated void enableRowScaling(boolean);
+ method protected android.support.v17.leanback.widget.VerticalGridView findGridViewFromRoot(android.view.View);
+ method public android.support.v17.leanback.widget.RowPresenter.ViewHolder findRowViewHolderByPosition(int);
+ method public android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentAdapter getMainFragmentAdapter();
+ method public android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentRowsAdapter getMainFragmentRowsAdapter();
+ method public android.support.v17.leanback.widget.BaseOnItemViewClickedListener getOnItemViewClickedListener();
+ method public android.support.v17.leanback.widget.BaseOnItemViewSelectedListener getOnItemViewSelectedListener();
+ method public android.support.v17.leanback.widget.RowPresenter.ViewHolder getRowViewHolder(int);
+ method public boolean isScrolling();
+ method public void setEntranceTransitionState(boolean);
+ method public void setExpand(boolean);
+ method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+ method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.BaseOnItemViewSelectedListener);
+ method public void setSelectedPosition(int, boolean, android.support.v17.leanback.widget.Presenter.ViewHolderTask);
+ }
+
+ public static class RowsSupportFragment.MainFragmentAdapter extends android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentAdapter {
+ ctor public RowsSupportFragment.MainFragmentAdapter(android.support.v17.leanback.app.RowsSupportFragment);
+ }
+
+ public static class RowsSupportFragment.MainFragmentRowsAdapter extends android.support.v17.leanback.app.BrowseSupportFragment.MainFragmentRowsAdapter {
+ ctor public RowsSupportFragment.MainFragmentRowsAdapter(android.support.v17.leanback.app.RowsSupportFragment);
+ }
+
+ public class SearchFragment extends android.app.Fragment {
+ ctor public SearchFragment();
+ method public static android.os.Bundle createArgs(android.os.Bundle, java.lang.String);
+ method public static android.os.Bundle createArgs(android.os.Bundle, java.lang.String, java.lang.String);
+ method public void displayCompletions(java.util.List<java.lang.String>);
+ method public void displayCompletions(android.view.inputmethod.CompletionInfo[]);
+ method public android.graphics.drawable.Drawable getBadgeDrawable();
+ method public android.content.Intent getRecognizerIntent();
+ method public android.support.v17.leanback.app.RowsFragment getRowsFragment();
+ method public java.lang.String getTitle();
+ method public static android.support.v17.leanback.app.SearchFragment newInstance(java.lang.String);
+ method public void setBadgeDrawable(android.graphics.drawable.Drawable);
+ method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+ method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+ method public void setSearchAffordanceColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+ method public void setSearchAffordanceColorsInListening(android.support.v17.leanback.widget.SearchOrbView.Colors);
+ 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 void setTitle(java.lang.String);
+ method public void startRecognition();
+ }
+
+ public static abstract interface SearchFragment.SearchResultProvider {
+ method public abstract android.support.v17.leanback.widget.ObjectAdapter getResultsAdapter();
+ method public abstract boolean onQueryTextChange(java.lang.String);
+ method public abstract boolean onQueryTextSubmit(java.lang.String);
+ }
+
+ public class SearchSupportFragment extends android.support.v4.app.Fragment {
+ ctor public SearchSupportFragment();
+ method public static android.os.Bundle createArgs(android.os.Bundle, java.lang.String);
+ method public static android.os.Bundle createArgs(android.os.Bundle, java.lang.String, java.lang.String);
+ method public void displayCompletions(java.util.List<java.lang.String>);
+ method public void displayCompletions(android.view.inputmethod.CompletionInfo[]);
+ method public android.graphics.drawable.Drawable getBadgeDrawable();
+ method public android.content.Intent getRecognizerIntent();
+ method public android.support.v17.leanback.app.RowsSupportFragment getRowsSupportFragment();
+ method public java.lang.String getTitle();
+ method public static android.support.v17.leanback.app.SearchSupportFragment newInstance(java.lang.String);
+ method public void setBadgeDrawable(android.graphics.drawable.Drawable);
+ method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+ method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+ method public void setSearchAffordanceColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+ method public void setSearchAffordanceColorsInListening(android.support.v17.leanback.widget.SearchOrbView.Colors);
+ 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 void setTitle(java.lang.String);
+ method public void startRecognition();
+ }
+
+ public static abstract interface SearchSupportFragment.SearchResultProvider {
+ method public abstract android.support.v17.leanback.widget.ObjectAdapter getResultsAdapter();
+ method public abstract boolean onQueryTextChange(java.lang.String);
+ method public abstract boolean onQueryTextSubmit(java.lang.String);
+ }
+
+ public class VerticalGridFragment extends android.support.v17.leanback.app.BrandedFragment {
+ ctor public VerticalGridFragment();
+ method protected java.lang.Object createEntranceTransition();
+ method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+ method public android.support.v17.leanback.widget.VerticalGridPresenter getGridPresenter();
+ method public android.support.v17.leanback.widget.OnItemViewClickedListener getOnItemViewClickedListener();
+ method protected void runEntranceTransition(java.lang.Object);
+ method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ method public void setGridPresenter(android.support.v17.leanback.widget.VerticalGridPresenter);
+ method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+ method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+ method public void setSelectedPosition(int);
+ }
+
+ public class VerticalGridSupportFragment extends android.support.v17.leanback.app.BrandedSupportFragment {
+ ctor public VerticalGridSupportFragment();
+ method protected java.lang.Object createEntranceTransition();
+ method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+ method public android.support.v17.leanback.widget.VerticalGridPresenter getGridPresenter();
+ method public android.support.v17.leanback.widget.OnItemViewClickedListener getOnItemViewClickedListener();
+ method protected void runEntranceTransition(java.lang.Object);
+ method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ method public void setGridPresenter(android.support.v17.leanback.widget.VerticalGridPresenter);
+ method public void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+ method public void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+ method public void setSelectedPosition(int);
+ }
+
+ public class VideoFragment extends android.support.v17.leanback.app.PlaybackFragment {
+ ctor public VideoFragment();
+ method public android.view.SurfaceView getSurfaceView();
+ method public void setSurfaceHolderCallback(android.view.SurfaceHolder.Callback);
+ }
+
+ public class VideoFragmentGlueHost extends android.support.v17.leanback.app.PlaybackFragmentGlueHost implements android.support.v17.leanback.media.SurfaceHolderGlueHost {
+ ctor public VideoFragmentGlueHost(android.support.v17.leanback.app.VideoFragment);
+ method public void setSurfaceHolderCallback(android.view.SurfaceHolder.Callback);
+ }
+
+ public class VideoSupportFragment extends android.support.v17.leanback.app.PlaybackSupportFragment {
+ ctor public VideoSupportFragment();
+ method public android.view.SurfaceView getSurfaceView();
+ method public void setSurfaceHolderCallback(android.view.SurfaceHolder.Callback);
+ }
+
+ public class VideoSupportFragmentGlueHost extends android.support.v17.leanback.app.PlaybackSupportFragmentGlueHost implements android.support.v17.leanback.media.SurfaceHolderGlueHost {
+ ctor public VideoSupportFragmentGlueHost(android.support.v17.leanback.app.VideoSupportFragment);
+ method public void setSurfaceHolderCallback(android.view.SurfaceHolder.Callback);
+ }
+
+}
+
+package android.support.v17.leanback.database {
+
+ public abstract class CursorMapper {
+ ctor public CursorMapper();
+ method protected abstract java.lang.Object bind(android.database.Cursor);
+ method protected abstract void bindColumns(android.database.Cursor);
+ method public java.lang.Object convert(android.database.Cursor);
+ }
+
+}
+
+package android.support.v17.leanback.graphics {
+
+ public class BoundsRule {
+ ctor public BoundsRule();
+ ctor public BoundsRule(android.support.v17.leanback.graphics.BoundsRule);
+ method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule absoluteValue(int);
+ method public void calculateBounds(android.graphics.Rect, android.graphics.Rect);
+ method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParent(float);
+ method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParentWithOffset(float, int);
+ field public android.support.v17.leanback.graphics.BoundsRule.ValueRule bottom;
+ field public android.support.v17.leanback.graphics.BoundsRule.ValueRule left;
+ field public android.support.v17.leanback.graphics.BoundsRule.ValueRule right;
+ field public android.support.v17.leanback.graphics.BoundsRule.ValueRule top;
+ }
+
+ public static final class BoundsRule.ValueRule {
+ method public int getAbsoluteValue();
+ method public float getFraction();
+ method public void setAbsoluteValue(int);
+ method public void setFraction(float);
+ }
+
+ public final class ColorFilterCache {
+ method public static android.support.v17.leanback.graphics.ColorFilterCache getColorFilterCache(int);
+ method public android.graphics.ColorFilter getFilterForLevel(float);
+ }
+
+ public final class ColorFilterDimmer {
+ method public void applyFilterToView(android.view.View);
+ method public static android.support.v17.leanback.graphics.ColorFilterDimmer create(android.support.v17.leanback.graphics.ColorFilterCache, float, float);
+ method public static android.support.v17.leanback.graphics.ColorFilterDimmer createDefault(android.content.Context);
+ method public android.graphics.ColorFilter getColorFilter();
+ method public android.graphics.Paint getPaint();
+ method public void setActiveLevel(float);
+ }
+
+ public final class ColorOverlayDimmer {
+ method public int applyToColor(int);
+ method public static android.support.v17.leanback.graphics.ColorOverlayDimmer createColorOverlayDimmer(int, float, float);
+ method public static android.support.v17.leanback.graphics.ColorOverlayDimmer createDefault(android.content.Context);
+ method public void drawColorOverlay(android.graphics.Canvas, android.view.View, boolean);
+ method public int getAlpha();
+ method public float getAlphaFloat();
+ method public android.graphics.Paint getPaint();
+ method public boolean needsDraw();
+ method public void setActiveLevel(float);
+ }
+
+ public class CompositeDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
+ ctor public CompositeDrawable();
+ method public void addChildDrawable(android.graphics.drawable.Drawable);
+ method public void draw(android.graphics.Canvas);
+ method public android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable getChildAt(int);
+ method public int getChildCount();
+ method public android.graphics.drawable.Drawable getDrawable(int);
+ method public int getOpacity();
+ method public void invalidateDrawable(android.graphics.drawable.Drawable);
+ method public void removeChild(int);
+ method public void removeDrawable(android.graphics.drawable.Drawable);
+ method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
+ method public void setAlpha(int);
+ method public void setChildDrawableAt(int, android.graphics.drawable.Drawable);
+ method public void setColorFilter(android.graphics.ColorFilter);
+ method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
+ }
+
+ public static final class CompositeDrawable.ChildDrawable {
+ ctor public CompositeDrawable.ChildDrawable(android.graphics.drawable.Drawable, android.support.v17.leanback.graphics.CompositeDrawable);
+ method public android.support.v17.leanback.graphics.BoundsRule getBoundsRule();
+ method public android.graphics.drawable.Drawable getDrawable();
+ method public void recomputeBounds();
+ field public static final android.util.Property<android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable, java.lang.Integer> BOTTOM_ABSOLUTE;
+ field public static final android.util.Property<android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable, java.lang.Float> BOTTOM_FRACTION;
+ field public static final android.util.Property<android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable, java.lang.Integer> LEFT_ABSOLUTE;
+ field public static final android.util.Property<android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable, java.lang.Float> LEFT_FRACTION;
+ field public static final android.util.Property<android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable, java.lang.Integer> RIGHT_ABSOLUTE;
+ field public static final android.util.Property<android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable, java.lang.Float> RIGHT_FRACTION;
+ field public static final android.util.Property<android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable, java.lang.Integer> TOP_ABSOLUTE;
+ field public static final android.util.Property<android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable, java.lang.Float> TOP_FRACTION;
+ }
+
+ public class FitWidthBitmapDrawable extends android.graphics.drawable.Drawable {
+ ctor public FitWidthBitmapDrawable();
+ method public void draw(android.graphics.Canvas);
+ method public android.graphics.Bitmap getBitmap();
+ method public int getOpacity();
+ method public android.graphics.Rect getSource();
+ method public int getVerticalOffset();
+ method public void setAlpha(int);
+ method public void setBitmap(android.graphics.Bitmap);
+ method public void setColorFilter(android.graphics.ColorFilter);
+ method public void setSource(android.graphics.Rect);
+ method public void setVerticalOffset(int);
+ field public static final android.util.Property<android.support.v17.leanback.graphics.FitWidthBitmapDrawable, java.lang.Integer> PROPERTY_VERTICAL_OFFSET;
+ }
+
+}
+
+package android.support.v17.leanback.media {
+
+ public abstract class MediaControllerGlue extends android.support.v17.leanback.media.PlaybackControlGlue {
+ ctor public MediaControllerGlue(android.content.Context, int[], int[]);
+ method public void attachToMediaController(android.support.v4.media.session.MediaControllerCompat);
+ method public void detach();
+ method public int getCurrentPosition();
+ method public int getCurrentSpeedId();
+ method public android.graphics.drawable.Drawable getMediaArt();
+ method public final android.support.v4.media.session.MediaControllerCompat getMediaController();
+ method public int getMediaDuration();
+ method public java.lang.CharSequence getMediaSubtitle();
+ method public java.lang.CharSequence getMediaTitle();
+ method public long getSupportedActions();
+ method public boolean hasValidMedia();
+ method public boolean isMediaPlaying();
+ }
+
+ public abstract class PlaybackControlGlue extends android.support.v17.leanback.media.PlaybackGlue implements android.support.v17.leanback.widget.OnActionClickedListener android.view.View.OnKeyListener {
+ ctor public PlaybackControlGlue(android.content.Context, int[]);
+ ctor public PlaybackControlGlue(android.content.Context, int[], int[]);
+ method public void enableProgressUpdating(boolean);
+ method public android.support.v17.leanback.widget.PlaybackControlsRow getControlsRow();
+ method public android.support.v17.leanback.widget.PlaybackControlsRowPresenter getControlsRowPresenter();
+ method public abstract int getCurrentPosition();
+ method public abstract int getCurrentSpeedId();
+ method public int[] getFastForwardSpeeds();
+ method public abstract android.graphics.drawable.Drawable getMediaArt();
+ method public abstract int getMediaDuration();
+ method public abstract java.lang.CharSequence getMediaSubtitle();
+ method public abstract java.lang.CharSequence getMediaTitle();
+ method public int[] getRewindSpeeds();
+ method public abstract long getSupportedActions();
+ method public int getUpdatePeriod();
+ method public abstract boolean hasValidMedia();
+ method public boolean isFadingEnabled();
+ method public abstract boolean isMediaPlaying();
+ method public void onActionClicked(android.support.v17.leanback.widget.Action);
+ method protected void onCreateControlsRowAndPresenter();
+ method protected void onCreatePrimaryActions(android.support.v17.leanback.widget.SparseArrayObjectAdapter);
+ method protected void onCreateSecondaryActions(android.support.v17.leanback.widget.ArrayObjectAdapter);
+ method public boolean onKey(android.view.View, int, android.view.KeyEvent);
+ method protected void onMetadataChanged();
+ method protected void onStateChanged();
+ method public void play(int);
+ method public final void play();
+ method public void setControlsRow(android.support.v17.leanback.widget.PlaybackControlsRow);
+ method public void setControlsRowPresenter(android.support.v17.leanback.widget.PlaybackControlsRowPresenter);
+ method public void setFadingEnabled(boolean);
+ method public void updateProgress();
+ 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 abstract class PlaybackGlue {
+ ctor public PlaybackGlue(android.content.Context);
+ method public android.content.Context getContext();
+ method public android.support.v17.leanback.media.PlaybackGlueHost getHost();
+ method public boolean isReadyForPlayback();
+ method public void next();
+ method protected void onAttachedToHost(android.support.v17.leanback.media.PlaybackGlueHost);
+ method protected void onDetachedFromHost();
+ method protected void onHostPause();
+ method protected void onHostResume();
+ method protected void onHostStart();
+ method protected void onHostStop();
+ method public void pause();
+ method public void play();
+ method public void previous();
+ method public final void setHost(android.support.v17.leanback.media.PlaybackGlueHost);
+ method public void setPlayerCallback(android.support.v17.leanback.media.PlaybackGlue.PlayerCallback);
+ }
+
+ public static abstract class PlaybackGlue.PlayerCallback {
+ ctor public PlaybackGlue.PlayerCallback();
+ method public abstract void onReadyForPlayback();
+ }
+
+ public abstract class PlaybackGlueHost {
+ ctor public PlaybackGlueHost();
+ method public void fadeOut();
+ method public void notifyPlaybackRowChanged();
+ method public void setFadingEnabled(boolean);
+ method public void setHostCallback(android.support.v17.leanback.media.PlaybackGlueHost.HostCallback);
+ method public void setOnActionClickedListener(android.support.v17.leanback.widget.OnActionClickedListener);
+ method public void setOnKeyInterceptListener(android.view.View.OnKeyListener);
+ method public void setPlaybackRow(android.support.v17.leanback.widget.Row);
+ method public void setPlaybackRowPresenter(android.support.v17.leanback.widget.PlaybackRowPresenter);
+ }
+
+ public static abstract class PlaybackGlueHost.HostCallback {
+ ctor public PlaybackGlueHost.HostCallback();
+ method public void onHostDestroy();
+ method public void onHostPause();
+ method public void onHostResume();
+ method public void onHostStart();
+ method public void onHostStop();
+ }
+
+ public abstract interface SurfaceHolderGlueHost {
+ method public abstract void setSurfaceHolderCallback(android.view.SurfaceHolder.Callback);
+ }
+
+}
+
+package android.support.v17.leanback.system {
+
+ public class Settings {
+ method public boolean getBoolean(java.lang.String);
+ method public static android.support.v17.leanback.system.Settings getInstance(android.content.Context);
+ method public void setBoolean(java.lang.String, boolean);
+ field public static final java.lang.String PREFER_STATIC_SHADOWS = "PREFER_STATIC_SHADOWS";
+ }
+
+}
+
+package android.support.v17.leanback.widget {
+
+ public abstract class AbstractDetailsDescriptionPresenter extends android.support.v17.leanback.widget.Presenter {
+ ctor public AbstractDetailsDescriptionPresenter();
+ method protected abstract void onBindDescription(android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter.ViewHolder, java.lang.Object);
+ method public final void onBindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object);
+ method public final android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter.ViewHolder onCreateViewHolder(android.view.ViewGroup);
+ method public void onUnbindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+ }
+
+ public static class AbstractDetailsDescriptionPresenter.ViewHolder extends android.support.v17.leanback.widget.Presenter.ViewHolder {
+ ctor public AbstractDetailsDescriptionPresenter.ViewHolder(android.view.View);
+ method public android.widget.TextView getBody();
+ method public android.widget.TextView getSubtitle();
+ method public android.widget.TextView getTitle();
+ }
+
+ public abstract class AbstractMediaItemPresenter extends android.support.v17.leanback.widget.RowPresenter {
+ ctor public AbstractMediaItemPresenter();
+ ctor public AbstractMediaItemPresenter(int);
+ method protected android.support.v17.leanback.widget.RowPresenter.ViewHolder createRowViewHolder(android.view.ViewGroup);
+ method public android.support.v17.leanback.widget.Presenter getActionPresenter();
+ method protected int getMediaPlayState(java.lang.Object);
+ method public int getThemeId();
+ method public boolean hasMediaRowSeparator();
+ method protected abstract void onBindMediaDetails(android.support.v17.leanback.widget.AbstractMediaItemPresenter.ViewHolder, java.lang.Object);
+ method public void onBindMediaPlayState(android.support.v17.leanback.widget.AbstractMediaItemPresenter.ViewHolder);
+ method protected void onBindRowActions(android.support.v17.leanback.widget.AbstractMediaItemPresenter.ViewHolder);
+ method protected void onUnbindMediaDetails(android.support.v17.leanback.widget.AbstractMediaItemPresenter.ViewHolder);
+ method public void onUnbindMediaPlayState(android.support.v17.leanback.widget.AbstractMediaItemPresenter.ViewHolder);
+ method public void setActionPresenter(android.support.v17.leanback.widget.Presenter);
+ method public void setBackgroundColor(int);
+ method public void setHasMediaRowSeparator(boolean);
+ method public void setThemeId(int);
+ field public static final int PLAY_STATE_INITIAL = 0; // 0x0
+ field public static final int PLAY_STATE_PAUSED = 1; // 0x1
+ field public static final int PLAY_STATE_PLAYING = 2; // 0x2
+ }
+
+ public static class AbstractMediaItemPresenter.ViewHolder extends android.support.v17.leanback.widget.RowPresenter.ViewHolder {
+ ctor public AbstractMediaItemPresenter.ViewHolder(android.view.View);
+ method public android.view.ViewGroup getMediaItemActionsContainer();
+ method public android.view.View getMediaItemDetailsView();
+ method public android.widget.TextView getMediaItemDurationView();
+ method public android.widget.TextView getMediaItemNameView();
+ method public android.widget.TextView getMediaItemNumberView();
+ method public android.widget.ViewFlipper getMediaItemNumberViewFlipper();
+ method public android.view.View getMediaItemPausedView();
+ method public android.view.View getMediaItemPlayingView();
+ method public android.support.v17.leanback.widget.MultiActionsProvider.MultiAction[] getMediaItemRowActions();
+ method public android.view.View getMediaItemRowSeparator();
+ method public android.view.View getSelectorView();
+ method public void notifyActionChanged(android.support.v17.leanback.widget.MultiActionsProvider.MultiAction);
+ method public void notifyDetailsChanged();
+ method public void notifyPlayStateChanged();
+ method public void onBindRowActions();
+ method public void setSelectedMediaItemNumberView(int);
+ }
+
+ public abstract class AbstractMediaListHeaderPresenter extends android.support.v17.leanback.widget.RowPresenter {
+ ctor public AbstractMediaListHeaderPresenter(android.content.Context, int);
+ ctor public AbstractMediaListHeaderPresenter();
+ method protected android.support.v17.leanback.widget.RowPresenter.ViewHolder createRowViewHolder(android.view.ViewGroup);
+ method protected abstract void onBindMediaListHeaderViewHolder(android.support.v17.leanback.widget.AbstractMediaListHeaderPresenter.ViewHolder, java.lang.Object);
+ method public void setBackgroundColor(int);
+ }
+
+ public static class AbstractMediaListHeaderPresenter.ViewHolder extends android.support.v17.leanback.widget.RowPresenter.ViewHolder {
+ ctor public AbstractMediaListHeaderPresenter.ViewHolder(android.view.View);
+ method public android.widget.TextView getHeaderView();
+ }
+
+ public class Action {
+ ctor public Action(long);
+ ctor public Action(long, java.lang.CharSequence);
+ ctor public Action(long, java.lang.CharSequence, java.lang.CharSequence);
+ ctor public Action(long, java.lang.CharSequence, java.lang.CharSequence, android.graphics.drawable.Drawable);
+ method public final void addKeyCode(int);
+ method public final android.graphics.drawable.Drawable getIcon();
+ method public final long getId();
+ method public final java.lang.CharSequence getLabel1();
+ method public final java.lang.CharSequence getLabel2();
+ method public final void removeKeyCode(int);
+ method public final boolean respondsToKeyCode(int);
+ method public final void setIcon(android.graphics.drawable.Drawable);
+ method public final void setId(long);
+ method public final void setLabel1(java.lang.CharSequence);
+ method public final void setLabel2(java.lang.CharSequence);
+ field public static final long NO_ID = -1L; // 0xffffffffffffffffL
+ }
+
+ public class ArrayObjectAdapter extends android.support.v17.leanback.widget.ObjectAdapter {
+ ctor public ArrayObjectAdapter(android.support.v17.leanback.widget.PresenterSelector);
+ ctor public ArrayObjectAdapter(android.support.v17.leanback.widget.Presenter);
+ ctor public ArrayObjectAdapter();
+ method public void add(java.lang.Object);
+ method public void add(int, java.lang.Object);
+ method public void addAll(int, java.util.Collection);
+ method public void clear();
+ method public java.lang.Object get(int);
+ method public int indexOf(java.lang.Object);
+ method public void notifyArrayItemRangeChanged(int, int);
+ method public boolean remove(java.lang.Object);
+ method public int removeItems(int, int);
+ method public void replace(int, java.lang.Object);
+ method public int size();
+ method public <E> java.util.List<E> unmodifiableList();
+ }
+
+ public class BaseCardView extends android.widget.FrameLayout {
+ ctor public BaseCardView(android.content.Context);
+ ctor public BaseCardView(android.content.Context, android.util.AttributeSet);
+ ctor public BaseCardView(android.content.Context, android.util.AttributeSet, int);
+ method public int getCardType();
+ method public deprecated int getExtraVisibility();
+ method public int getInfoVisibility();
+ method public boolean isSelectedAnimationDelayed();
+ method public void setCardType(int);
+ method public deprecated void setExtraVisibility(int);
+ method public void setInfoVisibility(int);
+ method public void setSelectedAnimationDelayed(boolean);
+ field public static final int CARD_REGION_VISIBLE_ACTIVATED = 1; // 0x1
+ field public static final int CARD_REGION_VISIBLE_ALWAYS = 0; // 0x0
+ field public static final int CARD_REGION_VISIBLE_SELECTED = 2; // 0x2
+ field public static final int CARD_TYPE_INFO_OVER = 1; // 0x1
+ field public static final int CARD_TYPE_INFO_UNDER = 2; // 0x2
+ field public static final int CARD_TYPE_INFO_UNDER_WITH_EXTRA = 3; // 0x3
+ field public static final int CARD_TYPE_MAIN_ONLY = 0; // 0x0
+ }
+
+ public static class BaseCardView.LayoutParams extends android.widget.FrameLayout.LayoutParams {
+ ctor public BaseCardView.LayoutParams(android.content.Context, android.util.AttributeSet);
+ ctor public BaseCardView.LayoutParams(int, int);
+ ctor public BaseCardView.LayoutParams(android.view.ViewGroup.LayoutParams);
+ ctor public BaseCardView.LayoutParams(android.support.v17.leanback.widget.BaseCardView.LayoutParams);
+ field public static final int VIEW_TYPE_EXTRA = 2; // 0x2
+ field public static final int VIEW_TYPE_INFO = 1; // 0x1
+ field public static final int VIEW_TYPE_MAIN = 0; // 0x0
+ field public int viewType;
+ }
+
+ public abstract interface BaseOnItemViewClickedListener<T> {
+ method public abstract void onItemClicked(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object, android.support.v17.leanback.widget.RowPresenter.ViewHolder, T);
+ }
+
+ public abstract interface BaseOnItemViewSelectedListener<T> {
+ method public abstract void onItemSelected(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object, android.support.v17.leanback.widget.RowPresenter.ViewHolder, T);
+ }
+
+ public class BrowseFrameLayout extends android.widget.FrameLayout {
+ ctor public BrowseFrameLayout(android.content.Context);
+ ctor public BrowseFrameLayout(android.content.Context, android.util.AttributeSet);
+ ctor public BrowseFrameLayout(android.content.Context, android.util.AttributeSet, int);
+ method public android.support.v17.leanback.widget.BrowseFrameLayout.OnChildFocusListener getOnChildFocusListener();
+ method public android.support.v17.leanback.widget.BrowseFrameLayout.OnFocusSearchListener getOnFocusSearchListener();
+ method public void setOnChildFocusListener(android.support.v17.leanback.widget.BrowseFrameLayout.OnChildFocusListener);
+ method public void setOnDispatchKeyListener(android.view.View.OnKeyListener);
+ method public void setOnFocusSearchListener(android.support.v17.leanback.widget.BrowseFrameLayout.OnFocusSearchListener);
+ }
+
+ public static abstract interface BrowseFrameLayout.OnChildFocusListener {
+ method public abstract void onRequestChildFocus(android.view.View, android.view.View);
+ method public abstract boolean onRequestFocusInDescendants(int, android.graphics.Rect);
+ }
+
+ public static abstract interface BrowseFrameLayout.OnFocusSearchListener {
+ method public abstract android.view.View onFocusSearch(android.view.View, int);
+ }
+
+ public final class ClassPresenterSelector extends android.support.v17.leanback.widget.PresenterSelector {
+ ctor public ClassPresenterSelector();
+ method public android.support.v17.leanback.widget.ClassPresenterSelector addClassPresenter(java.lang.Class<?>, android.support.v17.leanback.widget.Presenter);
+ method public android.support.v17.leanback.widget.ClassPresenterSelector addClassPresenterSelector(java.lang.Class<?>, android.support.v17.leanback.widget.PresenterSelector);
+ method public android.support.v17.leanback.widget.Presenter getPresenter(java.lang.Object);
+ }
+
+ public class ControlButtonPresenterSelector extends android.support.v17.leanback.widget.PresenterSelector {
+ ctor public ControlButtonPresenterSelector();
+ method public android.support.v17.leanback.widget.Presenter getPresenter(java.lang.Object);
+ method public android.support.v17.leanback.widget.Presenter getPrimaryPresenter();
+ method public android.support.v17.leanback.widget.Presenter getSecondaryPresenter();
+ }
+
+ public class CursorObjectAdapter extends android.support.v17.leanback.widget.ObjectAdapter {
+ ctor public CursorObjectAdapter(android.support.v17.leanback.widget.PresenterSelector);
+ ctor public CursorObjectAdapter(android.support.v17.leanback.widget.Presenter);
+ ctor public CursorObjectAdapter();
+ method public void changeCursor(android.database.Cursor);
+ method public void close();
+ method public java.lang.Object get(int);
+ method public final android.database.Cursor getCursor();
+ method public final android.support.v17.leanback.database.CursorMapper getMapper();
+ method protected final void invalidateCache(int);
+ method protected final void invalidateCache(int, int);
+ method public boolean isClosed();
+ method protected void onCursorChanged();
+ method protected void onMapperChanged();
+ method public final void setMapper(android.support.v17.leanback.database.CursorMapper);
+ method public int size();
+ method public android.database.Cursor swapCursor(android.database.Cursor);
+ }
+
+ public class DetailsOverviewLogoPresenter extends android.support.v17.leanback.widget.Presenter {
+ ctor public DetailsOverviewLogoPresenter();
+ method public boolean isBoundToImage(android.support.v17.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder, android.support.v17.leanback.widget.DetailsOverviewRow);
+ method public void onBindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object);
+ method public android.view.View onCreateView(android.view.ViewGroup);
+ method public android.support.v17.leanback.widget.Presenter.ViewHolder onCreateViewHolder(android.view.ViewGroup);
+ method public void onUnbindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+ method public void setContext(android.support.v17.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter);
+ }
+
+ public static class DetailsOverviewLogoPresenter.ViewHolder extends android.support.v17.leanback.widget.Presenter.ViewHolder {
+ ctor public DetailsOverviewLogoPresenter.ViewHolder(android.view.View);
+ method public android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter getParentPresenter();
+ method public android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder getParentViewHolder();
+ method public boolean isSizeFromDrawableIntrinsic();
+ method public void setSizeFromDrawableIntrinsic(boolean);
+ field protected android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter mParentPresenter;
+ field protected android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder mParentViewHolder;
+ }
+
+ public class DetailsOverviewRow extends android.support.v17.leanback.widget.Row {
+ ctor public DetailsOverviewRow(java.lang.Object);
+ method public final deprecated void addAction(android.support.v17.leanback.widget.Action);
+ method public final deprecated void addAction(int, android.support.v17.leanback.widget.Action);
+ method public android.support.v17.leanback.widget.Action getActionForKeyCode(int);
+ method public final deprecated java.util.List<android.support.v17.leanback.widget.Action> getActions();
+ method public final android.support.v17.leanback.widget.ObjectAdapter getActionsAdapter();
+ method public final android.graphics.drawable.Drawable getImageDrawable();
+ method public final java.lang.Object getItem();
+ method public boolean isImageScaleUpAllowed();
+ method public final deprecated boolean removeAction(android.support.v17.leanback.widget.Action);
+ method public final void setActionsAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ method public final void setImageBitmap(android.content.Context, android.graphics.Bitmap);
+ method public final void setImageDrawable(android.graphics.drawable.Drawable);
+ method public void setImageScaleUpAllowed(boolean);
+ method public final void setItem(java.lang.Object);
+ }
+
+ public static class DetailsOverviewRow.Listener {
+ ctor public DetailsOverviewRow.Listener();
+ method public void onActionsAdapterChanged(android.support.v17.leanback.widget.DetailsOverviewRow);
+ method public void onImageDrawableChanged(android.support.v17.leanback.widget.DetailsOverviewRow);
+ method public void onItemChanged(android.support.v17.leanback.widget.DetailsOverviewRow);
+ }
+
+ public deprecated class DetailsOverviewRowPresenter extends android.support.v17.leanback.widget.RowPresenter {
+ ctor public DetailsOverviewRowPresenter(android.support.v17.leanback.widget.Presenter);
+ method protected android.support.v17.leanback.widget.RowPresenter.ViewHolder createRowViewHolder(android.view.ViewGroup);
+ method public int getBackgroundColor();
+ method public android.support.v17.leanback.widget.OnActionClickedListener getOnActionClickedListener();
+ method public boolean isStyleLarge();
+ method public final boolean isUsingDefaultSelectEffect();
+ method public void setBackgroundColor(int);
+ method public void setOnActionClickedListener(android.support.v17.leanback.widget.OnActionClickedListener);
+ method public final void setSharedElementEnterTransition(android.app.Activity, java.lang.String, long);
+ method public final void setSharedElementEnterTransition(android.app.Activity, java.lang.String);
+ method public void setStyleLarge(boolean);
+ }
+
+ public final class DetailsOverviewRowPresenter.ViewHolder extends android.support.v17.leanback.widget.RowPresenter.ViewHolder {
+ ctor public DetailsOverviewRowPresenter.ViewHolder(android.view.View, android.support.v17.leanback.widget.Presenter);
+ field public final android.support.v17.leanback.widget.Presenter.ViewHolder mDetailsDescriptionViewHolder;
+ }
+
+ public class DetailsParallax extends android.support.v17.leanback.widget.RecyclerViewParallax {
+ ctor public DetailsParallax();
+ method public android.support.v17.leanback.widget.Parallax.IntProperty getOverviewRowBottom();
+ method public android.support.v17.leanback.widget.Parallax.IntProperty getOverviewRowTop();
+ }
+
+ public class DividerPresenter extends android.support.v17.leanback.widget.Presenter {
+ ctor public DividerPresenter();
+ method public void onBindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object);
+ method public android.support.v17.leanback.widget.Presenter.ViewHolder onCreateViewHolder(android.view.ViewGroup);
+ method public void onUnbindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+ }
+
+ public class DividerRow extends android.support.v17.leanback.widget.Row {
+ ctor public DividerRow();
+ method public final boolean isRenderedAsRowView();
+ }
+
+ public abstract interface FacetProvider {
+ method public abstract java.lang.Object getFacet(java.lang.Class<?>);
+ }
+
+ public abstract interface FacetProviderAdapter {
+ method public abstract android.support.v17.leanback.widget.FacetProvider getFacetProvider(int);
+ }
+
+ public abstract interface FocusHighlight {
+ field public static final int ZOOM_FACTOR_LARGE = 3; // 0x3
+ field public static final int ZOOM_FACTOR_MEDIUM = 2; // 0x2
+ field public static final int ZOOM_FACTOR_NONE = 0; // 0x0
+ field public static final int ZOOM_FACTOR_SMALL = 1; // 0x1
+ field public static final int ZOOM_FACTOR_XSMALL = 4; // 0x4
+ }
+
+ public class FocusHighlightHelper {
+ ctor public FocusHighlightHelper();
+ method public static void setupBrowseItemFocusHighlight(android.support.v17.leanback.widget.ItemBridgeAdapter, int, boolean);
+ method public static void setupHeaderItemFocusHighlight(android.support.v17.leanback.widget.VerticalGridView);
+ method public static void setupHeaderItemFocusHighlight(android.support.v17.leanback.widget.VerticalGridView, boolean);
+ }
+
+ public abstract interface FragmentAnimationProvider {
+ method public abstract void onImeAppearing(java.util.List<android.animation.Animator>);
+ method public abstract void onImeDisappearing(java.util.List<android.animation.Animator>);
+ }
+
+ public class FullWidthDetailsOverviewRowPresenter extends android.support.v17.leanback.widget.RowPresenter {
+ ctor public FullWidthDetailsOverviewRowPresenter(android.support.v17.leanback.widget.Presenter);
+ ctor public FullWidthDetailsOverviewRowPresenter(android.support.v17.leanback.widget.Presenter, android.support.v17.leanback.widget.DetailsOverviewLogoPresenter);
+ method protected android.support.v17.leanback.widget.RowPresenter.ViewHolder createRowViewHolder(android.view.ViewGroup);
+ method public final int getActionsBackgroundColor();
+ method public final int getAlignmentMode();
+ method public final int getBackgroundColor();
+ method public final int getInitialState();
+ method protected int getLayoutResourceId();
+ method public android.support.v17.leanback.widget.OnActionClickedListener getOnActionClickedListener();
+ method public final boolean isParticipatingEntranceTransition();
+ method public final boolean isUsingDefaultSelectEffect();
+ method public final void notifyOnBindLogo(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder);
+ method protected void onLayoutLogo(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, boolean);
+ method protected void onLayoutOverviewFrame(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, boolean);
+ method protected void onStateChanged(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int);
+ method public final void setActionsBackgroundColor(int);
+ method public final void setAlignmentMode(int);
+ method public final void setBackgroundColor(int);
+ method public final void setInitialState(int);
+ method public final void setListener(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.Listener);
+ method public void setOnActionClickedListener(android.support.v17.leanback.widget.OnActionClickedListener);
+ method public final void setParticipatingEntranceTransition(boolean);
+ method public final void setState(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int);
+ field public static final int ALIGN_MODE_MIDDLE = 1; // 0x1
+ field public static final int ALIGN_MODE_START = 0; // 0x0
+ field public static final int STATE_FULL = 1; // 0x1
+ field public static final int STATE_HALF = 0; // 0x0
+ field public static final int STATE_SMALL = 2; // 0x2
+ field protected int mInitialState;
+ }
+
+ public static abstract class FullWidthDetailsOverviewRowPresenter.Listener {
+ ctor public FullWidthDetailsOverviewRowPresenter.Listener();
+ method public void onBindLogo(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder);
+ }
+
+ public class FullWidthDetailsOverviewRowPresenter.ViewHolder extends android.support.v17.leanback.widget.RowPresenter.ViewHolder {
+ ctor public FullWidthDetailsOverviewRowPresenter.ViewHolder(android.view.View, android.support.v17.leanback.widget.Presenter, android.support.v17.leanback.widget.DetailsOverviewLogoPresenter);
+ method protected android.support.v17.leanback.widget.DetailsOverviewRow.Listener createRowListener();
+ method public final android.view.ViewGroup getActionsRow();
+ method public final android.view.ViewGroup getDetailsDescriptionFrame();
+ method public final android.support.v17.leanback.widget.Presenter.ViewHolder getDetailsDescriptionViewHolder();
+ method public final android.support.v17.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder getLogoViewHolder();
+ method public final android.view.ViewGroup getOverviewView();
+ method public final int getState();
+ field protected final android.support.v17.leanback.widget.DetailsOverviewRow.Listener mRowListener;
+ }
+
+ public class FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener extends android.support.v17.leanback.widget.DetailsOverviewRow.Listener {
+ ctor public FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener();
+ }
+
+ public class FullWidthDetailsOverviewSharedElementHelper extends android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.Listener {
+ ctor public FullWidthDetailsOverviewSharedElementHelper();
+ method public boolean getAutoStartSharedElementTransition();
+ method public void setAutoStartSharedElementTransition(boolean);
+ method public void setSharedElementEnterTransition(android.app.Activity, java.lang.String);
+ method public void setSharedElementEnterTransition(android.app.Activity, java.lang.String, long);
+ method public void startPostponedEnterTransition();
+ }
+
+ public class GuidanceStylist implements android.support.v17.leanback.widget.FragmentAnimationProvider {
+ ctor public GuidanceStylist();
+ method public android.widget.TextView getBreadcrumbView();
+ method public android.widget.TextView getDescriptionView();
+ method public android.widget.ImageView getIconView();
+ method public android.widget.TextView getTitleView();
+ method public android.view.View onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.support.v17.leanback.widget.GuidanceStylist.Guidance);
+ method public void onDestroyView();
+ method public void onImeAppearing(java.util.List<android.animation.Animator>);
+ method public void onImeDisappearing(java.util.List<android.animation.Animator>);
+ method public int onProvideLayoutId();
+ }
+
+ public static class GuidanceStylist.Guidance {
+ ctor public GuidanceStylist.Guidance(java.lang.String, java.lang.String, java.lang.String, android.graphics.drawable.Drawable);
+ method public java.lang.String getBreadcrumb();
+ method public java.lang.String getDescription();
+ method public android.graphics.drawable.Drawable getIconDrawable();
+ method public java.lang.String getTitle();
+ }
+
+ public class GuidedAction extends android.support.v17.leanback.widget.Action {
+ ctor protected GuidedAction();
+ method public int getCheckSetId();
+ method public java.lang.CharSequence getDescription();
+ method public int getDescriptionEditInputType();
+ method public int getDescriptionInputType();
+ method public java.lang.CharSequence getEditDescription();
+ method public int getEditInputType();
+ method public java.lang.CharSequence getEditTitle();
+ method public int getInputType();
+ method public android.content.Intent getIntent();
+ method public java.util.List<android.support.v17.leanback.widget.GuidedAction> getSubActions();
+ method public java.lang.CharSequence getTitle();
+ method public boolean hasEditableActivatorView();
+ method public boolean hasMultilineDescription();
+ method public boolean hasNext();
+ method public boolean hasSubActions();
+ method public boolean hasTextEditable();
+ method public boolean infoOnly();
+ method public final boolean isAutoSaveRestoreEnabled();
+ method public boolean isChecked();
+ method public boolean isDescriptionEditable();
+ method public boolean isEditTitleUsed();
+ method public boolean isEditable();
+ method public boolean isEnabled();
+ method public boolean isFocusable();
+ method public void onRestoreInstanceState(android.os.Bundle, java.lang.String);
+ method public void onSaveInstanceState(android.os.Bundle, java.lang.String);
+ method public void setChecked(boolean);
+ method public void setDescription(java.lang.CharSequence);
+ method public void setEditDescription(java.lang.CharSequence);
+ method public void setEditTitle(java.lang.CharSequence);
+ method public void setEnabled(boolean);
+ method public void setFocusable(boolean);
+ method public void setIntent(android.content.Intent);
+ method public void setSubActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>);
+ method public void setTitle(java.lang.CharSequence);
+ field public static final long ACTION_ID_CANCEL = -5L; // 0xfffffffffffffffbL
+ field public static final long ACTION_ID_CONTINUE = -7L; // 0xfffffffffffffff9L
+ field public static final long ACTION_ID_CURRENT = -3L; // 0xfffffffffffffffdL
+ field public static final long ACTION_ID_FINISH = -6L; // 0xfffffffffffffffaL
+ field public static final long ACTION_ID_NEXT = -2L; // 0xfffffffffffffffeL
+ field public static final long ACTION_ID_NO = -9L; // 0xfffffffffffffff7L
+ field public static final long ACTION_ID_OK = -4L; // 0xfffffffffffffffcL
+ field public static final long ACTION_ID_YES = -8L; // 0xfffffffffffffff8L
+ field public static final int CHECKBOX_CHECK_SET_ID = -1; // 0xffffffff
+ field public static final int DEFAULT_CHECK_SET_ID = 1; // 0x1
+ field public static final int NO_CHECK_SET = 0; // 0x0
+ }
+
+ public static class GuidedAction.Builder extends android.support.v17.leanback.widget.GuidedAction.BuilderBase {
+ ctor public deprecated GuidedAction.Builder();
+ ctor public GuidedAction.Builder(android.content.Context);
+ method public android.support.v17.leanback.widget.GuidedAction build();
+ }
+
+ public static abstract class GuidedAction.BuilderBase<B extends android.support.v17.leanback.widget.GuidedAction.BuilderBase> {
+ ctor public GuidedAction.BuilderBase(android.content.Context);
+ method protected final void applyValues(android.support.v17.leanback.widget.GuidedAction);
+ method public B autoSaveRestoreEnabled(boolean);
+ method public B checkSetId(int);
+ method public B checked(boolean);
+ method public B clickAction(long);
+ method public B description(java.lang.CharSequence);
+ method public B description(int);
+ method public B descriptionEditInputType(int);
+ method public B descriptionEditable(boolean);
+ method public B descriptionInputType(int);
+ method public B editDescription(java.lang.CharSequence);
+ method public B editDescription(int);
+ method public B editInputType(int);
+ method public B editTitle(java.lang.CharSequence);
+ method public B editTitle(int);
+ method public B editable(boolean);
+ method public B enabled(boolean);
+ method public B focusable(boolean);
+ method public android.content.Context getContext();
+ method public B hasEditableActivatorView(boolean);
+ method public B hasNext(boolean);
+ method public B icon(android.graphics.drawable.Drawable);
+ method public B icon(int);
+ method public deprecated B iconResourceId(int, android.content.Context);
+ method public B id(long);
+ method public B infoOnly(boolean);
+ method public B inputType(int);
+ method public B intent(android.content.Intent);
+ method public B multilineDescription(boolean);
+ method public B subActions(java.util.List<android.support.v17.leanback.widget.GuidedAction>);
+ method public B title(java.lang.CharSequence);
+ method public B title(int);
+ }
+
+ public class GuidedActionEditText extends android.widget.EditText implements android.support.v17.leanback.widget.ImeKeyMonitor {
+ ctor public GuidedActionEditText(android.content.Context);
+ ctor public GuidedActionEditText(android.content.Context, android.util.AttributeSet);
+ ctor public GuidedActionEditText(android.content.Context, android.util.AttributeSet, int);
+ method public void setImeKeyListener(android.support.v17.leanback.widget.ImeKeyMonitor.ImeKeyListener);
+ }
+
+ public class GuidedActionsStylist implements android.support.v17.leanback.widget.FragmentAnimationProvider {
+ ctor public GuidedActionsStylist();
+ method public void collapseAction(boolean);
+ method public void expandAction(android.support.v17.leanback.widget.GuidedAction, boolean);
+ method public android.support.v17.leanback.widget.VerticalGridView getActionsGridView();
+ method public android.support.v17.leanback.widget.GuidedAction getExpandedAction();
+ method public int getItemViewType(android.support.v17.leanback.widget.GuidedAction);
+ method public android.support.v17.leanback.widget.VerticalGridView getSubActionsGridView();
+ method public final boolean isBackKeyToCollapseActivatorView();
+ method public final boolean isBackKeyToCollapseSubActions();
+ method public boolean isButtonActions();
+ method public boolean isExpandTransitionSupported();
+ method public boolean isExpanded();
+ method public boolean isInExpandTransition();
+ method public boolean isSubActionsExpanded();
+ method public void onAnimateItemChecked(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, boolean);
+ method public void onAnimateItemFocused(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, boolean);
+ method public void onAnimateItemPressed(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, boolean);
+ method public void onAnimateItemPressedCancelled(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder);
+ method public void onBindActivatorView(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, android.support.v17.leanback.widget.GuidedAction);
+ method public void onBindCheckMarkView(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, android.support.v17.leanback.widget.GuidedAction);
+ method public void onBindChevronView(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, android.support.v17.leanback.widget.GuidedAction);
+ method public void onBindViewHolder(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, android.support.v17.leanback.widget.GuidedAction);
+ method public android.view.View onCreateView(android.view.LayoutInflater, android.view.ViewGroup);
+ method public android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder onCreateViewHolder(android.view.ViewGroup);
+ method public android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder onCreateViewHolder(android.view.ViewGroup, int);
+ method public void onDestroyView();
+ method protected deprecated void onEditingModeChange(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, android.support.v17.leanback.widget.GuidedAction, boolean);
+ method protected void onEditingModeChange(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, boolean, boolean);
+ method public void onImeAppearing(java.util.List<android.animation.Animator>);
+ method public void onImeDisappearing(java.util.List<android.animation.Animator>);
+ method public int onProvideItemLayoutId();
+ method public int onProvideItemLayoutId(int);
+ method public int onProvideLayoutId();
+ method public boolean onUpdateActivatorView(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, android.support.v17.leanback.widget.GuidedAction);
+ method public void onUpdateExpandedViewHolder(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder);
+ method public void setAsButtonActions();
+ method public final void setBackKeyToCollapseActivatorView(boolean);
+ method public final void setBackKeyToCollapseSubActions(boolean);
+ method public deprecated void setEditingMode(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, android.support.v17.leanback.widget.GuidedAction, boolean);
+ method public deprecated void setExpandedViewHolder(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder);
+ method protected void setupImeOptions(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder, android.support.v17.leanback.widget.GuidedAction);
+ method public deprecated void startExpandedTransition(android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder);
+ field public static final int VIEW_TYPE_DATE_PICKER = 1; // 0x1
+ field public static final int VIEW_TYPE_DEFAULT = 0; // 0x0
+ }
+
+ public static class GuidedActionsStylist.ViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder implements android.support.v17.leanback.widget.FacetProvider {
+ ctor public GuidedActionsStylist.ViewHolder(android.view.View);
+ ctor public GuidedActionsStylist.ViewHolder(android.view.View, boolean);
+ method public android.support.v17.leanback.widget.GuidedAction getAction();
+ method public android.widget.ImageView getCheckmarkView();
+ method public android.widget.ImageView getChevronView();
+ method public android.view.View getContentView();
+ method public android.widget.TextView getDescriptionView();
+ method public android.widget.EditText getEditableDescriptionView();
+ method public android.widget.EditText getEditableTitleView();
+ method public android.view.View getEditingView();
+ method public java.lang.Object getFacet(java.lang.Class<?>);
+ method public android.widget.ImageView getIconView();
+ method public android.widget.TextView getTitleView();
+ method public boolean isInEditing();
+ method public boolean isInEditingActivatorView();
+ method public boolean isInEditingDescription();
+ method public boolean isInEditingText();
+ method public boolean isInEditingTitle();
+ method public boolean isSubAction();
+ }
+
+ public class GuidedDatePickerAction extends android.support.v17.leanback.widget.GuidedAction {
+ ctor public GuidedDatePickerAction();
+ method public long getDate();
+ method public java.lang.String getDatePickerFormat();
+ method public long getMaxDate();
+ method public long getMinDate();
+ method public void setDate(long);
+ }
+
+ public static final class GuidedDatePickerAction.Builder extends android.support.v17.leanback.widget.GuidedDatePickerAction.BuilderBase {
+ ctor public GuidedDatePickerAction.Builder(android.content.Context);
+ method public android.support.v17.leanback.widget.GuidedDatePickerAction build();
+ }
+
+ public static abstract class GuidedDatePickerAction.BuilderBase<B extends android.support.v17.leanback.widget.GuidedDatePickerAction.BuilderBase> extends android.support.v17.leanback.widget.GuidedAction.BuilderBase {
+ ctor public GuidedDatePickerAction.BuilderBase(android.content.Context);
+ method protected final void applyDatePickerValues(android.support.v17.leanback.widget.GuidedDatePickerAction);
+ method public B date(long);
+ method public B datePickerFormat(java.lang.String);
+ method public B maxDate(long);
+ method public B minDate(long);
+ }
+
+ public class HeaderItem {
+ ctor public HeaderItem(long, java.lang.String);
+ ctor public HeaderItem(java.lang.String);
+ method public java.lang.CharSequence getContentDescription();
+ method public java.lang.CharSequence getDescription();
+ method public final long getId();
+ method public final java.lang.String getName();
+ method public void setContentDescription(java.lang.CharSequence);
+ method public void setDescription(java.lang.CharSequence);
+ }
+
+ public class HorizontalGridView extends android.support.v7.widget.RecyclerView {
+ ctor public HorizontalGridView(android.content.Context);
+ ctor public HorizontalGridView(android.content.Context, android.util.AttributeSet);
+ ctor public HorizontalGridView(android.content.Context, android.util.AttributeSet, int);
+ method public final boolean getFadingLeftEdge();
+ method public final int getFadingLeftEdgeLength();
+ method public final int getFadingLeftEdgeOffset();
+ method public final boolean getFadingRightEdge();
+ method public final int getFadingRightEdgeLength();
+ method public final int getFadingRightEdgeOffset();
+ method protected void initAttributes(android.content.Context, android.util.AttributeSet);
+ method public final void setFadingLeftEdge(boolean);
+ method public final void setFadingLeftEdgeLength(int);
+ method public final void setFadingLeftEdgeOffset(int);
+ method public final void setFadingRightEdge(boolean);
+ method public final void setFadingRightEdgeLength(int);
+ method public final void setFadingRightEdgeOffset(int);
+ method public void setNumRows(int);
+ method public void setRowHeight(int);
+ }
+
+ public final class HorizontalHoverCardSwitcher extends android.support.v17.leanback.widget.PresenterSwitcher {
+ ctor public HorizontalHoverCardSwitcher();
+ method protected void insertView(android.view.View);
+ method public void select(android.support.v17.leanback.widget.HorizontalGridView, android.view.View, java.lang.Object);
+ }
+
+ public class ImageCardView extends android.support.v17.leanback.widget.BaseCardView {
+ ctor public deprecated ImageCardView(android.content.Context, int);
+ ctor public ImageCardView(android.content.Context, android.util.AttributeSet, int);
+ ctor public ImageCardView(android.content.Context);
+ ctor public ImageCardView(android.content.Context, android.util.AttributeSet);
+ method public android.graphics.drawable.Drawable getBadgeImage();
+ method public java.lang.CharSequence getContentText();
+ method public android.graphics.drawable.Drawable getInfoAreaBackground();
+ method public android.graphics.drawable.Drawable getMainImage();
+ method public final android.widget.ImageView getMainImageView();
+ method public java.lang.CharSequence getTitleText();
+ method public void setBadgeImage(android.graphics.drawable.Drawable);
+ method public void setContentText(java.lang.CharSequence);
+ method public void setInfoAreaBackground(android.graphics.drawable.Drawable);
+ method public void setInfoAreaBackgroundColor(int);
+ method public void setMainImage(android.graphics.drawable.Drawable);
+ method public void setMainImage(android.graphics.drawable.Drawable, boolean);
+ method public void setMainImageAdjustViewBounds(boolean);
+ method public void setMainImageDimensions(int, int);
+ method public void setMainImageScaleType(android.widget.ImageView.ScaleType);
+ method public void setTitleText(java.lang.CharSequence);
+ field public static final int CARD_TYPE_FLAG_CONTENT = 2; // 0x2
+ field public static final int CARD_TYPE_FLAG_ICON_LEFT = 8; // 0x8
+ field public static final int CARD_TYPE_FLAG_ICON_RIGHT = 4; // 0x4
+ field public static final int CARD_TYPE_FLAG_IMAGE_ONLY = 0; // 0x0
+ field public static final int CARD_TYPE_FLAG_TITLE = 1; // 0x1
+ }
+
+ public abstract interface ImeKeyMonitor {
+ method public abstract void setImeKeyListener(android.support.v17.leanback.widget.ImeKeyMonitor.ImeKeyListener);
+ }
+
+ public static abstract interface ImeKeyMonitor.ImeKeyListener {
+ method public abstract boolean onKeyPreIme(android.widget.EditText, int, android.view.KeyEvent);
+ }
+
+ public final class ItemAlignmentFacet {
+ ctor public ItemAlignmentFacet();
+ method public android.support.v17.leanback.widget.ItemAlignmentFacet.ItemAlignmentDef[] getAlignmentDefs();
+ method public boolean isMultiAlignment();
+ method public void setAlignmentDefs(android.support.v17.leanback.widget.ItemAlignmentFacet.ItemAlignmentDef[]);
+ field public static final float ITEM_ALIGN_OFFSET_PERCENT_DISABLED = -1.0f;
+ }
+
+ public static class ItemAlignmentFacet.ItemAlignmentDef {
+ ctor public ItemAlignmentFacet.ItemAlignmentDef();
+ method public final int getItemAlignmentFocusViewId();
+ method public final int getItemAlignmentOffset();
+ method public final float getItemAlignmentOffsetPercent();
+ method public final int getItemAlignmentViewId();
+ method public boolean isAlignedToTextViewBaseLine();
+ method public final boolean isItemAlignmentOffsetWithPadding();
+ method public final void setAlignedToTextViewBaseline(boolean);
+ method public final void setItemAlignmentFocusViewId(int);
+ method public final void setItemAlignmentOffset(int);
+ method public final void setItemAlignmentOffsetPercent(float);
+ method public final void setItemAlignmentOffsetWithPadding(boolean);
+ method public final void setItemAlignmentViewId(int);
+ }
+
+ public class ItemBridgeAdapter extends android.support.v7.widget.RecyclerView.Adapter implements android.support.v17.leanback.widget.FacetProviderAdapter {
+ ctor public ItemBridgeAdapter(android.support.v17.leanback.widget.ObjectAdapter, android.support.v17.leanback.widget.PresenterSelector);
+ ctor public ItemBridgeAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ ctor public ItemBridgeAdapter();
+ method public void clear();
+ method public android.support.v17.leanback.widget.FacetProvider getFacetProvider(int);
+ method public int getItemCount();
+ method public java.util.ArrayList<android.support.v17.leanback.widget.Presenter> getPresenterMapper();
+ method public android.support.v17.leanback.widget.ItemBridgeAdapter.Wrapper getWrapper();
+ method protected void onAddPresenter(android.support.v17.leanback.widget.Presenter, int);
+ method protected void onAttachedToWindow(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+ method protected void onBind(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+ method public final void onBindViewHolder(android.support.v7.widget.RecyclerView.ViewHolder, int);
+ method protected void onCreate(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+ method public final android.support.v7.widget.RecyclerView.ViewHolder onCreateViewHolder(android.view.ViewGroup, int);
+ method protected void onDetachedFromWindow(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+ method protected void onUnbind(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+ method public final void onViewAttachedToWindow(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public final void onViewDetachedFromWindow(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public final void onViewRecycled(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public void setAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ method public void setAdapterListener(android.support.v17.leanback.widget.ItemBridgeAdapter.AdapterListener);
+ method public void setPresenter(android.support.v17.leanback.widget.PresenterSelector);
+ method public void setPresenterMapper(java.util.ArrayList<android.support.v17.leanback.widget.Presenter>);
+ method public void setWrapper(android.support.v17.leanback.widget.ItemBridgeAdapter.Wrapper);
+ }
+
+ public static class ItemBridgeAdapter.AdapterListener {
+ ctor public ItemBridgeAdapter.AdapterListener();
+ method public void onAddPresenter(android.support.v17.leanback.widget.Presenter, int);
+ method public void onAttachedToWindow(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+ method public void onBind(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+ method public void onCreate(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+ method public void onDetachedFromWindow(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+ method public void onUnbind(android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder);
+ }
+
+ public class ItemBridgeAdapter.ViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder implements android.support.v17.leanback.widget.FacetProvider {
+ method public final java.lang.Object getExtraObject();
+ method public java.lang.Object getFacet(java.lang.Class<?>);
+ method public final java.lang.Object getItem();
+ method public final android.support.v17.leanback.widget.Presenter getPresenter();
+ method public final android.support.v17.leanback.widget.Presenter.ViewHolder getViewHolder();
+ method public void setExtraObject(java.lang.Object);
+ }
+
+ public static abstract class ItemBridgeAdapter.Wrapper {
+ ctor public ItemBridgeAdapter.Wrapper();
+ method public abstract android.view.View createWrapper(android.view.View);
+ method public abstract void wrap(android.view.View, android.view.View);
+ }
+
+ public class ItemBridgeAdapterShadowOverlayWrapper extends android.support.v17.leanback.widget.ItemBridgeAdapter.Wrapper {
+ ctor public ItemBridgeAdapterShadowOverlayWrapper(android.support.v17.leanback.widget.ShadowOverlayHelper);
+ method public android.view.View createWrapper(android.view.View);
+ method public void wrap(android.view.View, android.view.View);
+ }
+
+ public class ListRow extends android.support.v17.leanback.widget.Row {
+ ctor public ListRow(android.support.v17.leanback.widget.HeaderItem, android.support.v17.leanback.widget.ObjectAdapter);
+ ctor public ListRow(long, android.support.v17.leanback.widget.HeaderItem, android.support.v17.leanback.widget.ObjectAdapter);
+ ctor public ListRow(android.support.v17.leanback.widget.ObjectAdapter);
+ method public final android.support.v17.leanback.widget.ObjectAdapter getAdapter();
+ method public java.lang.CharSequence getContentDescription();
+ method public void setContentDescription(java.lang.CharSequence);
+ }
+
+ public final class ListRowHoverCardView extends android.widget.LinearLayout {
+ ctor public ListRowHoverCardView(android.content.Context);
+ ctor public ListRowHoverCardView(android.content.Context, android.util.AttributeSet);
+ ctor public ListRowHoverCardView(android.content.Context, android.util.AttributeSet, int);
+ method public final java.lang.CharSequence getDescription();
+ method public final java.lang.CharSequence getTitle();
+ method public final void setDescription(java.lang.CharSequence);
+ method public final void setTitle(java.lang.CharSequence);
+ }
+
+ public class ListRowPresenter extends android.support.v17.leanback.widget.RowPresenter {
+ ctor public ListRowPresenter();
+ ctor public ListRowPresenter(int);
+ ctor public ListRowPresenter(int, boolean);
+ method public final boolean areChildRoundedCornersEnabled();
+ method protected android.support.v17.leanback.widget.RowPresenter.ViewHolder createRowViewHolder(android.view.ViewGroup);
+ method protected android.support.v17.leanback.widget.ShadowOverlayHelper.Options createShadowOverlayOptions();
+ method public final void enableChildRoundedCorners(boolean);
+ method public int getExpandedRowHeight();
+ method public final int getFocusZoomFactor();
+ method public final android.support.v17.leanback.widget.PresenterSelector getHoverCardPresenterSelector();
+ method public int getRecycledPoolSize(android.support.v17.leanback.widget.Presenter);
+ method public int getRowHeight();
+ method public final boolean getShadowEnabled();
+ method public final deprecated int getZoomFactor();
+ method public final boolean isFocusDimmerUsed();
+ method public final boolean isKeepChildForeground();
+ method public boolean isUsingDefaultListSelectEffect();
+ method public final boolean isUsingDefaultSelectEffect();
+ method public boolean isUsingDefaultShadow();
+ method public boolean isUsingZOrder(android.content.Context);
+ method public void setExpandedRowHeight(int);
+ method public final void setHoverCardPresenterSelector(android.support.v17.leanback.widget.PresenterSelector);
+ method public final void setKeepChildForeground(boolean);
+ method public void setNumRows(int);
+ method public void setRecycledPoolSize(android.support.v17.leanback.widget.Presenter, int);
+ method public void setRowHeight(int);
+ method public final void setShadowEnabled(boolean);
+ }
+
+ public static class ListRowPresenter.SelectItemViewHolderTask extends android.support.v17.leanback.widget.Presenter.ViewHolderTask {
+ ctor public ListRowPresenter.SelectItemViewHolderTask(int);
+ method public int getItemPosition();
+ method public android.support.v17.leanback.widget.Presenter.ViewHolderTask getItemTask();
+ method public boolean isSmoothScroll();
+ method public void setItemPosition(int);
+ method public void setItemTask(android.support.v17.leanback.widget.Presenter.ViewHolderTask);
+ method public void setSmoothScroll(boolean);
+ }
+
+ public static class ListRowPresenter.ViewHolder extends android.support.v17.leanback.widget.RowPresenter.ViewHolder {
+ ctor public ListRowPresenter.ViewHolder(android.view.View, android.support.v17.leanback.widget.HorizontalGridView, android.support.v17.leanback.widget.ListRowPresenter);
+ method public final android.support.v17.leanback.widget.ItemBridgeAdapter getBridgeAdapter();
+ method public final android.support.v17.leanback.widget.HorizontalGridView getGridView();
+ method public android.support.v17.leanback.widget.Presenter.ViewHolder getItemViewHolder(int);
+ method public final android.support.v17.leanback.widget.ListRowPresenter getListRowPresenter();
+ method public int getSelectedPosition();
+ }
+
+ public final class ListRowView extends android.widget.LinearLayout {
+ ctor public ListRowView(android.content.Context);
+ ctor public ListRowView(android.content.Context, android.util.AttributeSet);
+ ctor public ListRowView(android.content.Context, android.util.AttributeSet, int);
+ method public android.support.v17.leanback.widget.HorizontalGridView getGridView();
+ }
+
+ public abstract interface MultiActionsProvider {
+ method public abstract android.support.v17.leanback.widget.MultiActionsProvider.MultiAction[] getActions();
+ }
+
+ public static class MultiActionsProvider.MultiAction {
+ ctor public MultiActionsProvider.MultiAction(long);
+ method public android.graphics.drawable.Drawable getCurrentDrawable();
+ method public android.graphics.drawable.Drawable[] getDrawables();
+ method public long getId();
+ method public int getIndex();
+ method public void incrementIndex();
+ method public void setDrawables(android.graphics.drawable.Drawable[]);
+ method public void setIndex(int);
+ }
+
+ public abstract class ObjectAdapter {
+ ctor public ObjectAdapter(android.support.v17.leanback.widget.PresenterSelector);
+ ctor public ObjectAdapter(android.support.v17.leanback.widget.Presenter);
+ ctor public ObjectAdapter();
+ method public abstract java.lang.Object get(int);
+ method public long getId(int);
+ method public final android.support.v17.leanback.widget.Presenter getPresenter(java.lang.Object);
+ method public final android.support.v17.leanback.widget.PresenterSelector getPresenterSelector();
+ method public final boolean hasStableIds();
+ method public boolean isImmediateNotifySupported();
+ method protected final void notifyChanged();
+ method public final void notifyItemRangeChanged(int, int);
+ method protected final void notifyItemRangeInserted(int, int);
+ method protected final void notifyItemRangeRemoved(int, int);
+ method protected void onHasStableIdsChanged();
+ method protected void onPresenterSelectorChanged();
+ method public final void registerObserver(android.support.v17.leanback.widget.ObjectAdapter.DataObserver);
+ method public final void setHasStableIds(boolean);
+ method public final void setPresenterSelector(android.support.v17.leanback.widget.PresenterSelector);
+ method public abstract int size();
+ method public final void unregisterAllObservers();
+ method public final void unregisterObserver(android.support.v17.leanback.widget.ObjectAdapter.DataObserver);
+ field public static final int NO_ID = -1; // 0xffffffff
+ }
+
+ public static abstract class ObjectAdapter.DataObserver {
+ ctor public ObjectAdapter.DataObserver();
+ method public void onChanged();
+ method public void onItemRangeChanged(int, int);
+ method public void onItemRangeInserted(int, int);
+ method public void onItemRangeRemoved(int, int);
+ }
+
+ public abstract interface OnActionClickedListener {
+ method public abstract void onActionClicked(android.support.v17.leanback.widget.Action);
+ }
+
+ public abstract interface OnChildLaidOutListener {
+ method public abstract void onChildLaidOut(android.view.ViewGroup, android.view.View, int, long);
+ }
+
+ public abstract deprecated interface OnChildSelectedListener {
+ method public abstract void onChildSelected(android.view.ViewGroup, android.view.View, int, long);
+ }
+
+ public abstract class OnChildViewHolderSelectedListener {
+ ctor public OnChildViewHolderSelectedListener();
+ method public void onChildViewHolderSelected(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder, int, int);
+ method public void onChildViewHolderSelectedAndPositioned(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder, int, int);
+ }
+
+ public abstract interface OnItemViewClickedListener implements android.support.v17.leanback.widget.BaseOnItemViewClickedListener {
+ }
+
+ public abstract interface OnItemViewSelectedListener implements android.support.v17.leanback.widget.BaseOnItemViewSelectedListener {
+ }
+
+ public class PageRow extends android.support.v17.leanback.widget.Row {
+ ctor public PageRow(android.support.v17.leanback.widget.HeaderItem);
+ method public final boolean isRenderedAsRowView();
+ }
+
+ public abstract class Parallax<PropertyT extends android.util.Property> {
+ ctor public Parallax();
+ method public void addEffect(android.support.v17.leanback.widget.ParallaxEffect);
+ method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue...);
+ method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue...);
+ method public abstract PropertyT addProperty(java.lang.String);
+ method public abstract PropertyT createProperty(java.lang.String, int);
+ method public java.util.List<android.support.v17.leanback.widget.ParallaxEffect> getEffects();
+ method public final java.util.List<PropertyT> getProperties();
+ method public void removeAllEffects();
+ method public void removeEffect(android.support.v17.leanback.widget.ParallaxEffect);
+ method public void updateValues();
+ method public abstract void verifyProperties() throws java.lang.IllegalStateException;
+ }
+
+ public static abstract class Parallax.FloatParallax<FloatPropertyT extends android.support.v17.leanback.widget.Parallax.FloatProperty> extends android.support.v17.leanback.widget.Parallax {
+ ctor public Parallax.FloatParallax();
+ method public final FloatPropertyT addProperty(java.lang.String);
+ method public abstract float getMaxValue();
+ method public final float getPropertyValue(int);
+ method public final void setPropertyValue(int, float);
+ method public final void verifyProperties() throws java.lang.IllegalStateException;
+ }
+
+ public static class Parallax.FloatProperty extends android.util.Property {
+ ctor public Parallax.FloatProperty(java.lang.String, int);
+ method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue at(float, float);
+ method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue atAbsolute(float);
+ method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue atFraction(float);
+ method public final java.lang.Float get(android.support.v17.leanback.widget.Parallax.FloatParallax);
+ method public final int getIndex();
+ method public final void set(android.support.v17.leanback.widget.Parallax.FloatParallax, java.lang.Float);
+ field public static final float UNKNOWN_AFTER = 3.4028235E38f;
+ field public static final float UNKNOWN_BEFORE = -3.4028235E38f;
+ }
+
+ public static class Parallax.FloatPropertyMarkerValue extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue {
+ ctor public Parallax.FloatPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.FloatProperty, float);
+ ctor public Parallax.FloatPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.FloatProperty, float, float);
+ method public final float getMarkerValue(android.support.v17.leanback.widget.Parallax.FloatParallax);
+ }
+
+ public static abstract class Parallax.IntParallax<IntPropertyT extends android.support.v17.leanback.widget.Parallax.IntProperty> extends android.support.v17.leanback.widget.Parallax {
+ ctor public Parallax.IntParallax();
+ method public final IntPropertyT addProperty(java.lang.String);
+ method public abstract int getMaxValue();
+ method public final int getPropertyValue(int);
+ method public final void setPropertyValue(int, int);
+ method public final void verifyProperties() throws java.lang.IllegalStateException;
+ }
+
+ public static class Parallax.IntProperty extends android.util.Property {
+ ctor public Parallax.IntProperty(java.lang.String, int);
+ method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue at(int, float);
+ method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue atAbsolute(int);
+ method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue atFraction(float);
+ method public final java.lang.Integer get(android.support.v17.leanback.widget.Parallax.IntParallax);
+ method public final int getIndex();
+ method public final void set(android.support.v17.leanback.widget.Parallax.IntParallax, java.lang.Integer);
+ field public static final int UNKNOWN_AFTER = 2147483647; // 0x7fffffff
+ field public static final int UNKNOWN_BEFORE = -2147483648; // 0x80000000
+ }
+
+ public static class Parallax.IntPropertyMarkerValue extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue {
+ ctor public Parallax.IntPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.IntProperty, int);
+ ctor public Parallax.IntPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.IntProperty, int, float);
+ method public final int getMarkerValue(android.support.v17.leanback.widget.Parallax.IntParallax);
+ }
+
+ public static class Parallax.PropertyMarkerValue<PropertyT> {
+ ctor public Parallax.PropertyMarkerValue(PropertyT);
+ method public PropertyT getProperty();
+ }
+
+ public abstract class ParallaxEffect<ParallaxEffectT extends android.support.v17.leanback.widget.ParallaxEffect, PropertyMarkerValueT extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue> {
+ ctor public ParallaxEffect();
+ method public final void addTarget(android.support.v17.leanback.widget.ParallaxTarget);
+ method protected abstract float calculateFraction(android.support.v17.leanback.widget.Parallax);
+ method public final java.util.List<PropertyMarkerValueT> getPropertyRanges();
+ method public final java.util.List<android.support.v17.leanback.widget.ParallaxTarget> getTargets();
+ method public final void performMapping(android.support.v17.leanback.widget.Parallax);
+ method public final void removeTarget(android.support.v17.leanback.widget.ParallaxTarget);
+ method public final void setPropertyRanges(PropertyMarkerValueT...);
+ method public final android.support.v17.leanback.widget.ParallaxEffect target(android.support.v17.leanback.widget.ParallaxTarget);
+ method public final android.support.v17.leanback.widget.ParallaxEffect target(java.lang.Object, android.animation.PropertyValuesHolder);
+ }
+
+ public static final class ParallaxEffect.FloatEffect extends android.support.v17.leanback.widget.ParallaxEffect {
+ ctor public ParallaxEffect.FloatEffect();
+ method protected float calculateFraction(android.support.v17.leanback.widget.Parallax);
+ }
+
+ public static final class ParallaxEffect.IntEffect extends android.support.v17.leanback.widget.ParallaxEffect {
+ ctor public ParallaxEffect.IntEffect();
+ method protected float calculateFraction(android.support.v17.leanback.widget.Parallax);
+ }
+
+ public abstract class ParallaxTarget {
+ ctor public ParallaxTarget();
+ method public abstract float getFraction();
+ method public abstract void update(float);
+ }
+
+ public static final class ParallaxTarget.PropertyValuesHolderTarget extends android.support.v17.leanback.widget.ParallaxTarget {
+ ctor public ParallaxTarget.PropertyValuesHolderTarget(java.lang.Object, android.animation.PropertyValuesHolder);
+ method public float getFraction();
+ method public void update(float);
+ }
+
+ public class PlaybackControlsRow extends android.support.v17.leanback.widget.Row {
+ ctor public PlaybackControlsRow(java.lang.Object);
+ ctor public PlaybackControlsRow();
+ method public android.support.v17.leanback.widget.Action getActionForKeyCode(int);
+ method public android.support.v17.leanback.widget.Action getActionForKeyCode(android.support.v17.leanback.widget.ObjectAdapter, int);
+ method public int getBufferedProgress();
+ method public long getBufferedProgressLong();
+ method public int getCurrentTime();
+ method public long getCurrentTimeLong();
+ method public final android.graphics.drawable.Drawable getImageDrawable();
+ method public final java.lang.Object getItem();
+ method public final android.support.v17.leanback.widget.ObjectAdapter getPrimaryActionsAdapter();
+ method public final android.support.v17.leanback.widget.ObjectAdapter getSecondaryActionsAdapter();
+ method public int getTotalTime();
+ method public long getTotalTimeLong();
+ method public void setBufferedProgress(int);
+ method public void setBufferedProgressLong(long);
+ method public void setCurrentTime(int);
+ method public void setCurrentTimeLong(long);
+ method public final void setImageBitmap(android.content.Context, android.graphics.Bitmap);
+ method public final void setImageDrawable(android.graphics.drawable.Drawable);
+ method public final void setPrimaryActionsAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ method public final void setSecondaryActionsAdapter(android.support.v17.leanback.widget.ObjectAdapter);
+ method public void setTotalTime(int);
+ method public void setTotalTimeLong(long);
+ }
+
+ public static class PlaybackControlsRow.ClosedCaptioningAction extends android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction {
+ ctor public PlaybackControlsRow.ClosedCaptioningAction(android.content.Context);
+ ctor public PlaybackControlsRow.ClosedCaptioningAction(android.content.Context, int);
+ field public static int OFF;
+ field public static int ON;
+ }
+
+ public static class PlaybackControlsRow.FastForwardAction extends android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction {
+ ctor public PlaybackControlsRow.FastForwardAction(android.content.Context);
+ ctor public PlaybackControlsRow.FastForwardAction(android.content.Context, int);
+ }
+
+ public static class PlaybackControlsRow.HighQualityAction extends android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction {
+ ctor public PlaybackControlsRow.HighQualityAction(android.content.Context);
+ ctor public PlaybackControlsRow.HighQualityAction(android.content.Context, int);
+ field public static int OFF;
+ field public static int ON;
+ }
+
+ public static class PlaybackControlsRow.MoreActions extends android.support.v17.leanback.widget.Action {
+ ctor public PlaybackControlsRow.MoreActions(android.content.Context);
+ }
+
+ public static abstract class PlaybackControlsRow.MultiAction extends android.support.v17.leanback.widget.Action {
+ ctor public PlaybackControlsRow.MultiAction(int);
+ method public int getActionCount();
+ method public android.graphics.drawable.Drawable getDrawable(int);
+ method public int getIndex();
+ method public java.lang.String getLabel(int);
+ method public java.lang.String getSecondaryLabel(int);
+ method public void nextIndex();
+ method public void setDrawables(android.graphics.drawable.Drawable[]);
+ method public void setIndex(int);
+ method public void setLabels(java.lang.String[]);
+ method public void setSecondaryLabels(java.lang.String[]);
+ }
+
+ public static class PlaybackControlsRow.PictureInPictureAction extends android.support.v17.leanback.widget.Action {
+ ctor public PlaybackControlsRow.PictureInPictureAction(android.content.Context);
+ }
+
+ public static class PlaybackControlsRow.PlayPauseAction extends android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction {
+ ctor public PlaybackControlsRow.PlayPauseAction(android.content.Context);
+ field public static int PAUSE;
+ field public static int PLAY;
+ }
+
+ public static class PlaybackControlsRow.RepeatAction extends android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction {
+ ctor public PlaybackControlsRow.RepeatAction(android.content.Context);
+ ctor public PlaybackControlsRow.RepeatAction(android.content.Context, int);
+ ctor public PlaybackControlsRow.RepeatAction(android.content.Context, int, int);
+ field public static int ALL;
+ field public static int NONE;
+ field public static int ONE;
+ }
+
+ public static class PlaybackControlsRow.RewindAction extends android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction {
+ ctor public PlaybackControlsRow.RewindAction(android.content.Context);
+ ctor public PlaybackControlsRow.RewindAction(android.content.Context, int);
+ }
+
+ public static class PlaybackControlsRow.ShuffleAction extends android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction {
+ ctor public PlaybackControlsRow.ShuffleAction(android.content.Context);
+ ctor public PlaybackControlsRow.ShuffleAction(android.content.Context, int);
+ field public static int OFF;
+ field public static int ON;
+ }
+
+ public static class PlaybackControlsRow.SkipNextAction extends android.support.v17.leanback.widget.Action {
+ ctor public PlaybackControlsRow.SkipNextAction(android.content.Context);
+ }
+
+ public static class PlaybackControlsRow.SkipPreviousAction extends android.support.v17.leanback.widget.Action {
+ ctor public PlaybackControlsRow.SkipPreviousAction(android.content.Context);
+ }
+
+ public static abstract class PlaybackControlsRow.ThumbsAction extends android.support.v17.leanback.widget.PlaybackControlsRow.MultiAction {
+ ctor public PlaybackControlsRow.ThumbsAction(int, android.content.Context, int, int);
+ field public static int OUTLINE;
+ field public static int SOLID;
+ }
+
+ public static class PlaybackControlsRow.ThumbsDownAction extends android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsAction {
+ ctor public PlaybackControlsRow.ThumbsDownAction(android.content.Context);
+ }
+
+ public static class PlaybackControlsRow.ThumbsUpAction extends android.support.v17.leanback.widget.PlaybackControlsRow.ThumbsAction {
+ ctor public PlaybackControlsRow.ThumbsUpAction(android.content.Context);
+ }
+
+ public class PlaybackControlsRowPresenter extends android.support.v17.leanback.widget.PlaybackRowPresenter {
+ ctor public PlaybackControlsRowPresenter(android.support.v17.leanback.widget.Presenter);
+ ctor public PlaybackControlsRowPresenter();
+ method public boolean areSecondaryActionsHidden();
+ method protected android.support.v17.leanback.widget.RowPresenter.ViewHolder createRowViewHolder(android.view.ViewGroup);
+ method public int getBackgroundColor();
+ method public android.support.v17.leanback.widget.OnActionClickedListener getOnActionClickedListener();
+ method public int getProgressColor();
+ method public void setBackgroundColor(int);
+ method public void setOnActionClickedListener(android.support.v17.leanback.widget.OnActionClickedListener);
+ method public void setProgressColor(int);
+ method public void setSecondaryActionsHidden(boolean);
+ method public void showBottomSpace(android.support.v17.leanback.widget.PlaybackControlsRowPresenter.ViewHolder, boolean);
+ method public void showPrimaryActions(android.support.v17.leanback.widget.PlaybackControlsRowPresenter.ViewHolder);
+ }
+
+ public class PlaybackControlsRowPresenter.ViewHolder extends android.support.v17.leanback.widget.PlaybackRowPresenter.ViewHolder {
+ field public final android.support.v17.leanback.widget.Presenter.ViewHolder mDescriptionViewHolder;
+ }
+
+ public abstract class PlaybackRowPresenter extends android.support.v17.leanback.widget.RowPresenter {
+ ctor public PlaybackRowPresenter();
+ method public void onReappear(android.support.v17.leanback.widget.RowPresenter.ViewHolder);
+ }
+
+ public static class PlaybackRowPresenter.ViewHolder extends android.support.v17.leanback.widget.RowPresenter.ViewHolder {
+ ctor public PlaybackRowPresenter.ViewHolder(android.view.View);
+ }
+
+ public abstract class Presenter implements android.support.v17.leanback.widget.FacetProvider {
+ ctor public Presenter();
+ method protected static void cancelAnimationsRecursive(android.view.View);
+ method public final java.lang.Object getFacet(java.lang.Class<?>);
+ method public abstract void onBindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object);
+ method public abstract android.support.v17.leanback.widget.Presenter.ViewHolder onCreateViewHolder(android.view.ViewGroup);
+ method public abstract void onUnbindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+ method public void onViewAttachedToWindow(android.support.v17.leanback.widget.Presenter.ViewHolder);
+ method public void onViewDetachedFromWindow(android.support.v17.leanback.widget.Presenter.ViewHolder);
+ method public final void setFacet(java.lang.Class<?>, java.lang.Object);
+ method public void setOnClickListener(android.support.v17.leanback.widget.Presenter.ViewHolder, android.view.View.OnClickListener);
+ }
+
+ public static class Presenter.ViewHolder implements android.support.v17.leanback.widget.FacetProvider {
+ ctor public Presenter.ViewHolder(android.view.View);
+ method public final java.lang.Object getFacet(java.lang.Class<?>);
+ method public final void setFacet(java.lang.Class<?>, java.lang.Object);
+ field public final android.view.View view;
+ }
+
+ public static abstract class Presenter.ViewHolderTask {
+ ctor public Presenter.ViewHolderTask();
+ method public void run(android.support.v17.leanback.widget.Presenter.ViewHolder);
+ }
+
+ public abstract class PresenterSelector {
+ ctor public PresenterSelector();
+ method public abstract android.support.v17.leanback.widget.Presenter getPresenter(java.lang.Object);
+ method public android.support.v17.leanback.widget.Presenter[] getPresenters();
+ }
+
+ public abstract class PresenterSwitcher {
+ ctor public PresenterSwitcher();
+ method public void clear();
+ method public final android.view.ViewGroup getParentViewGroup();
+ method public void init(android.view.ViewGroup, android.support.v17.leanback.widget.PresenterSelector);
+ method protected abstract void insertView(android.view.View);
+ method protected void onViewSelected(android.view.View);
+ method public void select(java.lang.Object);
+ method protected void showView(android.view.View, boolean);
+ method public void unselect();
+ }
+
+ public class RecyclerViewParallax extends android.support.v17.leanback.widget.Parallax.IntParallax {
+ ctor public RecyclerViewParallax();
+ method public android.support.v17.leanback.widget.RecyclerViewParallax.ChildPositionProperty createProperty(java.lang.String, int);
+ method public int getMaxValue();
+ method public android.support.v7.widget.RecyclerView getRecyclerView();
+ method public void setRecyclerView(android.support.v7.widget.RecyclerView);
+ }
+
+ public static final class RecyclerViewParallax.ChildPositionProperty extends android.support.v17.leanback.widget.Parallax.IntProperty {
+ method public android.support.v17.leanback.widget.RecyclerViewParallax.ChildPositionProperty adapterPosition(int);
+ method public android.support.v17.leanback.widget.RecyclerViewParallax.ChildPositionProperty fraction(float);
+ method public int getAdapterPosition();
+ method public float getFraction();
+ method public int getOffset();
+ method public int getViewId();
+ method public android.support.v17.leanback.widget.RecyclerViewParallax.ChildPositionProperty offset(int);
+ method public android.support.v17.leanback.widget.RecyclerViewParallax.ChildPositionProperty viewId(int);
+ }
+
+ public class Row {
+ ctor public Row(long, android.support.v17.leanback.widget.HeaderItem);
+ ctor public Row(android.support.v17.leanback.widget.HeaderItem);
+ ctor public Row();
+ method public final android.support.v17.leanback.widget.HeaderItem getHeaderItem();
+ method public final long getId();
+ method public boolean isRenderedAsRowView();
+ method public final void setHeaderItem(android.support.v17.leanback.widget.HeaderItem);
+ method public final void setId(long);
+ }
+
+ public class RowHeaderPresenter extends android.support.v17.leanback.widget.Presenter {
+ ctor public RowHeaderPresenter();
+ method protected static float getFontDescent(android.widget.TextView, android.graphics.Paint);
+ method public int getSpaceUnderBaseline(android.support.v17.leanback.widget.RowHeaderPresenter.ViewHolder);
+ method public boolean isNullItemVisibilityGone();
+ method public void onBindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object);
+ method public android.support.v17.leanback.widget.Presenter.ViewHolder onCreateViewHolder(android.view.ViewGroup);
+ method protected void onSelectLevelChanged(android.support.v17.leanback.widget.RowHeaderPresenter.ViewHolder);
+ method public void onUnbindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+ method public void setNullItemVisibilityGone(boolean);
+ method public final void setSelectLevel(android.support.v17.leanback.widget.RowHeaderPresenter.ViewHolder, float);
+ }
+
+ public static class RowHeaderPresenter.ViewHolder extends android.support.v17.leanback.widget.Presenter.ViewHolder {
+ ctor public RowHeaderPresenter.ViewHolder(android.view.View);
+ method public final float getSelectLevel();
+ }
+
+ public final class RowHeaderView extends android.widget.TextView {
+ ctor public RowHeaderView(android.content.Context);
+ ctor public RowHeaderView(android.content.Context, android.util.AttributeSet);
+ ctor public RowHeaderView(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public abstract class RowPresenter extends android.support.v17.leanback.widget.Presenter {
+ ctor public RowPresenter();
+ method protected abstract android.support.v17.leanback.widget.RowPresenter.ViewHolder createRowViewHolder(android.view.ViewGroup);
+ method protected void dispatchItemSelectedListener(android.support.v17.leanback.widget.RowPresenter.ViewHolder, boolean);
+ method public void freeze(android.support.v17.leanback.widget.RowPresenter.ViewHolder, boolean);
+ method public final android.support.v17.leanback.widget.RowHeaderPresenter getHeaderPresenter();
+ method public final android.support.v17.leanback.widget.RowPresenter.ViewHolder getRowViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+ method public final boolean getSelectEffectEnabled();
+ method public final float getSelectLevel(android.support.v17.leanback.widget.Presenter.ViewHolder);
+ method public final int getSyncActivatePolicy();
+ method protected void initializeRowViewHolder(android.support.v17.leanback.widget.RowPresenter.ViewHolder);
+ method protected boolean isClippingChildren();
+ method public boolean isUsingDefaultSelectEffect();
+ method protected void onBindRowViewHolder(android.support.v17.leanback.widget.RowPresenter.ViewHolder, java.lang.Object);
+ method public final void onBindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object);
+ method public final android.support.v17.leanback.widget.Presenter.ViewHolder onCreateViewHolder(android.view.ViewGroup);
+ method protected void onRowViewAttachedToWindow(android.support.v17.leanback.widget.RowPresenter.ViewHolder);
+ method protected void onRowViewDetachedFromWindow(android.support.v17.leanback.widget.RowPresenter.ViewHolder);
+ method protected void onRowViewExpanded(android.support.v17.leanback.widget.RowPresenter.ViewHolder, boolean);
+ method protected void onRowViewSelected(android.support.v17.leanback.widget.RowPresenter.ViewHolder, boolean);
+ method protected void onSelectLevelChanged(android.support.v17.leanback.widget.RowPresenter.ViewHolder);
+ method protected void onUnbindRowViewHolder(android.support.v17.leanback.widget.RowPresenter.ViewHolder);
+ method public final void onUnbindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+ method public final void onViewAttachedToWindow(android.support.v17.leanback.widget.Presenter.ViewHolder);
+ method public final void onViewDetachedFromWindow(android.support.v17.leanback.widget.Presenter.ViewHolder);
+ method public void setEntranceTransitionState(android.support.v17.leanback.widget.RowPresenter.ViewHolder, boolean);
+ method public final void setHeaderPresenter(android.support.v17.leanback.widget.RowHeaderPresenter);
+ method public final void setRowViewExpanded(android.support.v17.leanback.widget.Presenter.ViewHolder, boolean);
+ method public final void setRowViewSelected(android.support.v17.leanback.widget.Presenter.ViewHolder, boolean);
+ method public final void setSelectEffectEnabled(boolean);
+ method public final void setSelectLevel(android.support.v17.leanback.widget.Presenter.ViewHolder, float);
+ method public final void setSyncActivatePolicy(int);
+ field public static final int SYNC_ACTIVATED_CUSTOM = 0; // 0x0
+ field public static final int SYNC_ACTIVATED_TO_EXPANDED = 1; // 0x1
+ field public static final int SYNC_ACTIVATED_TO_EXPANDED_AND_SELECTED = 3; // 0x3
+ field public static final int SYNC_ACTIVATED_TO_SELECTED = 2; // 0x2
+ }
+
+ public static class RowPresenter.ViewHolder extends android.support.v17.leanback.widget.Presenter.ViewHolder {
+ ctor public RowPresenter.ViewHolder(android.view.View);
+ method public final android.support.v17.leanback.widget.RowHeaderPresenter.ViewHolder getHeaderViewHolder();
+ method public final android.support.v17.leanback.widget.BaseOnItemViewClickedListener getOnItemViewClickedListener();
+ method public final android.support.v17.leanback.widget.BaseOnItemViewSelectedListener getOnItemViewSelectedListener();
+ method public android.view.View.OnKeyListener getOnKeyListener();
+ method public final android.support.v17.leanback.widget.Row getRow();
+ method public final java.lang.Object getRowObject();
+ method public final float getSelectLevel();
+ method public java.lang.Object getSelectedItem();
+ method public android.support.v17.leanback.widget.Presenter.ViewHolder getSelectedItemViewHolder();
+ method public final boolean isExpanded();
+ method public final boolean isSelected();
+ method public final void setActivated(boolean);
+ method public final void setOnItemViewClickedListener(android.support.v17.leanback.widget.BaseOnItemViewClickedListener);
+ method public final void setOnItemViewSelectedListener(android.support.v17.leanback.widget.BaseOnItemViewSelectedListener);
+ method public void setOnKeyListener(android.view.View.OnKeyListener);
+ method public final void syncActivatedStatus(android.view.View);
+ field protected final android.support.v17.leanback.graphics.ColorOverlayDimmer mColorDimmer;
+ }
+
+ public class SearchBar extends android.widget.RelativeLayout {
+ ctor public SearchBar(android.content.Context);
+ ctor public SearchBar(android.content.Context, android.util.AttributeSet);
+ ctor public SearchBar(android.content.Context, android.util.AttributeSet, int);
+ method public void displayCompletions(java.util.List<java.lang.String>);
+ method public void displayCompletions(android.view.inputmethod.CompletionInfo[]);
+ method public android.graphics.drawable.Drawable getBadgeDrawable();
+ method public java.lang.CharSequence getHint();
+ method public java.lang.String getTitle();
+ method public boolean isRecognizing();
+ method public void setBadgeDrawable(android.graphics.drawable.Drawable);
+ method public void setPermissionListener(android.support.v17.leanback.widget.SearchBar.SearchBarPermissionListener);
+ method public void setSearchAffordanceColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+ 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 void setSpeechRecognizer(android.speech.SpeechRecognizer);
+ method public void setTitle(java.lang.String);
+ method public void startRecognition();
+ method public void stopRecognition();
+ }
+
+ public static abstract interface SearchBar.SearchBarListener {
+ method public abstract void onKeyboardDismiss(java.lang.String);
+ method public abstract void onSearchQueryChange(java.lang.String);
+ method public abstract void onSearchQuerySubmit(java.lang.String);
+ }
+
+ public static abstract interface SearchBar.SearchBarPermissionListener {
+ method public abstract void requestAudioPermission();
+ }
+
+ public class SearchEditText extends android.support.v17.leanback.widget.StreamingTextView {
+ ctor public SearchEditText(android.content.Context);
+ ctor public SearchEditText(android.content.Context, android.util.AttributeSet);
+ ctor public SearchEditText(android.content.Context, android.util.AttributeSet, int);
+ method public void setOnKeyboardDismissListener(android.support.v17.leanback.widget.SearchEditText.OnKeyboardDismissListener);
+ }
+
+ public static abstract interface SearchEditText.OnKeyboardDismissListener {
+ method public abstract void onKeyboardDismiss();
+ }
+
+ public class SearchOrbView extends android.widget.FrameLayout implements android.view.View.OnClickListener {
+ ctor public SearchOrbView(android.content.Context);
+ ctor public SearchOrbView(android.content.Context, android.util.AttributeSet);
+ ctor public SearchOrbView(android.content.Context, android.util.AttributeSet, int);
+ method public void enableOrbColorAnimation(boolean);
+ method public int getOrbColor();
+ method public android.support.v17.leanback.widget.SearchOrbView.Colors getOrbColors();
+ method public android.graphics.drawable.Drawable getOrbIcon();
+ method public void onClick(android.view.View);
+ method public void setOnOrbClickedListener(android.view.View.OnClickListener);
+ method public void setOrbColor(int);
+ method public deprecated void setOrbColor(int, int);
+ method public void setOrbColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+ method public void setOrbIcon(android.graphics.drawable.Drawable);
+ }
+
+ public static class SearchOrbView.Colors {
+ ctor public SearchOrbView.Colors(int);
+ ctor public SearchOrbView.Colors(int, int);
+ ctor public SearchOrbView.Colors(int, int, int);
+ method public static int getBrightColor(int);
+ field public int brightColor;
+ field public int color;
+ field public int iconColor;
+ }
+
+ public class SectionRow extends android.support.v17.leanback.widget.Row {
+ ctor public SectionRow(android.support.v17.leanback.widget.HeaderItem);
+ ctor public SectionRow(long, java.lang.String);
+ ctor public SectionRow(java.lang.String);
+ method public final boolean isRenderedAsRowView();
+ }
+
+ public class ShadowOverlayContainer extends android.widget.FrameLayout {
+ ctor public ShadowOverlayContainer(android.content.Context);
+ ctor public ShadowOverlayContainer(android.content.Context, android.util.AttributeSet);
+ ctor public ShadowOverlayContainer(android.content.Context, android.util.AttributeSet, int);
+ method public int getShadowType();
+ method public android.view.View getWrappedView();
+ method public deprecated void initialize(boolean, boolean);
+ method public deprecated void initialize(boolean, boolean, boolean);
+ method public static void prepareParentForShadow(android.view.ViewGroup);
+ method public void setOverlayColor(int);
+ method public void setShadowFocusLevel(float);
+ method public static boolean supportsDynamicShadow();
+ method public static boolean supportsShadow();
+ method public void useDynamicShadow();
+ method public void useDynamicShadow(float, float);
+ method public void useStaticShadow();
+ method public void wrap(android.view.View);
+ field public static final int SHADOW_DYNAMIC = 3; // 0x3
+ field public static final int SHADOW_NONE = 1; // 0x1
+ field public static final int SHADOW_STATIC = 2; // 0x2
+ }
+
+ public final class ShadowOverlayHelper {
+ method public android.support.v17.leanback.widget.ShadowOverlayContainer createShadowOverlayContainer(android.content.Context);
+ method public int getShadowType();
+ method public boolean needsOverlay();
+ method public boolean needsRoundedCorner();
+ method public boolean needsWrapper();
+ method public void onViewCreated(android.view.View);
+ method public void prepareParentForShadow(android.view.ViewGroup);
+ method public static void setNoneWrapperOverlayColor(android.view.View, int);
+ method public static void setNoneWrapperShadowFocusLevel(android.view.View, float);
+ method public void setOverlayColor(android.view.View, int);
+ method public void setShadowFocusLevel(android.view.View, float);
+ method public static boolean supportsDynamicShadow();
+ method public static boolean supportsForeground();
+ method public static boolean supportsRoundedCorner();
+ method public static boolean supportsShadow();
+ field public static final int SHADOW_DYNAMIC = 3; // 0x3
+ field public static final int SHADOW_NONE = 1; // 0x1
+ field public static final int SHADOW_STATIC = 2; // 0x2
+ }
+
+ public static final class ShadowOverlayHelper.Builder {
+ ctor public ShadowOverlayHelper.Builder();
+ method public android.support.v17.leanback.widget.ShadowOverlayHelper build(android.content.Context);
+ method public android.support.v17.leanback.widget.ShadowOverlayHelper.Builder keepForegroundDrawable(boolean);
+ method public android.support.v17.leanback.widget.ShadowOverlayHelper.Builder needsOverlay(boolean);
+ method public android.support.v17.leanback.widget.ShadowOverlayHelper.Builder needsRoundedCorner(boolean);
+ method public android.support.v17.leanback.widget.ShadowOverlayHelper.Builder needsShadow(boolean);
+ method public android.support.v17.leanback.widget.ShadowOverlayHelper.Builder options(android.support.v17.leanback.widget.ShadowOverlayHelper.Options);
+ method public android.support.v17.leanback.widget.ShadowOverlayHelper.Builder preferZOrder(boolean);
+ }
+
+ public static final class ShadowOverlayHelper.Options {
+ ctor public ShadowOverlayHelper.Options();
+ method public android.support.v17.leanback.widget.ShadowOverlayHelper.Options dynamicShadowZ(float, float);
+ method public final float getDynamicShadowFocusedZ();
+ method public final float getDynamicShadowUnfocusedZ();
+ method public final int getRoundedCornerRadius();
+ method public android.support.v17.leanback.widget.ShadowOverlayHelper.Options roundedCornerRadius(int);
+ field public static final android.support.v17.leanback.widget.ShadowOverlayHelper.Options DEFAULT;
+ }
+
+ public final class SinglePresenterSelector extends android.support.v17.leanback.widget.PresenterSelector {
+ ctor public SinglePresenterSelector(android.support.v17.leanback.widget.Presenter);
+ method public android.support.v17.leanback.widget.Presenter getPresenter(java.lang.Object);
+ }
+
+ public class SparseArrayObjectAdapter extends android.support.v17.leanback.widget.ObjectAdapter {
+ ctor public SparseArrayObjectAdapter(android.support.v17.leanback.widget.PresenterSelector);
+ ctor public SparseArrayObjectAdapter(android.support.v17.leanback.widget.Presenter);
+ ctor public SparseArrayObjectAdapter();
+ method public void clear(int);
+ method public void clear();
+ method public java.lang.Object get(int);
+ method public int indexOf(java.lang.Object);
+ method public int indexOf(int);
+ method public java.lang.Object lookup(int);
+ method public void notifyArrayItemRangeChanged(int, int);
+ method public void set(int, java.lang.Object);
+ method public int size();
+ }
+
+ public class SpeechOrbView extends android.support.v17.leanback.widget.SearchOrbView {
+ ctor public SpeechOrbView(android.content.Context);
+ ctor public SpeechOrbView(android.content.Context, android.util.AttributeSet);
+ ctor public SpeechOrbView(android.content.Context, android.util.AttributeSet, int);
+ method public void setListeningOrbColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+ method public void setNotListeningOrbColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+ method public void setSoundLevel(int);
+ method public void showListening();
+ method public void showNotListening();
+ }
+
+ public abstract interface SpeechRecognitionCallback {
+ method public abstract void recognizeSpeech();
+ }
+
+ class StreamingTextView extends android.widget.EditText {
+ ctor public StreamingTextView(android.content.Context, android.util.AttributeSet);
+ ctor public StreamingTextView(android.content.Context, android.util.AttributeSet, int);
+ method public static boolean isLayoutRtl(android.view.View);
+ method public void reset();
+ method public void setFinalRecognizedText(java.lang.CharSequence);
+ method public void updateRecognizedText(java.lang.String, java.lang.String);
+ method public void updateRecognizedText(java.lang.String, java.util.List<java.lang.Float>);
+ }
+
+ public class TitleHelper {
+ ctor public TitleHelper(android.view.ViewGroup, android.view.View);
+ method public android.support.v17.leanback.widget.BrowseFrameLayout.OnFocusSearchListener getOnFocusSearchListener();
+ method public android.view.ViewGroup getSceneRoot();
+ method public android.view.View getTitleView();
+ method public void showTitle(boolean);
+ }
+
+ public class TitleView extends android.widget.FrameLayout implements android.support.v17.leanback.widget.TitleViewAdapter.Provider {
+ ctor public TitleView(android.content.Context);
+ ctor public TitleView(android.content.Context, android.util.AttributeSet);
+ ctor public TitleView(android.content.Context, android.util.AttributeSet, int);
+ method public void enableAnimation(boolean);
+ method public android.graphics.drawable.Drawable getBadgeDrawable();
+ method public android.support.v17.leanback.widget.SearchOrbView.Colors getSearchAffordanceColors();
+ method public android.view.View getSearchAffordanceView();
+ method public java.lang.CharSequence getTitle();
+ method public android.support.v17.leanback.widget.TitleViewAdapter getTitleViewAdapter();
+ method public void setBadgeDrawable(android.graphics.drawable.Drawable);
+ method public void setOnSearchClickedListener(android.view.View.OnClickListener);
+ method public void setSearchAffordanceColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+ method public void setTitle(java.lang.CharSequence);
+ method public void updateComponentsVisibility(int);
+ }
+
+ public abstract class TitleViewAdapter {
+ ctor public TitleViewAdapter();
+ method public android.graphics.drawable.Drawable getBadgeDrawable();
+ method public android.support.v17.leanback.widget.SearchOrbView.Colors getSearchAffordanceColors();
+ method public abstract android.view.View getSearchAffordanceView();
+ method public java.lang.CharSequence getTitle();
+ method public void setAnimationEnabled(boolean);
+ method public void setBadgeDrawable(android.graphics.drawable.Drawable);
+ method public void setOnSearchClickedListener(android.view.View.OnClickListener);
+ method public void setSearchAffordanceColors(android.support.v17.leanback.widget.SearchOrbView.Colors);
+ method public void setTitle(java.lang.CharSequence);
+ method public void updateComponentsVisibility(int);
+ field public static final int BRANDING_VIEW_VISIBLE = 2; // 0x2
+ field public static final int FULL_VIEW_VISIBLE = 6; // 0x6
+ field public static final int SEARCH_VIEW_VISIBLE = 4; // 0x4
+ }
+
+ public static abstract interface TitleViewAdapter.Provider {
+ method public abstract android.support.v17.leanback.widget.TitleViewAdapter getTitleViewAdapter();
+ }
+
+ public class VerticalGridPresenter extends android.support.v17.leanback.widget.Presenter {
+ ctor public VerticalGridPresenter();
+ ctor public VerticalGridPresenter(int);
+ ctor public VerticalGridPresenter(int, boolean);
+ method public final boolean areChildRoundedCornersEnabled();
+ method protected android.support.v17.leanback.widget.VerticalGridPresenter.ViewHolder createGridViewHolder(android.view.ViewGroup);
+ method protected android.support.v17.leanback.widget.ShadowOverlayHelper.Options createShadowOverlayOptions();
+ method public final void enableChildRoundedCorners(boolean);
+ method public final int getFocusZoomFactor();
+ method public final boolean getKeepChildForeground();
+ method public int getNumberOfColumns();
+ method public final android.support.v17.leanback.widget.OnItemViewClickedListener getOnItemViewClickedListener();
+ method public final android.support.v17.leanback.widget.OnItemViewSelectedListener getOnItemViewSelectedListener();
+ method public final boolean getShadowEnabled();
+ method protected void initializeGridViewHolder(android.support.v17.leanback.widget.VerticalGridPresenter.ViewHolder);
+ method public final boolean isFocusDimmerUsed();
+ method public boolean isUsingDefaultShadow();
+ method public boolean isUsingZOrder(android.content.Context);
+ method public void onBindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object);
+ method public final android.support.v17.leanback.widget.VerticalGridPresenter.ViewHolder onCreateViewHolder(android.view.ViewGroup);
+ method public void onUnbindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+ method public void setEntranceTransitionState(android.support.v17.leanback.widget.VerticalGridPresenter.ViewHolder, boolean);
+ method public final void setKeepChildForeground(boolean);
+ method public void setNumberOfColumns(int);
+ method public final void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
+ method public final void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
+ method public final void setShadowEnabled(boolean);
+ }
+
+ public static class VerticalGridPresenter.ViewHolder extends android.support.v17.leanback.widget.Presenter.ViewHolder {
+ ctor public VerticalGridPresenter.ViewHolder(android.support.v17.leanback.widget.VerticalGridView);
+ method public android.support.v17.leanback.widget.VerticalGridView getGridView();
+ }
+
+ public class VerticalGridView extends android.support.v7.widget.RecyclerView {
+ ctor public VerticalGridView(android.content.Context);
+ ctor public VerticalGridView(android.content.Context, android.util.AttributeSet);
+ ctor public VerticalGridView(android.content.Context, android.util.AttributeSet, int);
+ method protected void initAttributes(android.content.Context, android.util.AttributeSet);
+ method public void setColumnWidth(int);
+ method public void setNumColumns(int);
+ }
+
+ public abstract interface ViewHolderTask {
+ method public abstract void run(android.support.v7.widget.RecyclerView.ViewHolder);
+ }
+
+}
+
+package android.support.v17.leanback.widget.picker {
+
+ public class Picker extends android.widget.FrameLayout {
+ ctor public Picker(android.content.Context, android.util.AttributeSet, int);
+ method public void addOnValueChangedListener(android.support.v17.leanback.widget.picker.Picker.PickerValueListener);
+ method public float getActivatedVisibleItemCount();
+ method public android.support.v17.leanback.widget.picker.PickerColumn getColumnAt(int);
+ method public int getColumnsCount();
+ method protected int getPickerItemHeightPixels();
+ method public final int getPickerItemLayoutId();
+ method public final int getPickerItemTextViewId();
+ method public int getSelectedColumn();
+ method public final java.lang.CharSequence getSeparator();
+ method public float getVisibleItemCount();
+ method public void onColumnValueChanged(int, int);
+ method public void removeOnValueChangedListener(android.support.v17.leanback.widget.picker.Picker.PickerValueListener);
+ method public void setActivatedVisibleItemCount(float);
+ method public void setColumnAt(int, android.support.v17.leanback.widget.picker.PickerColumn);
+ method public void setColumnValue(int, int, boolean);
+ method public void setColumns(java.util.List<android.support.v17.leanback.widget.picker.PickerColumn>);
+ method public final void setPickerItemTextViewId(int);
+ method public void setSelectedColumn(int);
+ method public final void setSeparator(java.lang.CharSequence);
+ method public void setVisibleItemCount(float);
+ }
+
+ public static abstract interface Picker.PickerValueListener {
+ method public abstract void onValueChanged(android.support.v17.leanback.widget.picker.Picker, int);
+ }
+
+ public class PickerColumn {
+ ctor public PickerColumn();
+ method public int getCount();
+ method public int getCurrentValue();
+ method public java.lang.CharSequence getLabelFor(int);
+ method public java.lang.String getLabelFormat();
+ method public int getMaxValue();
+ method public int getMinValue();
+ method public java.lang.CharSequence[] getStaticLabels();
+ method public void setCurrentValue(int);
+ method public void setLabelFormat(java.lang.String);
+ method public void setMaxValue(int);
+ method public void setMinValue(int);
+ method public void setStaticLabels(java.lang.CharSequence[]);
+ }
+
+ public class TimePicker extends android.support.v17.leanback.widget.picker.Picker {
+ ctor public TimePicker(android.content.Context, android.util.AttributeSet);
+ ctor public TimePicker(android.content.Context, android.util.AttributeSet, int);
+ method public int getHour();
+ method public int getMinute();
+ method public boolean is24Hour();
+ method public boolean isPm();
+ method public void setHour(int);
+ method public void setIs24Hour(boolean);
+ method public void setMinute(int);
+ }
+
+}
+
+package android.support.v17.preference {
+
+ public abstract class BaseLeanbackPreferenceFragment extends android.support.v14.preference.PreferenceFragment {
+ ctor public BaseLeanbackPreferenceFragment();
+ }
+
+ public class LeanbackListPreferenceDialogFragment extends android.support.v17.preference.LeanbackPreferenceDialogFragment {
+ ctor public LeanbackListPreferenceDialogFragment();
+ method public static android.support.v17.preference.LeanbackListPreferenceDialogFragment newInstanceMulti(java.lang.String);
+ method public static android.support.v17.preference.LeanbackListPreferenceDialogFragment newInstanceSingle(java.lang.String);
+ method public android.support.v7.widget.RecyclerView.Adapter onCreateAdapter();
+ }
+
+ public class LeanbackListPreferenceDialogFragment.AdapterMulti extends android.support.v7.widget.RecyclerView.Adapter implements android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder.OnItemClickListener {
+ ctor public LeanbackListPreferenceDialogFragment.AdapterMulti(java.lang.CharSequence[], java.lang.CharSequence[], java.util.Set<java.lang.String>);
+ method public int getItemCount();
+ method public void onBindViewHolder(android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder, int);
+ method public android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder onCreateViewHolder(android.view.ViewGroup, int);
+ method public void onItemClick(android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder);
+ }
+
+ public class LeanbackListPreferenceDialogFragment.AdapterSingle extends android.support.v7.widget.RecyclerView.Adapter implements android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder.OnItemClickListener {
+ ctor public LeanbackListPreferenceDialogFragment.AdapterSingle(java.lang.CharSequence[], java.lang.CharSequence[], java.lang.CharSequence);
+ method public int getItemCount();
+ method public void onBindViewHolder(android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder, int);
+ method public android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder onCreateViewHolder(android.view.ViewGroup, int);
+ method public void onItemClick(android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder);
+ }
+
+ public static class LeanbackListPreferenceDialogFragment.ViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder implements android.view.View.OnClickListener {
+ ctor public LeanbackListPreferenceDialogFragment.ViewHolder(android.view.View, android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder.OnItemClickListener);
+ method public android.view.ViewGroup getContainer();
+ method public android.widget.TextView getTitleView();
+ method public android.widget.Checkable getWidgetView();
+ method public void onClick(android.view.View);
+ }
+
+ public static abstract interface LeanbackListPreferenceDialogFragment.ViewHolder.OnItemClickListener {
+ method public abstract void onItemClick(android.support.v17.preference.LeanbackListPreferenceDialogFragment.ViewHolder);
+ }
+
+ public class LeanbackPreferenceDialogFragment extends android.app.Fragment {
+ ctor public LeanbackPreferenceDialogFragment();
+ method public android.support.v7.preference.DialogPreference getPreference();
+ field public static final java.lang.String ARG_KEY = "key";
+ }
+
+ public abstract class LeanbackPreferenceFragment extends android.support.v17.preference.BaseLeanbackPreferenceFragment {
+ ctor public LeanbackPreferenceFragment();
+ method public void setTitle(java.lang.CharSequence);
+ }
+
+ public abstract class LeanbackSettingsFragment extends android.app.Fragment implements android.support.v14.preference.PreferenceFragment.OnPreferenceDisplayDialogCallback android.support.v14.preference.PreferenceFragment.OnPreferenceStartFragmentCallback android.support.v14.preference.PreferenceFragment.OnPreferenceStartScreenCallback {
+ ctor public LeanbackSettingsFragment();
+ method public boolean onPreferenceDisplayDialog(android.support.v14.preference.PreferenceFragment, android.support.v7.preference.Preference);
+ method public abstract void onPreferenceStartInitialScreen();
+ method public void startImmersiveFragment(android.app.Fragment);
+ method public void startPreferenceFragment(android.app.Fragment);
+ }
+
+}
+
+package android.support.v4.accessibilityservice {
+
+ public final class AccessibilityServiceInfoCompat {
+ method public static java.lang.String capabilityToString(int);
+ method public static java.lang.String feedbackTypeToString(int);
+ method public static java.lang.String flagToString(int);
+ method public static boolean getCanRetrieveWindowContent(android.accessibilityservice.AccessibilityServiceInfo);
+ method public static int getCapabilities(android.accessibilityservice.AccessibilityServiceInfo);
+ method public static deprecated java.lang.String getDescription(android.accessibilityservice.AccessibilityServiceInfo);
+ method public static java.lang.String getId(android.accessibilityservice.AccessibilityServiceInfo);
+ method public static android.content.pm.ResolveInfo getResolveInfo(android.accessibilityservice.AccessibilityServiceInfo);
+ method public static java.lang.String getSettingsActivityName(android.accessibilityservice.AccessibilityServiceInfo);
+ method public static java.lang.String loadDescription(android.accessibilityservice.AccessibilityServiceInfo, android.content.pm.PackageManager);
+ field public static final int CAPABILITY_CAN_FILTER_KEY_EVENTS = 8; // 0x8
+ field public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
+ field public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 2; // 0x2
+ field public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 1; // 0x1
+ field public static final int DEFAULT = 1; // 0x1
+ field public static final int FEEDBACK_ALL_MASK = -1; // 0xffffffff
+ field public static final int FEEDBACK_BRAILLE = 32; // 0x20
+ field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
+ field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
+ field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
+ field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
+ field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
+ }
+
+}
+
+package android.support.v4.app {
+
+ public deprecated class ActionBarDrawerToggle implements android.support.v4.widget.DrawerLayout.DrawerListener {
+ ctor public ActionBarDrawerToggle(android.app.Activity, android.support.v4.widget.DrawerLayout, int, int, int);
+ ctor public ActionBarDrawerToggle(android.app.Activity, android.support.v4.widget.DrawerLayout, boolean, int, int, int);
+ method public boolean isDrawerIndicatorEnabled();
+ method public void onConfigurationChanged(android.content.res.Configuration);
+ method public void onDrawerClosed(android.view.View);
+ method public void onDrawerOpened(android.view.View);
+ method public void onDrawerSlide(android.view.View, float);
+ method public void onDrawerStateChanged(int);
+ method public boolean onOptionsItemSelected(android.view.MenuItem);
+ method public void setDrawerIndicatorEnabled(boolean);
+ method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable);
+ method public void setHomeAsUpIndicator(int);
+ method public void syncState();
+ }
+
+ public static abstract interface ActionBarDrawerToggle.Delegate {
+ method public abstract android.graphics.drawable.Drawable getThemeUpIndicator();
+ method public abstract void setActionBarDescription(int);
+ method public abstract void setActionBarUpIndicator(android.graphics.drawable.Drawable, int);
+ }
+
+ public static abstract interface ActionBarDrawerToggle.DelegateProvider {
+ method public abstract android.support.v4.app.ActionBarDrawerToggle.Delegate getDrawerToggleDelegate();
+ }
+
+ public class ActivityCompat extends android.support.v4.content.ContextCompat {
+ ctor protected ActivityCompat();
+ method public static void finishAffinity(android.app.Activity);
+ method public static void finishAfterTransition(android.app.Activity);
+ method public static android.net.Uri getReferrer(android.app.Activity);
+ method public static boolean invalidateOptionsMenu(android.app.Activity);
+ method public static void postponeEnterTransition(android.app.Activity);
+ method public static void requestPermissions(android.app.Activity, java.lang.String[], int);
+ method public static void setEnterSharedElementCallback(android.app.Activity, android.support.v4.app.SharedElementCallback);
+ method public static void setExitSharedElementCallback(android.app.Activity, android.support.v4.app.SharedElementCallback);
+ method public static boolean shouldShowRequestPermissionRationale(android.app.Activity, java.lang.String);
+ method public static void startActivityForResult(android.app.Activity, android.content.Intent, int, android.os.Bundle);
+ method public static void startIntentSenderForResult(android.app.Activity, android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
+ method public static void startPostponedEnterTransition(android.app.Activity);
+ }
+
+ public static abstract interface ActivityCompat.OnRequestPermissionsResultCallback {
+ method public abstract void onRequestPermissionsResult(int, java.lang.String[], int[]);
+ }
+
+ public final class ActivityManagerCompat {
+ method public static boolean isLowRamDevice(android.app.ActivityManager);
+ }
+
+ public class ActivityOptionsCompat {
+ ctor protected ActivityOptionsCompat();
+ method public android.graphics.Rect getLaunchBounds();
+ method public static android.support.v4.app.ActivityOptionsCompat makeBasic();
+ method public static android.support.v4.app.ActivityOptionsCompat makeClipRevealAnimation(android.view.View, int, int, int, int);
+ method public static android.support.v4.app.ActivityOptionsCompat makeCustomAnimation(android.content.Context, int, int);
+ method public static android.support.v4.app.ActivityOptionsCompat makeScaleUpAnimation(android.view.View, int, int, int, int);
+ method public static android.support.v4.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, android.view.View, java.lang.String);
+ method public static android.support.v4.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, android.support.v4.util.Pair<android.view.View, java.lang.String>...);
+ method public static android.support.v4.app.ActivityOptionsCompat makeTaskLaunchBehind();
+ method public static android.support.v4.app.ActivityOptionsCompat makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
+ method public void requestUsageTimeReport(android.app.PendingIntent);
+ method public android.support.v4.app.ActivityOptionsCompat setLaunchBounds(android.graphics.Rect);
+ method public android.os.Bundle toBundle();
+ method public void update(android.support.v4.app.ActivityOptionsCompat);
+ field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
+ field public static final java.lang.String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages";
+ }
+
+ public final class AlarmManagerCompat {
+ method public static void setAlarmClock(android.app.AlarmManager, long, android.app.PendingIntent, android.app.PendingIntent);
+ method public static void setAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
+ method public static void setExact(android.app.AlarmManager, int, long, android.app.PendingIntent);
+ method public static void setExactAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
+ }
+
+ public class AppLaunchChecker {
+ ctor public AppLaunchChecker();
+ method public static boolean hasStartedFromLauncher(android.content.Context);
+ method public static void onActivityCreate(android.app.Activity);
+ }
+
+ public final class AppOpsManagerCompat {
+ method public static int noteOp(android.content.Context, java.lang.String, int, java.lang.String);
+ method public static int noteProxyOp(android.content.Context, java.lang.String, java.lang.String);
+ method public static java.lang.String permissionToOp(java.lang.String);
+ field public static final int MODE_ALLOWED = 0; // 0x0
+ field public static final int MODE_DEFAULT = 3; // 0x3
+ field public static final int MODE_IGNORED = 1; // 0x1
+ }
+
+ public final class BundleCompat {
+ method public static android.os.IBinder getBinder(android.os.Bundle, java.lang.String);
+ method public static void putBinder(android.os.Bundle, java.lang.String, android.os.IBinder);
+ }
+
+ public class DialogFragment extends android.support.v4.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
+ ctor public DialogFragment();
+ method public void dismiss();
+ method public void dismissAllowingStateLoss();
+ method public android.app.Dialog getDialog();
+ method public boolean getShowsDialog();
+ method public int getTheme();
+ method public boolean isCancelable();
+ method public void onCancel(android.content.DialogInterface);
+ method public android.app.Dialog onCreateDialog(android.os.Bundle);
+ method public void onDismiss(android.content.DialogInterface);
+ method public void setCancelable(boolean);
+ method public void setShowsDialog(boolean);
+ method public void setStyle(int, int);
+ method public void show(android.support.v4.app.FragmentManager, java.lang.String);
+ method public int show(android.support.v4.app.FragmentTransaction, java.lang.String);
+ field public static final int STYLE_NORMAL = 0; // 0x0
+ field public static final int STYLE_NO_FRAME = 2; // 0x2
+ field public static final int STYLE_NO_INPUT = 3; // 0x3
+ field public static final int STYLE_NO_TITLE = 1; // 0x1
+ }
+
+ public class Fragment implements android.content.ComponentCallbacks android.view.View.OnCreateContextMenuListener {
+ ctor public Fragment();
+ method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public final boolean equals(java.lang.Object);
+ method public final android.support.v4.app.FragmentActivity getActivity();
+ method public boolean getAllowEnterTransitionOverlap();
+ method public boolean getAllowReturnTransitionOverlap();
+ method public final android.os.Bundle getArguments();
+ method public final android.support.v4.app.FragmentManager getChildFragmentManager();
+ method public android.content.Context getContext();
+ method public java.lang.Object getEnterTransition();
+ method public java.lang.Object getExitTransition();
+ method public final android.support.v4.app.FragmentManager getFragmentManager();
+ method public final java.lang.Object getHost();
+ method public final int getId();
+ method public android.support.v4.app.LoaderManager getLoaderManager();
+ method public final android.support.v4.app.Fragment getParentFragment();
+ method public java.lang.Object getReenterTransition();
+ method public final android.content.res.Resources getResources();
+ method public final boolean getRetainInstance();
+ method public java.lang.Object getReturnTransition();
+ method public java.lang.Object getSharedElementEnterTransition();
+ method public java.lang.Object getSharedElementReturnTransition();
+ method public final java.lang.String getString(int);
+ method public final java.lang.String getString(int, java.lang.Object...);
+ method public final java.lang.String getTag();
+ method public final android.support.v4.app.Fragment getTargetFragment();
+ method public final int getTargetRequestCode();
+ method public final java.lang.CharSequence getText(int);
+ method public boolean getUserVisibleHint();
+ method public android.view.View getView();
+ method public final int hashCode();
+ method public static android.support.v4.app.Fragment instantiate(android.content.Context, java.lang.String);
+ method public static android.support.v4.app.Fragment instantiate(android.content.Context, java.lang.String, android.os.Bundle);
+ method public final boolean isAdded();
+ method public final boolean isDetached();
+ method public final boolean isHidden();
+ method public final boolean isInLayout();
+ method public final boolean isRemoving();
+ method public final boolean isResumed();
+ method public final boolean isStateSaved();
+ method public final boolean isVisible();
+ method public void onActivityCreated(android.os.Bundle);
+ method public void onActivityResult(int, int, android.content.Intent);
+ method public void onAttach(android.content.Context);
+ method public deprecated void onAttach(android.app.Activity);
+ method public void onAttachFragment(android.support.v4.app.Fragment);
+ method public void onConfigurationChanged(android.content.res.Configuration);
+ method public boolean onContextItemSelected(android.view.MenuItem);
+ method public void onCreate(android.os.Bundle);
+ method public android.view.animation.Animation onCreateAnimation(int, boolean, int);
+ method public void onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo);
+ method public void onCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
+ method public android.view.View onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+ method public void onDestroy();
+ method public void onDestroyOptionsMenu();
+ method public void onDestroyView();
+ method public void onDetach();
+ method public void onHiddenChanged(boolean);
+ method public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle);
+ method public deprecated void onInflate(android.app.Activity, android.util.AttributeSet, android.os.Bundle);
+ method public void onLowMemory();
+ method public void onMultiWindowModeChanged(boolean);
+ method public boolean onOptionsItemSelected(android.view.MenuItem);
+ method public void onOptionsMenuClosed(android.view.Menu);
+ method public void onPause();
+ method public void onPictureInPictureModeChanged(boolean);
+ method public void onPrepareOptionsMenu(android.view.Menu);
+ method public void onRequestPermissionsResult(int, java.lang.String[], int[]);
+ method public void onResume();
+ method public void onSaveInstanceState(android.os.Bundle);
+ method public void onStart();
+ method public void onStop();
+ method public void onViewCreated(android.view.View, android.os.Bundle);
+ method public void onViewStateRestored(android.os.Bundle);
+ method public void postponeEnterTransition();
+ method public void registerForContextMenu(android.view.View);
+ method public final void requestPermissions(java.lang.String[], int);
+ method public void setAllowEnterTransitionOverlap(boolean);
+ method public void setAllowReturnTransitionOverlap(boolean);
+ method public void setArguments(android.os.Bundle);
+ method public void setEnterSharedElementCallback(android.support.v4.app.SharedElementCallback);
+ method public void setEnterTransition(java.lang.Object);
+ method public void setExitSharedElementCallback(android.support.v4.app.SharedElementCallback);
+ method public void setExitTransition(java.lang.Object);
+ method public void setHasOptionsMenu(boolean);
+ method public void setInitialSavedState(android.support.v4.app.Fragment.SavedState);
+ method public void setMenuVisibility(boolean);
+ method public void setReenterTransition(java.lang.Object);
+ method public void setRetainInstance(boolean);
+ method public void setReturnTransition(java.lang.Object);
+ method public void setSharedElementEnterTransition(java.lang.Object);
+ method public void setSharedElementReturnTransition(java.lang.Object);
+ method public void setTargetFragment(android.support.v4.app.Fragment, int);
+ method public void setUserVisibleHint(boolean);
+ method public boolean shouldShowRequestPermissionRationale(java.lang.String);
+ method public void startActivity(android.content.Intent);
+ method public void startActivity(android.content.Intent, android.os.Bundle);
+ method public void startActivityForResult(android.content.Intent, int);
+ method public void startActivityForResult(android.content.Intent, int, android.os.Bundle);
+ method public void startIntentSenderForResult(android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
+ method public void startPostponedEnterTransition();
+ method public void unregisterForContextMenu(android.view.View);
+ }
+
+ public static class Fragment.InstantiationException extends java.lang.RuntimeException {
+ ctor public Fragment.InstantiationException(java.lang.String, java.lang.Exception);
+ }
+
+ public static class Fragment.SavedState implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.app.Fragment.SavedState> CREATOR;
+ }
+
+ public class FragmentActivity extends android.app.Activity implements android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback {
+ ctor public FragmentActivity();
+ method public java.lang.Object getLastCustomNonConfigurationInstance();
+ method public android.support.v4.app.FragmentManager getSupportFragmentManager();
+ method public android.support.v4.app.LoaderManager getSupportLoaderManager();
+ method public void onAttachFragment(android.support.v4.app.Fragment);
+ method protected void onResumeFragments();
+ method public java.lang.Object onRetainCustomNonConfigurationInstance();
+ method public final java.lang.Object onRetainNonConfigurationInstance();
+ method public void setEnterSharedElementCallback(android.support.v4.app.SharedElementCallback);
+ method public void setExitSharedElementCallback(android.support.v4.app.SharedElementCallback);
+ method public void startActivityFromFragment(android.support.v4.app.Fragment, android.content.Intent, int);
+ method public void startActivityFromFragment(android.support.v4.app.Fragment, android.content.Intent, int, android.os.Bundle);
+ method public void startIntentSenderFromFragment(android.support.v4.app.Fragment, android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
+ method public void supportFinishAfterTransition();
+ method public deprecated void supportInvalidateOptionsMenu();
+ method public void supportPostponeEnterTransition();
+ method public void supportStartPostponedEnterTransition();
+ method public final void validateRequestPermissionsRequestCode(int);
+ }
+
+ public abstract class FragmentContainer {
+ ctor public FragmentContainer();
+ method public android.support.v4.app.Fragment instantiate(android.content.Context, java.lang.String, android.os.Bundle);
+ method public abstract android.view.View onFindViewById(int);
+ method public abstract boolean onHasView();
+ }
+
+ public class FragmentController {
+ method public void attachHost(android.support.v4.app.Fragment);
+ method public static final android.support.v4.app.FragmentController createController(android.support.v4.app.FragmentHostCallback<?>);
+ method public void dispatchActivityCreated();
+ method public void dispatchConfigurationChanged(android.content.res.Configuration);
+ method public boolean dispatchContextItemSelected(android.view.MenuItem);
+ method public void dispatchCreate();
+ method public boolean dispatchCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
+ method public void dispatchDestroy();
+ method public void dispatchDestroyView();
+ method public void dispatchLowMemory();
+ method public void dispatchMultiWindowModeChanged(boolean);
+ method public boolean dispatchOptionsItemSelected(android.view.MenuItem);
+ method public void dispatchOptionsMenuClosed(android.view.Menu);
+ method public void dispatchPause();
+ method public void dispatchPictureInPictureModeChanged(boolean);
+ method public boolean dispatchPrepareOptionsMenu(android.view.Menu);
+ method public void dispatchReallyStop();
+ method public void dispatchResume();
+ method public void dispatchStart();
+ method public void dispatchStop();
+ method public void doLoaderDestroy();
+ method public void doLoaderRetain();
+ method public void doLoaderStart();
+ method public void doLoaderStop(boolean);
+ method public void dumpLoaders(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public boolean execPendingActions();
+ method public android.support.v4.app.Fragment findFragmentByWho(java.lang.String);
+ method public java.util.List<android.support.v4.app.Fragment> getActiveFragments(java.util.List<android.support.v4.app.Fragment>);
+ method public int getActiveFragmentsCount();
+ method public android.support.v4.app.FragmentManager getSupportFragmentManager();
+ method public android.support.v4.app.LoaderManager getSupportLoaderManager();
+ method public void noteStateNotSaved();
+ method public android.view.View onCreateView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet);
+ method public void reportLoaderStart();
+ method public deprecated void restoreAllState(android.os.Parcelable, java.util.List<android.support.v4.app.Fragment>);
+ method public void restoreAllState(android.os.Parcelable, android.support.v4.app.FragmentManagerNonConfig);
+ method public void restoreLoaderNonConfig(android.support.v4.util.SimpleArrayMap<java.lang.String, android.support.v4.app.LoaderManager>);
+ method public android.support.v4.util.SimpleArrayMap<java.lang.String, android.support.v4.app.LoaderManager> retainLoaderNonConfig();
+ method public android.support.v4.app.FragmentManagerNonConfig retainNestedNonConfig();
+ method public deprecated java.util.List<android.support.v4.app.Fragment> retainNonConfig();
+ method public android.os.Parcelable saveAllState();
+ }
+
+ public abstract class FragmentHostCallback<E> extends android.support.v4.app.FragmentContainer {
+ ctor public FragmentHostCallback(android.content.Context, android.os.Handler, int);
+ method public void onDump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public android.view.View onFindViewById(int);
+ method public abstract E onGetHost();
+ method public android.view.LayoutInflater onGetLayoutInflater();
+ method public int onGetWindowAnimations();
+ method public boolean onHasView();
+ method public boolean onHasWindowAnimations();
+ method public void onRequestPermissionsFromFragment(android.support.v4.app.Fragment, java.lang.String[], int);
+ method public boolean onShouldSaveFragmentState(android.support.v4.app.Fragment);
+ method public boolean onShouldShowRequestPermissionRationale(java.lang.String);
+ method public void onStartActivityFromFragment(android.support.v4.app.Fragment, android.content.Intent, int);
+ method public void onStartActivityFromFragment(android.support.v4.app.Fragment, android.content.Intent, int, android.os.Bundle);
+ method public void onStartIntentSenderFromFragment(android.support.v4.app.Fragment, android.content.IntentSender, int, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
+ method public void onSupportInvalidateOptionsMenu();
+ }
+
+ public abstract class FragmentManager {
+ ctor public FragmentManager();
+ method public abstract void addOnBackStackChangedListener(android.support.v4.app.FragmentManager.OnBackStackChangedListener);
+ method public abstract android.support.v4.app.FragmentTransaction beginTransaction();
+ method public abstract void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public static void enableDebugLogging(boolean);
+ method public abstract boolean executePendingTransactions();
+ method public abstract android.support.v4.app.Fragment findFragmentById(int);
+ method public abstract android.support.v4.app.Fragment findFragmentByTag(java.lang.String);
+ method public abstract android.support.v4.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
+ method public abstract int getBackStackEntryCount();
+ method public abstract android.support.v4.app.Fragment getFragment(android.os.Bundle, java.lang.String);
+ method public abstract android.support.v4.app.Fragment getPrimaryNavigationFragment();
+ method public abstract boolean isDestroyed();
+ method public abstract void popBackStack();
+ method public abstract void popBackStack(java.lang.String, int);
+ method public abstract void popBackStack(int, int);
+ method public abstract boolean popBackStackImmediate();
+ method public abstract boolean popBackStackImmediate(java.lang.String, int);
+ method public abstract boolean popBackStackImmediate(int, int);
+ method public abstract void putFragment(android.os.Bundle, java.lang.String, android.support.v4.app.Fragment);
+ method public abstract void registerFragmentLifecycleCallbacks(android.support.v4.app.FragmentManager.FragmentLifecycleCallbacks, boolean);
+ method public abstract void removeOnBackStackChangedListener(android.support.v4.app.FragmentManager.OnBackStackChangedListener);
+ method public abstract android.support.v4.app.Fragment.SavedState saveFragmentInstanceState(android.support.v4.app.Fragment);
+ method public abstract void unregisterFragmentLifecycleCallbacks(android.support.v4.app.FragmentManager.FragmentLifecycleCallbacks);
+ field public static final int POP_BACK_STACK_INCLUSIVE = 1; // 0x1
+ }
+
+ public static abstract interface FragmentManager.BackStackEntry {
+ method public abstract java.lang.CharSequence getBreadCrumbShortTitle();
+ method public abstract int getBreadCrumbShortTitleRes();
+ method public abstract java.lang.CharSequence getBreadCrumbTitle();
+ method public abstract int getBreadCrumbTitleRes();
+ method public abstract int getId();
+ method public abstract java.lang.String getName();
+ }
+
+ public static abstract class FragmentManager.FragmentLifecycleCallbacks {
+ ctor public FragmentManager.FragmentLifecycleCallbacks();
+ method public void onFragmentActivityCreated(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment, android.os.Bundle);
+ method public void onFragmentAttached(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment, android.content.Context);
+ method public void onFragmentCreated(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment, android.os.Bundle);
+ method public void onFragmentDestroyed(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment);
+ method public void onFragmentDetached(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment);
+ method public void onFragmentPaused(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment);
+ method public void onFragmentPreAttached(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment, android.content.Context);
+ method public void onFragmentResumed(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment);
+ method public void onFragmentSaveInstanceState(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment, android.os.Bundle);
+ method public void onFragmentStarted(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment);
+ method public void onFragmentStopped(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment);
+ method public void onFragmentViewCreated(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment, android.view.View, android.os.Bundle);
+ method public void onFragmentViewDestroyed(android.support.v4.app.FragmentManager, android.support.v4.app.Fragment);
+ }
+
+ public static abstract interface FragmentManager.OnBackStackChangedListener {
+ method public abstract void onBackStackChanged();
+ }
+
+ public class FragmentManagerNonConfig {
+ }
+
+ public abstract class FragmentPagerAdapter extends android.support.v4.view.PagerAdapter {
+ ctor public FragmentPagerAdapter(android.support.v4.app.FragmentManager);
+ method public abstract android.support.v4.app.Fragment getItem(int);
+ method public long getItemId(int);
+ method public boolean isViewFromObject(android.view.View, java.lang.Object);
+ }
+
+ public abstract class FragmentStatePagerAdapter extends android.support.v4.view.PagerAdapter {
+ ctor public FragmentStatePagerAdapter(android.support.v4.app.FragmentManager);
+ method public abstract android.support.v4.app.Fragment getItem(int);
+ method public boolean isViewFromObject(android.view.View, java.lang.Object);
+ }
+
+ public class FragmentTabHost extends android.widget.TabHost implements android.widget.TabHost.OnTabChangeListener {
+ ctor public FragmentTabHost(android.content.Context);
+ ctor public FragmentTabHost(android.content.Context, android.util.AttributeSet);
+ method public void addTab(android.widget.TabHost.TabSpec, java.lang.Class<?>, android.os.Bundle);
+ method public void onTabChanged(java.lang.String);
+ method public void setup(android.content.Context, android.support.v4.app.FragmentManager);
+ method public void setup(android.content.Context, android.support.v4.app.FragmentManager, int);
+ }
+
+ public abstract class FragmentTransaction {
+ ctor public FragmentTransaction();
+ method public abstract android.support.v4.app.FragmentTransaction add(android.support.v4.app.Fragment, java.lang.String);
+ method public abstract android.support.v4.app.FragmentTransaction add(int, android.support.v4.app.Fragment);
+ method public abstract android.support.v4.app.FragmentTransaction add(int, android.support.v4.app.Fragment, java.lang.String);
+ method public abstract android.support.v4.app.FragmentTransaction addSharedElement(android.view.View, java.lang.String);
+ method public abstract android.support.v4.app.FragmentTransaction addToBackStack(java.lang.String);
+ method public abstract android.support.v4.app.FragmentTransaction attach(android.support.v4.app.Fragment);
+ method public abstract int commit();
+ method public abstract int commitAllowingStateLoss();
+ method public abstract void commitNow();
+ method public abstract void commitNowAllowingStateLoss();
+ method public abstract android.support.v4.app.FragmentTransaction detach(android.support.v4.app.Fragment);
+ method public abstract android.support.v4.app.FragmentTransaction disallowAddToBackStack();
+ method public abstract android.support.v4.app.FragmentTransaction hide(android.support.v4.app.Fragment);
+ method public abstract boolean isAddToBackStackAllowed();
+ method public abstract boolean isEmpty();
+ method public abstract android.support.v4.app.FragmentTransaction postOnCommit(java.lang.Runnable);
+ method public abstract android.support.v4.app.FragmentTransaction remove(android.support.v4.app.Fragment);
+ method public abstract android.support.v4.app.FragmentTransaction replace(int, android.support.v4.app.Fragment);
+ method public abstract android.support.v4.app.FragmentTransaction replace(int, android.support.v4.app.Fragment, java.lang.String);
+ method public abstract android.support.v4.app.FragmentTransaction setAllowOptimization(boolean);
+ method public abstract android.support.v4.app.FragmentTransaction setBreadCrumbShortTitle(int);
+ method public abstract android.support.v4.app.FragmentTransaction setBreadCrumbShortTitle(java.lang.CharSequence);
+ method public abstract android.support.v4.app.FragmentTransaction setBreadCrumbTitle(int);
+ method public abstract android.support.v4.app.FragmentTransaction setBreadCrumbTitle(java.lang.CharSequence);
+ method public abstract android.support.v4.app.FragmentTransaction setCustomAnimations(int, int);
+ method public abstract android.support.v4.app.FragmentTransaction setCustomAnimations(int, int, int, int);
+ method public abstract android.support.v4.app.FragmentTransaction setPrimaryNavigationFragment(android.support.v4.app.Fragment);
+ method public abstract android.support.v4.app.FragmentTransaction setTransition(int);
+ method public abstract android.support.v4.app.FragmentTransaction setTransitionStyle(int);
+ method public abstract android.support.v4.app.FragmentTransaction show(android.support.v4.app.Fragment);
+ field public static final int TRANSIT_ENTER_MASK = 4096; // 0x1000
+ field public static final int TRANSIT_EXIT_MASK = 8192; // 0x2000
+ field public static final int TRANSIT_FRAGMENT_CLOSE = 8194; // 0x2002
+ field public static final int TRANSIT_FRAGMENT_FADE = 4099; // 0x1003
+ field public static final int TRANSIT_FRAGMENT_OPEN = 4097; // 0x1001
+ field public static final int TRANSIT_NONE = 0; // 0x0
+ field public static final int TRANSIT_UNSET = -1; // 0xffffffff
+ }
+
+ public class ListFragment extends android.support.v4.app.Fragment {
+ ctor public ListFragment();
+ method public android.widget.ListAdapter getListAdapter();
+ method public android.widget.ListView getListView();
+ method public long getSelectedItemId();
+ method public int getSelectedItemPosition();
+ method public void onListItemClick(android.widget.ListView, android.view.View, int, long);
+ method public void setEmptyText(java.lang.CharSequence);
+ method public void setListAdapter(android.widget.ListAdapter);
+ method public void setListShown(boolean);
+ method public void setListShownNoAnimation(boolean);
+ method public void setSelection(int);
+ }
+
+ public abstract class LoaderManager {
+ ctor public LoaderManager();
+ method public abstract void destroyLoader(int);
+ method public abstract void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public static void enableDebugLogging(boolean);
+ method public abstract <D> android.support.v4.content.Loader<D> getLoader(int);
+ method public boolean hasRunningLoaders();
+ method public abstract <D> android.support.v4.content.Loader<D> initLoader(int, android.os.Bundle, android.support.v4.app.LoaderManager.LoaderCallbacks<D>);
+ method public abstract <D> android.support.v4.content.Loader<D> restartLoader(int, android.os.Bundle, android.support.v4.app.LoaderManager.LoaderCallbacks<D>);
+ }
+
+ public static abstract interface LoaderManager.LoaderCallbacks<D> {
+ method public abstract android.support.v4.content.Loader<D> onCreateLoader(int, android.os.Bundle);
+ method public abstract void onLoadFinished(android.support.v4.content.Loader<D>, D);
+ method public abstract void onLoaderReset(android.support.v4.content.Loader<D>);
+ }
+
+ public final class NavUtils {
+ method public static android.content.Intent getParentActivityIntent(android.app.Activity);
+ method public static android.content.Intent getParentActivityIntent(android.content.Context, java.lang.Class<?>) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public static android.content.Intent getParentActivityIntent(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public static java.lang.String getParentActivityName(android.app.Activity);
+ method public static java.lang.String getParentActivityName(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+ method public static void navigateUpFromSameTask(android.app.Activity);
+ method public static void navigateUpTo(android.app.Activity, android.content.Intent);
+ method public static boolean shouldUpRecreateTask(android.app.Activity, android.content.Intent);
+ field public static final java.lang.String PARENT_ACTIVITY = "android.support.PARENT_ACTIVITY";
+ }
+
+ public class NotificationCompat {
+ ctor public NotificationCompat();
+ method public static android.support.v4.app.NotificationCompat.Action getAction(android.app.Notification, int);
+ method public static int getActionCount(android.app.Notification);
+ method public static java.lang.String getCategory(android.app.Notification);
+ method public static java.lang.String getChannel(android.app.Notification);
+ method public static android.os.Bundle getExtras(android.app.Notification);
+ method public static java.lang.String getGroup(android.app.Notification);
+ method public static boolean getLocalOnly(android.app.Notification);
+ method public static java.lang.String getSortKey(android.app.Notification);
+ method public static boolean isGroupSummary(android.app.Notification);
+ field public static final java.lang.String CATEGORY_ALARM = "alarm";
+ field public static final java.lang.String CATEGORY_CALL = "call";
+ field public static final java.lang.String CATEGORY_EMAIL = "email";
+ field public static final java.lang.String CATEGORY_ERROR = "err";
+ field public static final java.lang.String CATEGORY_EVENT = "event";
+ field public static final java.lang.String CATEGORY_MESSAGE = "msg";
+ field public static final java.lang.String CATEGORY_PROGRESS = "progress";
+ field public static final java.lang.String CATEGORY_PROMO = "promo";
+ field public static final java.lang.String CATEGORY_RECOMMENDATION = "recommendation";
+ field public static final java.lang.String CATEGORY_REMINDER = "reminder";
+ field public static final java.lang.String CATEGORY_SERVICE = "service";
+ field public static final java.lang.String CATEGORY_SOCIAL = "social";
+ field public static final java.lang.String CATEGORY_STATUS = "status";
+ field public static final java.lang.String CATEGORY_SYSTEM = "sys";
+ field public static final java.lang.String CATEGORY_TRANSPORT = "transport";
+ field public static final int COLOR_DEFAULT = 0; // 0x0
+ field public static final int DEFAULT_ALL = -1; // 0xffffffff
+ field public static final int DEFAULT_LIGHTS = 4; // 0x4
+ field public static final int DEFAULT_SOUND = 1; // 0x1
+ field public static final int DEFAULT_VIBRATE = 2; // 0x2
+ field public static final java.lang.String EXTRA_AUDIO_CONTENTS_URI = "android.audioContents";
+ field public static final java.lang.String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
+ field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
+ field public static final java.lang.String EXTRA_COMPACT_ACTIONS = "android.compactActions";
+ field public static final java.lang.String EXTRA_CONVERSATION_TITLE = "android.conversationTitle";
+ field public static final java.lang.String EXTRA_INFO_TEXT = "android.infoText";
+ field public static final java.lang.String EXTRA_LARGE_ICON = "android.largeIcon";
+ field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
+ field public static final java.lang.String EXTRA_MEDIA_SESSION = "android.mediaSession";
+ field public static final java.lang.String EXTRA_MESSAGES = "android.messages";
+ field public static final java.lang.String EXTRA_PEOPLE = "android.people";
+ field public static final java.lang.String EXTRA_PICTURE = "android.picture";
+ field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
+ field public static final java.lang.String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
+ field public static final java.lang.String EXTRA_PROGRESS_MAX = "android.progressMax";
+ field public static final java.lang.String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
+ field public static final java.lang.String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
+ field public static final java.lang.String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
+ field public static final java.lang.String EXTRA_SHOW_WHEN = "android.showWhen";
+ field public static final java.lang.String EXTRA_SMALL_ICON = "android.icon";
+ field public static final java.lang.String EXTRA_SUB_TEXT = "android.subText";
+ field public static final java.lang.String EXTRA_SUMMARY_TEXT = "android.summaryText";
+ field public static final java.lang.String EXTRA_TEMPLATE = "android.template";
+ field public static final java.lang.String EXTRA_TEXT = "android.text";
+ field public static final java.lang.String EXTRA_TEXT_LINES = "android.textLines";
+ field public static final java.lang.String EXTRA_TITLE = "android.title";
+ field public static final java.lang.String EXTRA_TITLE_BIG = "android.title.big";
+ field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
+ field public static final int FLAG_FOREGROUND_SERVICE = 64; // 0x40
+ field public static final int FLAG_GROUP_SUMMARY = 512; // 0x200
+ field public static final deprecated int FLAG_HIGH_PRIORITY = 128; // 0x80
+ field public static final int FLAG_INSISTENT = 4; // 0x4
+ field public static final int FLAG_LOCAL_ONLY = 256; // 0x100
+ field public static final int FLAG_NO_CLEAR = 32; // 0x20
+ field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
+ field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
+ field public static final int FLAG_SHOW_LIGHTS = 1; // 0x1
+ field public static final int PRIORITY_DEFAULT = 0; // 0x0
+ field public static final int PRIORITY_HIGH = 1; // 0x1
+ field public static final int PRIORITY_LOW = -1; // 0xffffffff
+ field public static final int PRIORITY_MAX = 2; // 0x2
+ field public static final int PRIORITY_MIN = -2; // 0xfffffffe
+ field public static final int STREAM_DEFAULT = -1; // 0xffffffff
+ field public static final int VISIBILITY_PRIVATE = 0; // 0x0
+ field public static final int VISIBILITY_PUBLIC = 1; // 0x1
+ field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
+ }
+
+ public static class NotificationCompat.Action {
+ ctor public NotificationCompat.Action(int, java.lang.CharSequence, android.app.PendingIntent);
+ method public android.app.PendingIntent getActionIntent();
+ method public boolean getAllowGeneratedReplies();
+ method public android.support.v4.app.RemoteInput[] getDataOnlyRemoteInputs();
+ method public android.os.Bundle getExtras();
+ method public int getIcon();
+ method public android.support.v4.app.RemoteInput[] getRemoteInputs();
+ method public java.lang.CharSequence getTitle();
+ field public android.app.PendingIntent actionIntent;
+ field public int icon;
+ field public java.lang.CharSequence title;
+ }
+
+ public static final class NotificationCompat.Action.Builder {
+ ctor public NotificationCompat.Action.Builder(int, java.lang.CharSequence, android.app.PendingIntent);
+ ctor public NotificationCompat.Action.Builder(android.support.v4.app.NotificationCompat.Action);
+ method public android.support.v4.app.NotificationCompat.Action.Builder addExtras(android.os.Bundle);
+ method public android.support.v4.app.NotificationCompat.Action.Builder addRemoteInput(android.support.v4.app.RemoteInput);
+ method public android.support.v4.app.NotificationCompat.Action build();
+ method public android.support.v4.app.NotificationCompat.Action.Builder extend(android.support.v4.app.NotificationCompat.Action.Extender);
+ method public android.os.Bundle getExtras();
+ method public android.support.v4.app.NotificationCompat.Action.Builder setAllowGeneratedReplies(boolean);
+ }
+
+ public static abstract interface NotificationCompat.Action.Extender {
+ method public abstract android.support.v4.app.NotificationCompat.Action.Builder extend(android.support.v4.app.NotificationCompat.Action.Builder);
+ }
+
+ public static final class NotificationCompat.Action.WearableExtender implements android.support.v4.app.NotificationCompat.Action.Extender {
+ ctor public NotificationCompat.Action.WearableExtender();
+ ctor public NotificationCompat.Action.WearableExtender(android.support.v4.app.NotificationCompat.Action);
+ method public android.support.v4.app.NotificationCompat.Action.WearableExtender clone();
+ method public android.support.v4.app.NotificationCompat.Action.Builder extend(android.support.v4.app.NotificationCompat.Action.Builder);
+ method public java.lang.CharSequence getCancelLabel();
+ method public java.lang.CharSequence getConfirmLabel();
+ method public boolean getHintDisplayActionInline();
+ method public boolean getHintLaunchesActivity();
+ method public java.lang.CharSequence getInProgressLabel();
+ method public boolean isAvailableOffline();
+ method public android.support.v4.app.NotificationCompat.Action.WearableExtender setAvailableOffline(boolean);
+ method public android.support.v4.app.NotificationCompat.Action.WearableExtender setCancelLabel(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.Action.WearableExtender setConfirmLabel(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.Action.WearableExtender setHintDisplayActionInline(boolean);
+ method public android.support.v4.app.NotificationCompat.Action.WearableExtender setHintLaunchesActivity(boolean);
+ method public android.support.v4.app.NotificationCompat.Action.WearableExtender setInProgressLabel(java.lang.CharSequence);
+ }
+
+ public static class NotificationCompat.BigPictureStyle extends android.support.v4.app.NotificationCompat.Style {
+ ctor public NotificationCompat.BigPictureStyle();
+ ctor public NotificationCompat.BigPictureStyle(android.support.v4.app.NotificationCompat.Builder);
+ method public android.support.v4.app.NotificationCompat.BigPictureStyle bigLargeIcon(android.graphics.Bitmap);
+ method public android.support.v4.app.NotificationCompat.BigPictureStyle bigPicture(android.graphics.Bitmap);
+ method public android.support.v4.app.NotificationCompat.BigPictureStyle setBigContentTitle(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.BigPictureStyle setSummaryText(java.lang.CharSequence);
+ }
+
+ public static class NotificationCompat.BigTextStyle extends android.support.v4.app.NotificationCompat.Style {
+ ctor public NotificationCompat.BigTextStyle();
+ ctor public NotificationCompat.BigTextStyle(android.support.v4.app.NotificationCompat.Builder);
+ method public android.support.v4.app.NotificationCompat.BigTextStyle bigText(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.BigTextStyle setBigContentTitle(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.BigTextStyle setSummaryText(java.lang.CharSequence);
+ }
+
+ public static class NotificationCompat.Builder {
+ ctor public NotificationCompat.Builder(android.content.Context);
+ method public android.support.v4.app.NotificationCompat.Builder addAction(int, java.lang.CharSequence, android.app.PendingIntent);
+ method public android.support.v4.app.NotificationCompat.Builder addAction(android.support.v4.app.NotificationCompat.Action);
+ method public android.support.v4.app.NotificationCompat.Builder addExtras(android.os.Bundle);
+ method public android.support.v4.app.NotificationCompat.Builder addPerson(java.lang.String);
+ method public android.app.Notification build();
+ method public android.support.v4.app.NotificationCompat.Builder extend(android.support.v4.app.NotificationCompat.Extender);
+ method public android.os.Bundle getExtras();
+ method public deprecated android.app.Notification getNotification();
+ method protected static java.lang.CharSequence limitCharSequenceLength(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.Builder setAutoCancel(boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setCategory(java.lang.String);
+ method public android.support.v4.app.NotificationCompat.Builder setChannel(java.lang.String);
+ method public android.support.v4.app.NotificationCompat.Builder setColor(int);
+ method public android.support.v4.app.NotificationCompat.Builder setContent(android.widget.RemoteViews);
+ method public android.support.v4.app.NotificationCompat.Builder setContentInfo(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.Builder setContentIntent(android.app.PendingIntent);
+ method public android.support.v4.app.NotificationCompat.Builder setContentText(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.Builder setContentTitle(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.Builder setCustomBigContentView(android.widget.RemoteViews);
+ method public android.support.v4.app.NotificationCompat.Builder setCustomContentView(android.widget.RemoteViews);
+ method public android.support.v4.app.NotificationCompat.Builder setCustomHeadsUpContentView(android.widget.RemoteViews);
+ method public android.support.v4.app.NotificationCompat.Builder setDefaults(int);
+ method public android.support.v4.app.NotificationCompat.Builder setDeleteIntent(android.app.PendingIntent);
+ method public android.support.v4.app.NotificationCompat.Builder setExtras(android.os.Bundle);
+ method public android.support.v4.app.NotificationCompat.Builder setFullScreenIntent(android.app.PendingIntent, boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setGroup(java.lang.String);
+ method public android.support.v4.app.NotificationCompat.Builder setGroupSummary(boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setLargeIcon(android.graphics.Bitmap);
+ method public android.support.v4.app.NotificationCompat.Builder setLights(int, int, int);
+ method public android.support.v4.app.NotificationCompat.Builder setLocalOnly(boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setNumber(int);
+ method public android.support.v4.app.NotificationCompat.Builder setOngoing(boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setOnlyAlertOnce(boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setPriority(int);
+ method public android.support.v4.app.NotificationCompat.Builder setProgress(int, int, boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setPublicVersion(android.app.Notification);
+ method public android.support.v4.app.NotificationCompat.Builder setRemoteInputHistory(java.lang.CharSequence[]);
+ method public android.support.v4.app.NotificationCompat.Builder setShowWhen(boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setSmallIcon(int);
+ method public android.support.v4.app.NotificationCompat.Builder setSmallIcon(int, int);
+ method public android.support.v4.app.NotificationCompat.Builder setSortKey(java.lang.String);
+ method public android.support.v4.app.NotificationCompat.Builder setSound(android.net.Uri);
+ method public android.support.v4.app.NotificationCompat.Builder setSound(android.net.Uri, int);
+ method public android.support.v4.app.NotificationCompat.Builder setStyle(android.support.v4.app.NotificationCompat.Style);
+ method public android.support.v4.app.NotificationCompat.Builder setSubText(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.Builder setTicker(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
+ method public android.support.v4.app.NotificationCompat.Builder setUsesChronometer(boolean);
+ method public android.support.v4.app.NotificationCompat.Builder setVibrate(long[]);
+ method public android.support.v4.app.NotificationCompat.Builder setVisibility(int);
+ method public android.support.v4.app.NotificationCompat.Builder setWhen(long);
+ field public java.util.ArrayList<java.lang.String> mPeople;
+ }
+
+ public static final class NotificationCompat.CarExtender implements android.support.v4.app.NotificationCompat.Extender {
+ ctor public NotificationCompat.CarExtender();
+ ctor public NotificationCompat.CarExtender(android.app.Notification);
+ method public android.support.v4.app.NotificationCompat.Builder extend(android.support.v4.app.NotificationCompat.Builder);
+ method public int getColor();
+ method public android.graphics.Bitmap getLargeIcon();
+ method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation getUnreadConversation();
+ method public android.support.v4.app.NotificationCompat.CarExtender setColor(int);
+ method public android.support.v4.app.NotificationCompat.CarExtender setLargeIcon(android.graphics.Bitmap);
+ method public android.support.v4.app.NotificationCompat.CarExtender setUnreadConversation(android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation);
+ }
+
+ public static class NotificationCompat.CarExtender.UnreadConversation {
+ method public long getLatestTimestamp();
+ method public java.lang.String[] getMessages();
+ method public java.lang.String getParticipant();
+ method public java.lang.String[] getParticipants();
+ method public android.app.PendingIntent getReadPendingIntent();
+ method public android.support.v4.app.RemoteInput getRemoteInput();
+ method public android.app.PendingIntent getReplyPendingIntent();
+ }
+
+ public static class NotificationCompat.CarExtender.UnreadConversation.Builder {
+ ctor public NotificationCompat.CarExtender.UnreadConversation.Builder(java.lang.String);
+ method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder addMessage(java.lang.String);
+ method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation build();
+ method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder setLatestTimestamp(long);
+ method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReadPendingIntent(android.app.PendingIntent);
+ method public android.support.v4.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReplyAction(android.app.PendingIntent, android.support.v4.app.RemoteInput);
+ }
+
+ public static abstract interface NotificationCompat.Extender {
+ method public abstract android.support.v4.app.NotificationCompat.Builder extend(android.support.v4.app.NotificationCompat.Builder);
+ }
+
+ public static class NotificationCompat.InboxStyle extends android.support.v4.app.NotificationCompat.Style {
+ ctor public NotificationCompat.InboxStyle();
+ ctor public NotificationCompat.InboxStyle(android.support.v4.app.NotificationCompat.Builder);
+ method public android.support.v4.app.NotificationCompat.InboxStyle addLine(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.InboxStyle setBigContentTitle(java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.InboxStyle setSummaryText(java.lang.CharSequence);
+ }
+
+ public static class NotificationCompat.MessagingStyle extends android.support.v4.app.NotificationCompat.Style {
+ ctor public NotificationCompat.MessagingStyle(java.lang.CharSequence);
+ method public void addCompatExtras(android.os.Bundle);
+ method public android.support.v4.app.NotificationCompat.MessagingStyle addMessage(java.lang.CharSequence, long, java.lang.CharSequence);
+ method public android.support.v4.app.NotificationCompat.MessagingStyle addMessage(android.support.v4.app.NotificationCompat.MessagingStyle.Message);
+ method public static android.support.v4.app.NotificationCompat.MessagingStyle extractMessagingStyleFromNotification(android.app.Notification);
+ method public java.lang.CharSequence getConversationTitle();
+ method public java.util.List<android.support.v4.app.NotificationCompat.MessagingStyle.Message> getMessages();
+ method public java.lang.CharSequence getUserDisplayName();
+ method public android.support.v4.app.NotificationCompat.MessagingStyle setConversationTitle(java.lang.CharSequence);
+ field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
+ }
+
+ public static final class NotificationCompat.MessagingStyle.Message {
+ ctor public NotificationCompat.MessagingStyle.Message(java.lang.CharSequence, long, java.lang.CharSequence);
+ method public java.lang.String getDataMimeType();
+ method public android.net.Uri getDataUri();
+ method public java.lang.CharSequence getSender();
+ method public java.lang.CharSequence getText();
+ method public long getTimestamp();
+ method public android.support.v4.app.NotificationCompat.MessagingStyle.Message setData(java.lang.String, android.net.Uri);
+ }
+
+ public static abstract class NotificationCompat.Style {
+ ctor public NotificationCompat.Style();
+ method public android.app.Notification build();
+ method public void setBuilder(android.support.v4.app.NotificationCompat.Builder);
+ }
+
+ public static final class NotificationCompat.WearableExtender implements android.support.v4.app.NotificationCompat.Extender {
+ ctor public NotificationCompat.WearableExtender();
+ ctor public NotificationCompat.WearableExtender(android.app.Notification);
+ method public android.support.v4.app.NotificationCompat.WearableExtender addAction(android.support.v4.app.NotificationCompat.Action);
+ method public android.support.v4.app.NotificationCompat.WearableExtender addActions(java.util.List<android.support.v4.app.NotificationCompat.Action>);
+ method public android.support.v4.app.NotificationCompat.WearableExtender addPage(android.app.Notification);
+ method public android.support.v4.app.NotificationCompat.WearableExtender addPages(java.util.List<android.app.Notification>);
+ method public android.support.v4.app.NotificationCompat.WearableExtender clearActions();
+ method public android.support.v4.app.NotificationCompat.WearableExtender clearPages();
+ method public android.support.v4.app.NotificationCompat.WearableExtender clone();
+ method public android.support.v4.app.NotificationCompat.Builder extend(android.support.v4.app.NotificationCompat.Builder);
+ method public java.util.List<android.support.v4.app.NotificationCompat.Action> getActions();
+ method public android.graphics.Bitmap getBackground();
+ method public java.lang.String getBridgeTag();
+ method public int getContentAction();
+ method public int getContentIcon();
+ method public int getContentIconGravity();
+ method public boolean getContentIntentAvailableOffline();
+ method public int getCustomContentHeight();
+ method public int getCustomSizePreset();
+ method public java.lang.String getDismissalId();
+ method public android.app.PendingIntent getDisplayIntent();
+ method public int getGravity();
+ method public boolean getHintAmbientBigPicture();
+ method public boolean getHintAvoidBackgroundClipping();
+ method public boolean getHintContentIntentLaunchesActivity();
+ method public boolean getHintHideIcon();
+ method public int getHintScreenTimeout();
+ method public boolean getHintShowBackgroundOnly();
+ method public java.util.List<android.app.Notification> getPages();
+ method public boolean getStartScrollBottom();
+ method public android.support.v4.app.NotificationCompat.WearableExtender setBackground(android.graphics.Bitmap);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setBridgeTag(java.lang.String);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setContentAction(int);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setContentIcon(int);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setContentIconGravity(int);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setContentIntentAvailableOffline(boolean);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setCustomContentHeight(int);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setCustomSizePreset(int);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setDismissalId(java.lang.String);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setDisplayIntent(android.app.PendingIntent);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setGravity(int);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setHintAmbientBigPicture(boolean);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setHintAvoidBackgroundClipping(boolean);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setHintContentIntentLaunchesActivity(boolean);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setHintHideIcon(boolean);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setHintScreenTimeout(int);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setHintShowBackgroundOnly(boolean);
+ method public android.support.v4.app.NotificationCompat.WearableExtender setStartScrollBottom(boolean);
+ field public static final int SCREEN_TIMEOUT_LONG = -1; // 0xffffffff
+ field public static final int SCREEN_TIMEOUT_SHORT = 0; // 0x0
+ field public static final int SIZE_DEFAULT = 0; // 0x0
+ field public static final int SIZE_FULL_SCREEN = 5; // 0x5
+ field public static final int SIZE_LARGE = 4; // 0x4
+ field public static final int SIZE_MEDIUM = 3; // 0x3
+ field public static final int SIZE_SMALL = 2; // 0x2
+ field public static final int SIZE_XSMALL = 1; // 0x1
+ field public static final int UNSET_ACTION_INDEX = -1; // 0xffffffff
+ }
+
+ public final class NotificationCompatExtras {
+ field public static final java.lang.String EXTRA_ACTION_EXTRAS = "android.support.actionExtras";
+ field public static final java.lang.String EXTRA_GROUP_KEY = "android.support.groupKey";
+ field public static final java.lang.String EXTRA_GROUP_SUMMARY = "android.support.isGroupSummary";
+ field public static final java.lang.String EXTRA_LOCAL_ONLY = "android.support.localOnly";
+ field public static final java.lang.String EXTRA_REMOTE_INPUTS = "android.support.remoteInputs";
+ field public static final java.lang.String EXTRA_SORT_KEY = "android.support.sortKey";
+ }
+
+ public abstract class NotificationCompatSideChannelService extends android.app.Service {
+ ctor public NotificationCompatSideChannelService();
+ method public abstract void cancel(java.lang.String, int, java.lang.String);
+ method public abstract void cancelAll(java.lang.String);
+ method public abstract void notify(java.lang.String, int, java.lang.String, android.app.Notification);
+ method public android.os.IBinder onBind(android.content.Intent);
+ }
+
+ public final class NotificationManagerCompat {
+ method public boolean areNotificationsEnabled();
+ method public void cancel(int);
+ method public void cancel(java.lang.String, int);
+ method public void cancelAll();
+ method public static android.support.v4.app.NotificationManagerCompat from(android.content.Context);
+ method public static java.util.Set<java.lang.String> getEnabledListenerPackages(android.content.Context);
+ method public int getImportance();
+ method public void notify(int, android.app.Notification);
+ method public void notify(java.lang.String, int, android.app.Notification);
+ field public static final java.lang.String ACTION_BIND_SIDE_CHANNEL = "android.support.BIND_NOTIFICATION_SIDE_CHANNEL";
+ field public static final java.lang.String EXTRA_USE_SIDE_CHANNEL = "android.support.useSideChannel";
+ field public static final int IMPORTANCE_DEFAULT = 3; // 0x3
+ field public static final int IMPORTANCE_HIGH = 4; // 0x4
+ field public static final int IMPORTANCE_LOW = 2; // 0x2
+ field public static final int IMPORTANCE_MAX = 5; // 0x5
+ field public static final int IMPORTANCE_MIN = 1; // 0x1
+ field public static final int IMPORTANCE_NONE = 0; // 0x0
+ field public static final int IMPORTANCE_UNSPECIFIED = -1000; // 0xfffffc18
+ }
+
+ public final class RemoteInput extends android.support.v4.app.RemoteInputCompatBase.RemoteInput {
+ method public static void addDataResultToIntent(android.support.v4.app.RemoteInput, android.content.Intent, java.util.Map<java.lang.String, android.net.Uri>);
+ method public static void addResultsToIntent(android.support.v4.app.RemoteInput[], android.content.Intent, android.os.Bundle);
+ method public boolean getAllowFreeFormInput();
+ method public java.util.Set<java.lang.String> getAllowedDataTypes();
+ method public java.lang.CharSequence[] getChoices();
+ method public static java.util.Map<java.lang.String, android.net.Uri> getDataResultsFromIntent(android.content.Intent, java.lang.String);
+ method public android.os.Bundle getExtras();
+ method public java.lang.CharSequence getLabel();
+ method public java.lang.String getResultKey();
+ method public static android.os.Bundle getResultsFromIntent(android.content.Intent);
+ method public boolean isDataOnly();
+ field public static final java.lang.String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
+ field public static final java.lang.String RESULTS_CLIP_LABEL = "android.remoteinput.results";
+ }
+
+ public static final class RemoteInput.Builder {
+ ctor public RemoteInput.Builder(java.lang.String);
+ method public android.support.v4.app.RemoteInput.Builder addExtras(android.os.Bundle);
+ method public android.support.v4.app.RemoteInput build();
+ method public android.os.Bundle getExtras();
+ method public android.support.v4.app.RemoteInput.Builder setAllowDataType(java.lang.String, boolean);
+ method public android.support.v4.app.RemoteInput.Builder setAllowFreeFormInput(boolean);
+ method public android.support.v4.app.RemoteInput.Builder setChoices(java.lang.CharSequence[]);
+ method public android.support.v4.app.RemoteInput.Builder setLabel(java.lang.CharSequence);
+ }
+
+ class RemoteInputCompatBase {
+ }
+
+ public static abstract class RemoteInputCompatBase.RemoteInput {
+ ctor public RemoteInputCompatBase.RemoteInput();
+ method protected abstract boolean getAllowFreeFormInput();
+ method protected abstract java.util.Set<java.lang.String> getAllowedDataTypes();
+ method protected abstract java.lang.CharSequence[] getChoices();
+ method protected abstract android.os.Bundle getExtras();
+ method protected abstract java.lang.CharSequence getLabel();
+ method protected abstract java.lang.String getResultKey();
+ }
+
+ public final class ServiceCompat {
+ method public static void stopForeground(android.app.Service, int);
+ field public static final int START_STICKY = 1; // 0x1
+ field public static final int STOP_FOREGROUND_DETACH = 2; // 0x2
+ field public static final int STOP_FOREGROUND_REMOVE = 1; // 0x1
+ }
+
+ public final class ShareCompat {
+ method public static void configureMenuItem(android.view.MenuItem, android.support.v4.app.ShareCompat.IntentBuilder);
+ method public static void configureMenuItem(android.view.Menu, int, android.support.v4.app.ShareCompat.IntentBuilder);
+ method public static android.content.ComponentName getCallingActivity(android.app.Activity);
+ method public static java.lang.String getCallingPackage(android.app.Activity);
+ field public static final java.lang.String EXTRA_CALLING_ACTIVITY = "android.support.v4.app.EXTRA_CALLING_ACTIVITY";
+ field public static final java.lang.String EXTRA_CALLING_PACKAGE = "android.support.v4.app.EXTRA_CALLING_PACKAGE";
+ }
+
+ public static class ShareCompat.IntentBuilder {
+ method public android.support.v4.app.ShareCompat.IntentBuilder addEmailBcc(java.lang.String);
+ method public android.support.v4.app.ShareCompat.IntentBuilder addEmailBcc(java.lang.String[]);
+ method public android.support.v4.app.ShareCompat.IntentBuilder addEmailCc(java.lang.String);
+ method public android.support.v4.app.ShareCompat.IntentBuilder addEmailCc(java.lang.String[]);
+ method public android.support.v4.app.ShareCompat.IntentBuilder addEmailTo(java.lang.String);
+ method public android.support.v4.app.ShareCompat.IntentBuilder addEmailTo(java.lang.String[]);
+ method public android.support.v4.app.ShareCompat.IntentBuilder addStream(android.net.Uri);
+ method public android.content.Intent createChooserIntent();
+ method public static android.support.v4.app.ShareCompat.IntentBuilder from(android.app.Activity);
+ method public android.content.Intent getIntent();
+ method public android.support.v4.app.ShareCompat.IntentBuilder setChooserTitle(java.lang.CharSequence);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setChooserTitle(int);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setEmailBcc(java.lang.String[]);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setEmailCc(java.lang.String[]);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setEmailTo(java.lang.String[]);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setHtmlText(java.lang.String);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setStream(android.net.Uri);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setSubject(java.lang.String);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setText(java.lang.CharSequence);
+ method public android.support.v4.app.ShareCompat.IntentBuilder setType(java.lang.String);
+ method public void startChooser();
+ }
+
+ public static class ShareCompat.IntentReader {
+ method public static android.support.v4.app.ShareCompat.IntentReader from(android.app.Activity);
+ method public android.content.ComponentName getCallingActivity();
+ method public android.graphics.drawable.Drawable getCallingActivityIcon();
+ method public android.graphics.drawable.Drawable getCallingApplicationIcon();
+ method public java.lang.CharSequence getCallingApplicationLabel();
+ method public java.lang.String getCallingPackage();
+ method public java.lang.String[] getEmailBcc();
+ method public java.lang.String[] getEmailCc();
+ method public java.lang.String[] getEmailTo();
+ method public java.lang.String getHtmlText();
+ method public android.net.Uri getStream();
+ method public android.net.Uri getStream(int);
+ method public int getStreamCount();
+ method public java.lang.String getSubject();
+ method public java.lang.CharSequence getText();
+ method public java.lang.String getType();
+ method public boolean isMultipleShare();
+ method public boolean isShareIntent();
+ method public boolean isSingleShare();
+ }
+
+ public abstract class SharedElementCallback {
+ ctor public SharedElementCallback();
+ method public android.os.Parcelable onCaptureSharedElementSnapshot(android.view.View, android.graphics.Matrix, android.graphics.RectF);
+ method public android.view.View onCreateSnapshotView(android.content.Context, android.os.Parcelable);
+ method public void onMapSharedElements(java.util.List<java.lang.String>, java.util.Map<java.lang.String, android.view.View>);
+ method public void onRejectSharedElements(java.util.List<android.view.View>);
+ method public void onSharedElementEnd(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>);
+ method public void onSharedElementStart(java.util.List<java.lang.String>, java.util.List<android.view.View>, java.util.List<android.view.View>);
+ method public void onSharedElementsArrived(java.util.List<java.lang.String>, java.util.List<android.view.View>, android.support.v4.app.SharedElementCallback.OnSharedElementsReadyListener);
+ }
+
+ public static abstract interface SharedElementCallback.OnSharedElementsReadyListener {
+ method public abstract void onSharedElementsReady();
+ }
+
+ public final class TaskStackBuilder implements java.lang.Iterable {
+ method public android.support.v4.app.TaskStackBuilder addNextIntent(android.content.Intent);
+ method public android.support.v4.app.TaskStackBuilder addNextIntentWithParentStack(android.content.Intent);
+ method public android.support.v4.app.TaskStackBuilder addParentStack(android.app.Activity);
+ method public android.support.v4.app.TaskStackBuilder addParentStack(java.lang.Class<?>);
+ method public android.support.v4.app.TaskStackBuilder addParentStack(android.content.ComponentName);
+ method public static android.support.v4.app.TaskStackBuilder create(android.content.Context);
+ method public android.content.Intent editIntentAt(int);
+ method public static deprecated android.support.v4.app.TaskStackBuilder from(android.content.Context);
+ method public deprecated android.content.Intent getIntent(int);
+ method public int getIntentCount();
+ method public android.content.Intent[] getIntents();
+ method public android.app.PendingIntent getPendingIntent(int, int);
+ method public android.app.PendingIntent getPendingIntent(int, int, android.os.Bundle);
+ method public deprecated java.util.Iterator<android.content.Intent> iterator();
+ method public void startActivities();
+ method public void startActivities(android.os.Bundle);
+ }
+
+ public static abstract interface TaskStackBuilder.SupportParentable {
+ method public abstract android.content.Intent getSupportParentActivityIntent();
+ }
+
+}
+
+package android.support.v4.content {
+
+ public abstract class AsyncTaskLoader<D> extends android.support.v4.content.Loader {
+ ctor public AsyncTaskLoader(android.content.Context);
+ method public void cancelLoadInBackground();
+ method public boolean isLoadInBackgroundCanceled();
+ method public abstract D loadInBackground();
+ method public void onCanceled(D);
+ method protected D onLoadInBackground();
+ method public void setUpdateThrottle(long);
+ }
+
+ public final class ContentResolverCompat {
+ method public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.support.v4.os.CancellationSignal);
+ }
+
+ public class ContextCompat {
+ ctor protected ContextCompat();
+ method public static int checkSelfPermission(android.content.Context, java.lang.String);
+ method public static android.content.Context createDeviceProtectedStorageContext(android.content.Context);
+ method public static java.io.File getCodeCacheDir(android.content.Context);
+ method public static final int getColor(android.content.Context, int);
+ method public static final android.content.res.ColorStateList getColorStateList(android.content.Context, int);
+ method public static java.io.File getDataDir(android.content.Context);
+ method public static final android.graphics.drawable.Drawable getDrawable(android.content.Context, int);
+ method public static java.io.File[] getExternalCacheDirs(android.content.Context);
+ method public static java.io.File[] getExternalFilesDirs(android.content.Context, java.lang.String);
+ method public static final java.io.File getNoBackupFilesDir(android.content.Context);
+ method public static java.io.File[] getObbDirs(android.content.Context);
+ method public static boolean isDeviceProtectedStorage(android.content.Context);
+ method public static boolean startActivities(android.content.Context, android.content.Intent[]);
+ method public static boolean startActivities(android.content.Context, android.content.Intent[], android.os.Bundle);
+ method public static void startActivity(android.content.Context, android.content.Intent, android.os.Bundle);
+ }
+
+ public class CursorLoader extends android.support.v4.content.AsyncTaskLoader {
+ ctor public CursorLoader(android.content.Context);
+ ctor public CursorLoader(android.content.Context, android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
+ method public void deliverResult(android.database.Cursor);
+ method public java.lang.String[] getProjection();
+ method public java.lang.String getSelection();
+ method public java.lang.String[] getSelectionArgs();
+ method public java.lang.String getSortOrder();
+ method public android.net.Uri getUri();
+ method public android.database.Cursor loadInBackground();
+ method public void onCanceled(android.database.Cursor);
+ method public void setProjection(java.lang.String[]);
+ method public void setSelection(java.lang.String);
+ method public void setSelectionArgs(java.lang.String[]);
+ method public void setSortOrder(java.lang.String);
+ method public void setUri(android.net.Uri);
+ }
+
+ public class FileProvider extends android.content.ContentProvider {
+ ctor public FileProvider();
+ method public int delete(android.net.Uri, java.lang.String, java.lang.String[]);
+ method public java.lang.String getType(android.net.Uri);
+ method public static android.net.Uri getUriForFile(android.content.Context, java.lang.String, java.io.File);
+ method public android.net.Uri insert(android.net.Uri, android.content.ContentValues);
+ method public boolean onCreate();
+ method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
+ method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
+ }
+
+ public final class IntentCompat {
+ method public static deprecated android.content.Intent makeMainActivity(android.content.ComponentName);
+ method public static android.content.Intent makeMainSelectorActivity(java.lang.String, java.lang.String);
+ method public static deprecated android.content.Intent makeRestartActivityTask(android.content.ComponentName);
+ field public static final deprecated java.lang.String ACTION_EXTERNAL_APPLICATIONS_AVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE";
+ field public static final deprecated java.lang.String ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE";
+ field public static final java.lang.String CATEGORY_LEANBACK_LAUNCHER = "android.intent.category.LEANBACK_LAUNCHER";
+ field public static final deprecated java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
+ field public static final deprecated java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list";
+ field public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
+ field public static final deprecated int FLAG_ACTIVITY_CLEAR_TASK = 32768; // 0x8000
+ field public static final deprecated int FLAG_ACTIVITY_TASK_ON_HOME = 16384; // 0x4000
+ }
+
+ public class Loader<D> {
+ ctor public Loader(android.content.Context);
+ method public void abandon();
+ method public boolean cancelLoad();
+ method public void commitContentChanged();
+ method public java.lang.String dataToString(D);
+ method public void deliverCancellation();
+ method public void deliverResult(D);
+ method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public void forceLoad();
+ method public android.content.Context getContext();
+ method public int getId();
+ method public boolean isAbandoned();
+ method public boolean isReset();
+ method public boolean isStarted();
+ method protected void onAbandon();
+ method protected boolean onCancelLoad();
+ method public void onContentChanged();
+ method protected void onForceLoad();
+ method protected void onReset();
+ method protected void onStartLoading();
+ method protected void onStopLoading();
+ method public void registerListener(int, android.support.v4.content.Loader.OnLoadCompleteListener<D>);
+ method public void registerOnLoadCanceledListener(android.support.v4.content.Loader.OnLoadCanceledListener<D>);
+ method public void reset();
+ method public void rollbackContentChanged();
+ method public final void startLoading();
+ method public void stopLoading();
+ method public boolean takeContentChanged();
+ method public void unregisterListener(android.support.v4.content.Loader.OnLoadCompleteListener<D>);
+ method public void unregisterOnLoadCanceledListener(android.support.v4.content.Loader.OnLoadCanceledListener<D>);
+ }
+
+ public final class Loader.ForceLoadContentObserver extends android.database.ContentObserver {
+ ctor public Loader.ForceLoadContentObserver();
+ }
+
+ public static abstract interface Loader.OnLoadCanceledListener<D> {
+ method public abstract void onLoadCanceled(android.support.v4.content.Loader<D>);
+ }
+
+ public static abstract interface Loader.OnLoadCompleteListener<D> {
+ method public abstract void onLoadComplete(android.support.v4.content.Loader<D>, D);
+ }
+
+ public final class LocalBroadcastManager {
+ method public static android.support.v4.content.LocalBroadcastManager getInstance(android.content.Context);
+ method public void registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter);
+ method public boolean sendBroadcast(android.content.Intent);
+ method public void sendBroadcastSync(android.content.Intent);
+ method public void unregisterReceiver(android.content.BroadcastReceiver);
+ }
+
+ public final class MimeTypeFilter {
+ method public static boolean matches(java.lang.String, java.lang.String);
+ method public static java.lang.String matches(java.lang.String, java.lang.String[]);
+ method public static java.lang.String matches(java.lang.String[], java.lang.String);
+ method public static java.lang.String[] matchesMany(java.lang.String[], java.lang.String);
+ }
+
+ public final deprecated class ParallelExecutorCompat {
+ method public static deprecated java.util.concurrent.Executor getParallelExecutor();
+ }
+
+ public final class PermissionChecker {
+ method public static int checkCallingOrSelfPermission(android.content.Context, java.lang.String);
+ method public static int checkCallingPermission(android.content.Context, java.lang.String, java.lang.String);
+ method public static int checkPermission(android.content.Context, java.lang.String, int, int, java.lang.String);
+ method public static int checkSelfPermission(android.content.Context, java.lang.String);
+ field public static final int PERMISSION_DENIED = -1; // 0xffffffff
+ field public static final int PERMISSION_DENIED_APP_OP = -2; // 0xfffffffe
+ field public static final int PERMISSION_GRANTED = 0; // 0x0
+ }
+
+ public static abstract class PermissionChecker.PermissionResult implements java.lang.annotation.Annotation {
+ }
+
+ public final class SharedPreferencesCompat {
+ }
+
+ public static final class SharedPreferencesCompat.EditorCompat {
+ method public void apply(android.content.SharedPreferences.Editor);
+ method public static android.support.v4.content.SharedPreferencesCompat.EditorCompat getInstance();
+ }
+
+ public abstract class WakefulBroadcastReceiver extends android.content.BroadcastReceiver {
+ ctor public WakefulBroadcastReceiver();
+ method public static boolean completeWakefulIntent(android.content.Intent);
+ method public static android.content.ComponentName startWakefulService(android.content.Context, android.content.Intent);
+ }
+
+}
+
+package android.support.v4.content.pm {
+
+ public final class ActivityInfoCompat {
+ field public static final int CONFIG_UI_MODE = 512; // 0x200
+ }
+
+ public class ShortcutInfoCompat {
+ }
+
+ public static class ShortcutInfoCompat.Builder {
+ ctor public ShortcutInfoCompat.Builder(android.content.Context, java.lang.String);
+ method public android.support.v4.content.pm.ShortcutInfoCompat build();
+ method public android.support.v4.content.pm.ShortcutInfoCompat.Builder setActivity(android.content.ComponentName);
+ method public android.support.v4.content.pm.ShortcutInfoCompat.Builder setDisabledMessage(java.lang.CharSequence);
+ method public android.support.v4.content.pm.ShortcutInfoCompat.Builder setIcon(android.graphics.Bitmap);
+ method public android.support.v4.content.pm.ShortcutInfoCompat.Builder setIcon(int);
+ method public android.support.v4.content.pm.ShortcutInfoCompat.Builder setIntent(android.content.Intent);
+ method public android.support.v4.content.pm.ShortcutInfoCompat.Builder setIntents(android.content.Intent[]);
+ method public android.support.v4.content.pm.ShortcutInfoCompat.Builder setLongLabel(java.lang.CharSequence);
+ method public android.support.v4.content.pm.ShortcutInfoCompat.Builder setShortLabel(java.lang.CharSequence);
+ }
+
+ public class ShortcutManagerCompat {
+ ctor public ShortcutManagerCompat();
+ method public static android.content.Intent createShortcutResultIntent(android.content.Context, android.support.v4.content.pm.ShortcutInfoCompat);
+ method public static boolean isRequestPinShortcutSupported(android.content.Context);
+ method public static boolean requestPinShortcut(android.content.Context, android.support.v4.content.pm.ShortcutInfoCompat, android.content.IntentSender);
+ }
+
+}
+
+package android.support.v4.content.res {
+
+ public final class ConfigurationHelper {
+ method public static int getDensityDpi(android.content.res.Resources);
+ method public static deprecated int getScreenHeightDp(android.content.res.Resources);
+ method public static deprecated int getScreenWidthDp(android.content.res.Resources);
+ method public static deprecated int getSmallestScreenWidthDp(android.content.res.Resources);
+ }
+
+ public final class ResourcesCompat {
+ method public static int getColor(android.content.res.Resources, int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
+ method public static android.content.res.ColorStateList getColorStateList(android.content.res.Resources, int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
+ method public static android.graphics.drawable.Drawable getDrawable(android.content.res.Resources, int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
+ method public static android.graphics.drawable.Drawable getDrawableForDensity(android.content.res.Resources, int, int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
+ }
+
+}
+
+package android.support.v4.database {
+
+ public final class DatabaseUtilsCompat {
+ method public static java.lang.String[] appendSelectionArgs(java.lang.String[], java.lang.String[]);
+ method public static java.lang.String concatenateWhere(java.lang.String, java.lang.String);
+ }
+
+}
+
+package android.support.v4.graphics {
+
+ public final class BitmapCompat {
+ method public static int getAllocationByteCount(android.graphics.Bitmap);
+ method public static boolean hasMipMap(android.graphics.Bitmap);
+ method public static void setHasMipMap(android.graphics.Bitmap, boolean);
+ }
+
+ public final class ColorUtils {
+ method public static int HSLToColor(float[]);
+ method public static int LABToColor(double, double, double);
+ method public static void LABToXYZ(double, double, double, double[]);
+ method public static void RGBToHSL(int, int, int, float[]);
+ method public static void RGBToLAB(int, int, int, double[]);
+ method public static void RGBToXYZ(int, int, int, double[]);
+ method public static int XYZToColor(double, double, double);
+ method public static void XYZToLAB(double, double, double, double[]);
+ method public static int blendARGB(int, int, float);
+ method public static void blendHSL(float[], float[], float, float[]);
+ method public static void blendLAB(double[], double[], double, double[]);
+ method public static double calculateContrast(int, int);
+ method public static double calculateLuminance(int);
+ method public static int calculateMinimumAlpha(int, int, float);
+ method public static void colorToHSL(int, float[]);
+ method public static void colorToLAB(int, double[]);
+ method public static void colorToXYZ(int, double[]);
+ method public static int compositeColors(int, int);
+ method public static double distanceEuclidean(double[], double[]);
+ method public static int setAlphaComponent(int, int);
+ }
+
+ public final class PaintCompat {
+ method public static boolean hasGlyph(android.graphics.Paint, java.lang.String);
+ }
+
+}
+
+package android.support.v4.graphics.drawable {
+
+ public final class DrawableCompat {
+ method public static void applyTheme(android.graphics.drawable.Drawable, android.content.res.Resources.Theme);
+ method public static boolean canApplyTheme(android.graphics.drawable.Drawable);
+ method public static void clearColorFilter(android.graphics.drawable.Drawable);
+ method public static int getAlpha(android.graphics.drawable.Drawable);
+ method public static android.graphics.ColorFilter getColorFilter(android.graphics.drawable.Drawable);
+ method public static int getLayoutDirection(android.graphics.drawable.Drawable);
+ method public static void inflate(android.graphics.drawable.Drawable, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static boolean isAutoMirrored(android.graphics.drawable.Drawable);
+ method public static void jumpToCurrentState(android.graphics.drawable.Drawable);
+ method public static void setAutoMirrored(android.graphics.drawable.Drawable, boolean);
+ method public static void setHotspot(android.graphics.drawable.Drawable, float, float);
+ method public static void setHotspotBounds(android.graphics.drawable.Drawable, int, int, int, int);
+ method public static boolean setLayoutDirection(android.graphics.drawable.Drawable, int);
+ method public static void setTint(android.graphics.drawable.Drawable, int);
+ method public static void setTintList(android.graphics.drawable.Drawable, android.content.res.ColorStateList);
+ method public static void setTintMode(android.graphics.drawable.Drawable, android.graphics.PorterDuff.Mode);
+ method public static <T extends android.graphics.drawable.Drawable> T unwrap(android.graphics.drawable.Drawable);
+ method public static android.graphics.drawable.Drawable wrap(android.graphics.drawable.Drawable);
+ }
+
+ public abstract class RoundedBitmapDrawable extends android.graphics.drawable.Drawable {
+ method public void draw(android.graphics.Canvas);
+ method public final android.graphics.Bitmap getBitmap();
+ method public float getCornerRadius();
+ method public int getGravity();
+ method public int getOpacity();
+ method public final android.graphics.Paint getPaint();
+ method public boolean hasAntiAlias();
+ method public boolean hasMipMap();
+ method public boolean isCircular();
+ method public void setAlpha(int);
+ method public void setAntiAlias(boolean);
+ method public void setCircular(boolean);
+ method public void setColorFilter(android.graphics.ColorFilter);
+ method public void setCornerRadius(float);
+ method public void setGravity(int);
+ method public void setMipMap(boolean);
+ method public void setTargetDensity(android.graphics.Canvas);
+ method public void setTargetDensity(android.util.DisplayMetrics);
+ method public void setTargetDensity(int);
+ }
+
+ public final class RoundedBitmapDrawableFactory {
+ method public static android.support.v4.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, android.graphics.Bitmap);
+ method public static android.support.v4.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, java.lang.String);
+ method public static android.support.v4.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, java.io.InputStream);
+ }
+
+}
+
+package android.support.v4.hardware.display {
+
+ public abstract class DisplayManagerCompat {
+ method public abstract android.view.Display getDisplay(int);
+ method public abstract android.view.Display[] getDisplays();
+ method public abstract android.view.Display[] getDisplays(java.lang.String);
+ method public static android.support.v4.hardware.display.DisplayManagerCompat getInstance(android.content.Context);
+ field public static final java.lang.String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";
+ }
+
+}
+
+package android.support.v4.hardware.fingerprint {
+
+ public final class FingerprintManagerCompat {
+ method public void authenticate(android.support.v4.hardware.fingerprint.FingerprintManagerCompat.CryptoObject, int, android.support.v4.os.CancellationSignal, android.support.v4.hardware.fingerprint.FingerprintManagerCompat.AuthenticationCallback, android.os.Handler);
+ method public static android.support.v4.hardware.fingerprint.FingerprintManagerCompat from(android.content.Context);
+ method public boolean hasEnrolledFingerprints();
+ method public boolean isHardwareDetected();
+ }
+
+ public static abstract class FingerprintManagerCompat.AuthenticationCallback {
+ ctor public FingerprintManagerCompat.AuthenticationCallback();
+ method public void onAuthenticationError(int, java.lang.CharSequence);
+ method public void onAuthenticationFailed();
+ method public void onAuthenticationHelp(int, java.lang.CharSequence);
+ method public void onAuthenticationSucceeded(android.support.v4.hardware.fingerprint.FingerprintManagerCompat.AuthenticationResult);
+ }
+
+ public static final class FingerprintManagerCompat.AuthenticationResult {
+ ctor public FingerprintManagerCompat.AuthenticationResult(android.support.v4.hardware.fingerprint.FingerprintManagerCompat.CryptoObject);
+ method public android.support.v4.hardware.fingerprint.FingerprintManagerCompat.CryptoObject getCryptoObject();
+ }
+
+ public static class FingerprintManagerCompat.CryptoObject {
+ ctor public FingerprintManagerCompat.CryptoObject(java.security.Signature);
+ ctor public FingerprintManagerCompat.CryptoObject(javax.crypto.Cipher);
+ ctor public FingerprintManagerCompat.CryptoObject(javax.crypto.Mac);
+ method public javax.crypto.Cipher getCipher();
+ method public javax.crypto.Mac getMac();
+ method public java.security.Signature getSignature();
+ }
+
+}
+
+package android.support.v4.math {
+
+ public class MathUtils {
+ ctor public MathUtils();
+ method public static float clamp(float, int, int);
+ method public static double clamp(double, double, double);
+ method public static int clamp(int, int, int);
+ }
+
+}
+
+package android.support.v4.media {
+
+ public final class MediaBrowserCompat {
+ ctor public MediaBrowserCompat(android.content.Context, android.content.ComponentName, android.support.v4.media.MediaBrowserCompat.ConnectionCallback, android.os.Bundle);
+ method public void connect();
+ method public void disconnect();
+ method public android.os.Bundle getExtras();
+ method public void getItem(java.lang.String, android.support.v4.media.MediaBrowserCompat.ItemCallback);
+ method public java.lang.String getRoot();
+ method public android.content.ComponentName getServiceComponent();
+ method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
+ method public boolean isConnected();
+ method public void subscribe(java.lang.String, android.support.v4.media.MediaBrowserCompat.SubscriptionCallback);
+ method public void subscribe(java.lang.String, android.os.Bundle, android.support.v4.media.MediaBrowserCompat.SubscriptionCallback);
+ method public void unsubscribe(java.lang.String);
+ method public void unsubscribe(java.lang.String, android.support.v4.media.MediaBrowserCompat.SubscriptionCallback);
+ field public static final java.lang.String EXTRA_PAGE = "android.media.browse.extra.PAGE";
+ field public static final java.lang.String EXTRA_PAGE_SIZE = "android.media.browse.extra.PAGE_SIZE";
+ }
+
+ public static class MediaBrowserCompat.ConnectionCallback {
+ ctor public MediaBrowserCompat.ConnectionCallback();
+ method public void onConnected();
+ method public void onConnectionFailed();
+ method public void onConnectionSuspended();
+ }
+
+ public static abstract class MediaBrowserCompat.ItemCallback {
+ ctor public MediaBrowserCompat.ItemCallback();
+ method public void onError(java.lang.String);
+ method public void onItemLoaded(android.support.v4.media.MediaBrowserCompat.MediaItem);
+ }
+
+ public static class MediaBrowserCompat.MediaItem implements android.os.Parcelable {
+ ctor public MediaBrowserCompat.MediaItem(android.support.v4.media.MediaDescriptionCompat, int);
+ method public int describeContents();
+ method public static android.support.v4.media.MediaBrowserCompat.MediaItem fromMediaItem(java.lang.Object);
+ method public static java.util.List<android.support.v4.media.MediaBrowserCompat.MediaItem> fromMediaItemList(java.util.List<?>);
+ method public android.support.v4.media.MediaDescriptionCompat getDescription();
+ method public int getFlags();
+ method public java.lang.String getMediaId();
+ method public boolean isBrowsable();
+ method public boolean isPlayable();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.MediaBrowserCompat.MediaItem> CREATOR;
+ field public static final int FLAG_BROWSABLE = 1; // 0x1
+ field public static final int FLAG_PLAYABLE = 2; // 0x2
+ }
+
+ public static abstract class MediaBrowserCompat.SubscriptionCallback {
+ ctor public MediaBrowserCompat.SubscriptionCallback();
+ method public void onChildrenLoaded(java.lang.String, java.util.List<android.support.v4.media.MediaBrowserCompat.MediaItem>);
+ method public void onChildrenLoaded(java.lang.String, java.util.List<android.support.v4.media.MediaBrowserCompat.MediaItem>, android.os.Bundle);
+ method public void onError(java.lang.String);
+ method public void onError(java.lang.String, android.os.Bundle);
+ }
+
+ public abstract class MediaBrowserServiceCompat extends android.app.Service {
+ ctor public MediaBrowserServiceCompat();
+ method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public final android.os.Bundle getBrowserRootHints();
+ method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
+ method public void notifyChildrenChanged(java.lang.String);
+ method public void notifyChildrenChanged(java.lang.String, android.os.Bundle);
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public abstract android.support.v4.media.MediaBrowserServiceCompat.BrowserRoot onGetRoot(java.lang.String, int, android.os.Bundle);
+ method public abstract void onLoadChildren(java.lang.String, android.support.v4.media.MediaBrowserServiceCompat.Result<java.util.List<android.support.v4.media.MediaBrowserCompat.MediaItem>>);
+ method public void onLoadChildren(java.lang.String, android.support.v4.media.MediaBrowserServiceCompat.Result<java.util.List<android.support.v4.media.MediaBrowserCompat.MediaItem>>, android.os.Bundle);
+ method public void onLoadItem(java.lang.String, android.support.v4.media.MediaBrowserServiceCompat.Result<android.support.v4.media.MediaBrowserCompat.MediaItem>);
+ method public void setSessionToken(android.support.v4.media.session.MediaSessionCompat.Token);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.media.browse.MediaBrowserService";
+ }
+
+ public static final class MediaBrowserServiceCompat.BrowserRoot {
+ ctor public MediaBrowserServiceCompat.BrowserRoot(java.lang.String, android.os.Bundle);
+ method public android.os.Bundle getExtras();
+ method public java.lang.String getRootId();
+ field public static final java.lang.String EXTRA_OFFLINE = "android.service.media.extra.OFFLINE";
+ field public static final java.lang.String EXTRA_RECENT = "android.service.media.extra.RECENT";
+ field public static final java.lang.String EXTRA_SUGGESTED = "android.service.media.extra.SUGGESTED";
+ field public static final java.lang.String EXTRA_SUGGESTION_KEYWORDS = "android.service.media.extra.SUGGESTION_KEYWORDS";
+ }
+
+ public static class MediaBrowserServiceCompat.Result<T> {
+ method public void detach();
+ method public void sendResult(T);
+ }
+
+ public final class MediaDescriptionCompat implements android.os.Parcelable {
+ method public int describeContents();
+ method public static android.support.v4.media.MediaDescriptionCompat fromMediaDescription(java.lang.Object);
+ method public java.lang.CharSequence getDescription();
+ method public android.os.Bundle getExtras();
+ method public android.graphics.Bitmap getIconBitmap();
+ method public android.net.Uri getIconUri();
+ method public java.lang.Object getMediaDescription();
+ method public java.lang.String getMediaId();
+ method public android.net.Uri getMediaUri();
+ method public java.lang.CharSequence getSubtitle();
+ method public java.lang.CharSequence getTitle();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final long BT_FOLDER_TYPE_ALBUMS = 2L; // 0x2L
+ field public static final long BT_FOLDER_TYPE_ARTISTS = 3L; // 0x3L
+ field public static final long BT_FOLDER_TYPE_GENRES = 4L; // 0x4L
+ field public static final long BT_FOLDER_TYPE_MIXED = 0L; // 0x0L
+ field public static final long BT_FOLDER_TYPE_PLAYLISTS = 5L; // 0x5L
+ field public static final long BT_FOLDER_TYPE_TITLES = 1L; // 0x1L
+ field public static final long BT_FOLDER_TYPE_YEARS = 6L; // 0x6L
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.MediaDescriptionCompat> CREATOR;
+ field public static final java.lang.String EXTRA_BT_FOLDER_TYPE = "android.media.extra.BT_FOLDER_TYPE";
+ }
+
+ public static final class MediaDescriptionCompat.Builder {
+ ctor public MediaDescriptionCompat.Builder();
+ method public android.support.v4.media.MediaDescriptionCompat build();
+ method public android.support.v4.media.MediaDescriptionCompat.Builder setDescription(java.lang.CharSequence);
+ method public android.support.v4.media.MediaDescriptionCompat.Builder setExtras(android.os.Bundle);
+ method public android.support.v4.media.MediaDescriptionCompat.Builder setIconBitmap(android.graphics.Bitmap);
+ method public android.support.v4.media.MediaDescriptionCompat.Builder setIconUri(android.net.Uri);
+ method public android.support.v4.media.MediaDescriptionCompat.Builder setMediaId(java.lang.String);
+ method public android.support.v4.media.MediaDescriptionCompat.Builder setMediaUri(android.net.Uri);
+ method public android.support.v4.media.MediaDescriptionCompat.Builder setSubtitle(java.lang.CharSequence);
+ method public android.support.v4.media.MediaDescriptionCompat.Builder setTitle(java.lang.CharSequence);
+ }
+
+ public final class MediaMetadataCompat implements android.os.Parcelable {
+ method public boolean containsKey(java.lang.String);
+ method public int describeContents();
+ method public static android.support.v4.media.MediaMetadataCompat fromMediaMetadata(java.lang.Object);
+ method public android.graphics.Bitmap getBitmap(java.lang.String);
+ method public android.os.Bundle getBundle();
+ method public android.support.v4.media.MediaDescriptionCompat getDescription();
+ method public long getLong(java.lang.String);
+ method public java.lang.Object getMediaMetadata();
+ method public android.support.v4.media.RatingCompat getRating(java.lang.String);
+ method public java.lang.String getString(java.lang.String);
+ method public java.lang.CharSequence getText(java.lang.String);
+ method public java.util.Set<java.lang.String> keySet();
+ method public int size();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.MediaMetadataCompat> CREATOR;
+ field public static final java.lang.String METADATA_KEY_ADVERTISEMENT = "android.media.metadata.ADVERTISEMENT";
+ field public static final java.lang.String METADATA_KEY_ALBUM = "android.media.metadata.ALBUM";
+ field public static final java.lang.String METADATA_KEY_ALBUM_ART = "android.media.metadata.ALBUM_ART";
+ field public static final java.lang.String METADATA_KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST";
+ field public static final java.lang.String METADATA_KEY_ALBUM_ART_URI = "android.media.metadata.ALBUM_ART_URI";
+ field public static final java.lang.String METADATA_KEY_ART = "android.media.metadata.ART";
+ field public static final java.lang.String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST";
+ field public static final java.lang.String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI";
+ field public static final java.lang.String METADATA_KEY_AUTHOR = "android.media.metadata.AUTHOR";
+ field public static final java.lang.String METADATA_KEY_BT_FOLDER_TYPE = "android.media.metadata.BT_FOLDER_TYPE";
+ field public static final java.lang.String METADATA_KEY_COMPILATION = "android.media.metadata.COMPILATION";
+ field public static final java.lang.String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER";
+ field public static final java.lang.String METADATA_KEY_DATE = "android.media.metadata.DATE";
+ field public static final java.lang.String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
+ field public static final java.lang.String METADATA_KEY_DISPLAY_DESCRIPTION = "android.media.metadata.DISPLAY_DESCRIPTION";
+ field public static final java.lang.String METADATA_KEY_DISPLAY_ICON = "android.media.metadata.DISPLAY_ICON";
+ field public static final java.lang.String METADATA_KEY_DISPLAY_ICON_URI = "android.media.metadata.DISPLAY_ICON_URI";
+ field public static final java.lang.String METADATA_KEY_DISPLAY_SUBTITLE = "android.media.metadata.DISPLAY_SUBTITLE";
+ field public static final java.lang.String METADATA_KEY_DISPLAY_TITLE = "android.media.metadata.DISPLAY_TITLE";
+ field public static final java.lang.String METADATA_KEY_DURATION = "android.media.metadata.DURATION";
+ field public static final java.lang.String METADATA_KEY_GENRE = "android.media.metadata.GENRE";
+ field public static final java.lang.String METADATA_KEY_MEDIA_ID = "android.media.metadata.MEDIA_ID";
+ field public static final java.lang.String METADATA_KEY_MEDIA_URI = "android.media.metadata.MEDIA_URI";
+ field public static final java.lang.String METADATA_KEY_NUM_TRACKS = "android.media.metadata.NUM_TRACKS";
+ field public static final java.lang.String METADATA_KEY_RATING = "android.media.metadata.RATING";
+ field public static final java.lang.String METADATA_KEY_TITLE = "android.media.metadata.TITLE";
+ field public static final java.lang.String METADATA_KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER";
+ field public static final java.lang.String METADATA_KEY_USER_RATING = "android.media.metadata.USER_RATING";
+ field public static final java.lang.String METADATA_KEY_WRITER = "android.media.metadata.WRITER";
+ field public static final java.lang.String METADATA_KEY_YEAR = "android.media.metadata.YEAR";
+ }
+
+ public static final class MediaMetadataCompat.Builder {
+ ctor public MediaMetadataCompat.Builder();
+ ctor public MediaMetadataCompat.Builder(android.support.v4.media.MediaMetadataCompat);
+ method public android.support.v4.media.MediaMetadataCompat build();
+ method public android.support.v4.media.MediaMetadataCompat.Builder putBitmap(java.lang.String, android.graphics.Bitmap);
+ method public android.support.v4.media.MediaMetadataCompat.Builder putLong(java.lang.String, long);
+ method public android.support.v4.media.MediaMetadataCompat.Builder putRating(java.lang.String, android.support.v4.media.RatingCompat);
+ method public android.support.v4.media.MediaMetadataCompat.Builder putString(java.lang.String, java.lang.String);
+ method public android.support.v4.media.MediaMetadataCompat.Builder putText(java.lang.String, java.lang.CharSequence);
+ }
+
+ public final class RatingCompat implements android.os.Parcelable {
+ method public int describeContents();
+ method public static android.support.v4.media.RatingCompat fromRating(java.lang.Object);
+ method public float getPercentRating();
+ method public java.lang.Object getRating();
+ method public int getRatingStyle();
+ method public float getStarRating();
+ method public boolean hasHeart();
+ method public boolean isRated();
+ method public boolean isThumbUp();
+ method public static android.support.v4.media.RatingCompat newHeartRating(boolean);
+ method public static android.support.v4.media.RatingCompat newPercentageRating(float);
+ method public static android.support.v4.media.RatingCompat newStarRating(int, float);
+ method public static android.support.v4.media.RatingCompat newThumbRating(boolean);
+ method public static android.support.v4.media.RatingCompat newUnratedRating(int);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.RatingCompat> CREATOR;
+ field public static final int RATING_3_STARS = 3; // 0x3
+ field public static final int RATING_4_STARS = 4; // 0x4
+ field public static final int RATING_5_STARS = 5; // 0x5
+ field public static final int RATING_HEART = 1; // 0x1
+ field public static final int RATING_NONE = 0; // 0x0
+ field public static final int RATING_PERCENTAGE = 6; // 0x6
+ field public static final int RATING_THUMB_UP_DOWN = 2; // 0x2
+ }
+
+ public abstract class TransportController {
+ ctor public TransportController();
+ method public abstract int getBufferPercentage();
+ method public abstract long getCurrentPosition();
+ method public abstract long getDuration();
+ method public abstract int getTransportControlFlags();
+ method public abstract boolean isPlaying();
+ method public abstract void pausePlaying();
+ method public abstract void registerStateListener(android.support.v4.media.TransportStateListener);
+ method public abstract void seekTo(long);
+ method public abstract void startPlaying();
+ method public abstract void stopPlaying();
+ method public abstract void unregisterStateListener(android.support.v4.media.TransportStateListener);
+ }
+
+ public class TransportMediator extends android.support.v4.media.TransportController {
+ ctor public TransportMediator(android.app.Activity, android.support.v4.media.TransportPerformer);
+ ctor public TransportMediator(android.view.View, android.support.v4.media.TransportPerformer);
+ method public void destroy();
+ method public boolean dispatchKeyEvent(android.view.KeyEvent);
+ method public int getBufferPercentage();
+ method public long getCurrentPosition();
+ method public long getDuration();
+ method public java.lang.Object getRemoteControlClient();
+ method public int getTransportControlFlags();
+ method public boolean isPlaying();
+ method public void pausePlaying();
+ method public void refreshState();
+ method public void registerStateListener(android.support.v4.media.TransportStateListener);
+ method public void seekTo(long);
+ method public void startPlaying();
+ method public void stopPlaying();
+ method public void unregisterStateListener(android.support.v4.media.TransportStateListener);
+ field public static final int FLAG_KEY_MEDIA_FAST_FORWARD = 64; // 0x40
+ field public static final int FLAG_KEY_MEDIA_NEXT = 128; // 0x80
+ field public static final int FLAG_KEY_MEDIA_PAUSE = 16; // 0x10
+ field public static final int FLAG_KEY_MEDIA_PLAY = 4; // 0x4
+ field public static final int FLAG_KEY_MEDIA_PLAY_PAUSE = 8; // 0x8
+ field public static final int FLAG_KEY_MEDIA_PREVIOUS = 1; // 0x1
+ field public static final int FLAG_KEY_MEDIA_REWIND = 2; // 0x2
+ field public static final int FLAG_KEY_MEDIA_STOP = 32; // 0x20
+ field public static final int KEYCODE_MEDIA_PAUSE = 127; // 0x7f
+ field public static final int KEYCODE_MEDIA_PLAY = 126; // 0x7e
+ field public static final int KEYCODE_MEDIA_RECORD = 130; // 0x82
+ }
+
+ public abstract class TransportPerformer {
+ ctor public TransportPerformer();
+ method public void onAudioFocusChange(int);
+ method public int onGetBufferPercentage();
+ method public abstract long onGetCurrentPosition();
+ method public abstract long onGetDuration();
+ method public int onGetTransportControlFlags();
+ method public abstract boolean onIsPlaying();
+ method public boolean onMediaButtonDown(int, android.view.KeyEvent);
+ method public boolean onMediaButtonUp(int, android.view.KeyEvent);
+ method public abstract void onPause();
+ method public abstract void onSeekTo(long);
+ method public abstract void onStart();
+ method public abstract void onStop();
+ }
+
+ public class TransportStateListener {
+ ctor public TransportStateListener();
+ method public void onPlayingChanged(android.support.v4.media.TransportController);
+ method public void onTransportControlsChanged(android.support.v4.media.TransportController);
+ }
+
+ public abstract class VolumeProviderCompat {
+ ctor public VolumeProviderCompat(int, int, int);
+ method public final int getCurrentVolume();
+ method public final int getMaxVolume();
+ method public final int getVolumeControl();
+ method public java.lang.Object getVolumeProvider();
+ method public void onAdjustVolume(int);
+ method public void onSetVolumeTo(int);
+ method public void setCallback(android.support.v4.media.VolumeProviderCompat.Callback);
+ method public final void setCurrentVolume(int);
+ field public static final int VOLUME_CONTROL_ABSOLUTE = 2; // 0x2
+ field public static final int VOLUME_CONTROL_FIXED = 0; // 0x0
+ field public static final int VOLUME_CONTROL_RELATIVE = 1; // 0x1
+ }
+
+ public static abstract class VolumeProviderCompat.Callback {
+ ctor public VolumeProviderCompat.Callback();
+ method public abstract void onVolumeChanged(android.support.v4.media.VolumeProviderCompat);
+ }
+
+}
+
+package android.support.v4.media.session {
+
+ public class MediaButtonReceiver extends android.content.BroadcastReceiver {
+ ctor public MediaButtonReceiver();
+ method public static android.app.PendingIntent buildMediaButtonPendingIntent(android.content.Context, long);
+ method public static android.app.PendingIntent buildMediaButtonPendingIntent(android.content.Context, android.content.ComponentName, long);
+ method public static android.view.KeyEvent handleIntent(android.support.v4.media.session.MediaSessionCompat, android.content.Intent);
+ method public void onReceive(android.content.Context, android.content.Intent);
+ }
+
+ public final class MediaControllerCompat {
+ ctor public MediaControllerCompat(android.content.Context, android.support.v4.media.session.MediaSessionCompat);
+ ctor public MediaControllerCompat(android.content.Context, android.support.v4.media.session.MediaSessionCompat.Token) throws android.os.RemoteException;
+ method public void adjustVolume(int, int);
+ method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
+ method public android.os.Bundle getExtras();
+ method public long getFlags();
+ method public static android.support.v4.media.session.MediaControllerCompat getMediaController(android.app.Activity);
+ method public java.lang.Object getMediaController();
+ method public android.support.v4.media.MediaMetadataCompat getMetadata();
+ method public java.lang.String getPackageName();
+ method public android.support.v4.media.session.MediaControllerCompat.PlaybackInfo getPlaybackInfo();
+ method public android.support.v4.media.session.PlaybackStateCompat getPlaybackState();
+ method public java.util.List<android.support.v4.media.session.MediaSessionCompat.QueueItem> getQueue();
+ method public java.lang.CharSequence getQueueTitle();
+ method public int getRatingType();
+ method public int getRepeatMode();
+ method public android.app.PendingIntent getSessionActivity();
+ method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
+ method public android.support.v4.media.session.MediaControllerCompat.TransportControls getTransportControls();
+ method public boolean isShuffleModeEnabled();
+ method public void registerCallback(android.support.v4.media.session.MediaControllerCompat.Callback);
+ method public void registerCallback(android.support.v4.media.session.MediaControllerCompat.Callback, android.os.Handler);
+ method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
+ method public static void setMediaController(android.app.Activity, android.support.v4.media.session.MediaControllerCompat);
+ method public void setVolumeTo(int, int);
+ method public void unregisterCallback(android.support.v4.media.session.MediaControllerCompat.Callback);
+ }
+
+ public static abstract class MediaControllerCompat.Callback implements android.os.IBinder.DeathRecipient {
+ ctor public MediaControllerCompat.Callback();
+ method public void binderDied();
+ method public void onAudioInfoChanged(android.support.v4.media.session.MediaControllerCompat.PlaybackInfo);
+ method public void onExtrasChanged(android.os.Bundle);
+ method public void onMetadataChanged(android.support.v4.media.MediaMetadataCompat);
+ method public void onPlaybackStateChanged(android.support.v4.media.session.PlaybackStateCompat);
+ method public void onQueueChanged(java.util.List<android.support.v4.media.session.MediaSessionCompat.QueueItem>);
+ method public void onQueueTitleChanged(java.lang.CharSequence);
+ method public void onRepeatModeChanged(int);
+ method public void onSessionDestroyed();
+ method public void onSessionEvent(java.lang.String, android.os.Bundle);
+ method public void onShuffleModeChanged(boolean);
+ }
+
+ public static final class MediaControllerCompat.PlaybackInfo {
+ method public int getAudioStream();
+ method public int getCurrentVolume();
+ method public int getMaxVolume();
+ method public int getPlaybackType();
+ method public int getVolumeControl();
+ field public static final int PLAYBACK_TYPE_LOCAL = 1; // 0x1
+ field public static final int PLAYBACK_TYPE_REMOTE = 2; // 0x2
+ }
+
+ public static abstract class MediaControllerCompat.TransportControls {
+ method public abstract void fastForward();
+ method public abstract void pause();
+ method public abstract void play();
+ method public abstract void playFromMediaId(java.lang.String, android.os.Bundle);
+ method public abstract void playFromSearch(java.lang.String, android.os.Bundle);
+ method public abstract void playFromUri(android.net.Uri, android.os.Bundle);
+ method public abstract void prepare();
+ method public abstract void prepareFromMediaId(java.lang.String, android.os.Bundle);
+ method public abstract void prepareFromSearch(java.lang.String, android.os.Bundle);
+ method public abstract void prepareFromUri(android.net.Uri, android.os.Bundle);
+ method public abstract void rewind();
+ method public abstract void seekTo(long);
+ method public abstract void sendCustomAction(android.support.v4.media.session.PlaybackStateCompat.CustomAction, android.os.Bundle);
+ method public abstract void sendCustomAction(java.lang.String, android.os.Bundle);
+ method public abstract void setRating(android.support.v4.media.RatingCompat);
+ method public abstract void setRepeatMode(int);
+ method public abstract void setShuffleModeEnabled(boolean);
+ method public abstract void skipToNext();
+ method public abstract void skipToPrevious();
+ method public abstract void skipToQueueItem(long);
+ method public abstract void stop();
+ }
+
+ public class MediaSessionCompat {
+ ctor public MediaSessionCompat(android.content.Context, java.lang.String);
+ ctor public MediaSessionCompat(android.content.Context, java.lang.String, android.content.ComponentName, android.app.PendingIntent);
+ method public void addOnActiveChangeListener(android.support.v4.media.session.MediaSessionCompat.OnActiveChangeListener);
+ method public static android.support.v4.media.session.MediaSessionCompat fromMediaSession(android.content.Context, java.lang.Object);
+ method public android.support.v4.media.session.MediaControllerCompat getController();
+ method public java.lang.Object getMediaSession();
+ method public java.lang.Object getRemoteControlClient();
+ method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
+ method public boolean isActive();
+ method public static deprecated android.support.v4.media.session.MediaSessionCompat obtain(android.content.Context, java.lang.Object);
+ method public void release();
+ method public void removeOnActiveChangeListener(android.support.v4.media.session.MediaSessionCompat.OnActiveChangeListener);
+ method public void sendSessionEvent(java.lang.String, android.os.Bundle);
+ method public void setActive(boolean);
+ method public void setCallback(android.support.v4.media.session.MediaSessionCompat.Callback);
+ method public void setCallback(android.support.v4.media.session.MediaSessionCompat.Callback, android.os.Handler);
+ method public void setExtras(android.os.Bundle);
+ method public void setFlags(int);
+ method public void setMediaButtonReceiver(android.app.PendingIntent);
+ method public void setMetadata(android.support.v4.media.MediaMetadataCompat);
+ method public void setPlaybackState(android.support.v4.media.session.PlaybackStateCompat);
+ method public void setPlaybackToLocal(int);
+ method public void setPlaybackToRemote(android.support.v4.media.VolumeProviderCompat);
+ method public void setQueue(java.util.List<android.support.v4.media.session.MediaSessionCompat.QueueItem>);
+ method public void setQueueTitle(java.lang.CharSequence);
+ method public void setRatingType(int);
+ method public void setRepeatMode(int);
+ method public void setSessionActivity(android.app.PendingIntent);
+ method public void setShuffleModeEnabled(boolean);
+ field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
+ field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
+ }
+
+ public static abstract class MediaSessionCompat.Callback {
+ ctor public MediaSessionCompat.Callback();
+ method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
+ method public void onCustomAction(java.lang.String, android.os.Bundle);
+ method public void onFastForward();
+ method public boolean onMediaButtonEvent(android.content.Intent);
+ method public void onPause();
+ method public void onPlay();
+ method public void onPlayFromMediaId(java.lang.String, android.os.Bundle);
+ method public void onPlayFromSearch(java.lang.String, android.os.Bundle);
+ method public void onPlayFromUri(android.net.Uri, android.os.Bundle);
+ method public void onPrepare();
+ method public void onPrepareFromMediaId(java.lang.String, android.os.Bundle);
+ method public void onPrepareFromSearch(java.lang.String, android.os.Bundle);
+ method public void onPrepareFromUri(android.net.Uri, android.os.Bundle);
+ method public void onRewind();
+ method public void onSeekTo(long);
+ method public void onSetRating(android.support.v4.media.RatingCompat);
+ method public void onSetRepeatMode(int);
+ method public void onSetShuffleModeEnabled(boolean);
+ method public void onSkipToNext();
+ method public void onSkipToPrevious();
+ method public void onSkipToQueueItem(long);
+ method public void onStop();
+ }
+
+ public static abstract interface MediaSessionCompat.OnActiveChangeListener {
+ method public abstract void onActiveChanged();
+ }
+
+ public static final class MediaSessionCompat.QueueItem implements android.os.Parcelable {
+ ctor public MediaSessionCompat.QueueItem(android.support.v4.media.MediaDescriptionCompat, long);
+ method public int describeContents();
+ method public static android.support.v4.media.session.MediaSessionCompat.QueueItem fromQueueItem(java.lang.Object);
+ method public static java.util.List<android.support.v4.media.session.MediaSessionCompat.QueueItem> fromQueueItemList(java.util.List<?>);
+ method public android.support.v4.media.MediaDescriptionCompat getDescription();
+ method public long getQueueId();
+ method public java.lang.Object getQueueItem();
+ method public static deprecated android.support.v4.media.session.MediaSessionCompat.QueueItem obtain(java.lang.Object);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.session.MediaSessionCompat.QueueItem> CREATOR;
+ field public static final int UNKNOWN_ID = -1; // 0xffffffff
+ }
+
+ public static final class MediaSessionCompat.Token implements android.os.Parcelable {
+ method public int describeContents();
+ method public static android.support.v4.media.session.MediaSessionCompat.Token fromToken(java.lang.Object);
+ method public java.lang.Object getToken();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.session.MediaSessionCompat.Token> CREATOR;
+ }
+
+ public class ParcelableVolumeInfo implements android.os.Parcelable {
+ ctor public ParcelableVolumeInfo(int, int, int, int, int);
+ ctor public ParcelableVolumeInfo(android.os.Parcel);
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.session.ParcelableVolumeInfo> CREATOR;
+ field public int audioStream;
+ field public int controlType;
+ field public int currentVolume;
+ field public int maxVolume;
+ field public int volumeType;
+ }
+
+ public final class PlaybackStateCompat implements android.os.Parcelable {
+ method public int describeContents();
+ method public static android.support.v4.media.session.PlaybackStateCompat fromPlaybackState(java.lang.Object);
+ method public long getActions();
+ method public long getActiveQueueItemId();
+ method public long getBufferedPosition();
+ method public java.util.List<android.support.v4.media.session.PlaybackStateCompat.CustomAction> getCustomActions();
+ method public int getErrorCode();
+ method public java.lang.CharSequence getErrorMessage();
+ method public android.os.Bundle getExtras();
+ method public long getLastPositionUpdateTime();
+ method public float getPlaybackSpeed();
+ method public java.lang.Object getPlaybackState();
+ method public long getPosition();
+ method public int getState();
+ method public static int toKeyCode(long);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final long ACTION_FAST_FORWARD = 64L; // 0x40L
+ field public static final long ACTION_PAUSE = 2L; // 0x2L
+ field public static final long ACTION_PLAY = 4L; // 0x4L
+ field public static final long ACTION_PLAY_FROM_MEDIA_ID = 1024L; // 0x400L
+ field public static final long ACTION_PLAY_FROM_SEARCH = 2048L; // 0x800L
+ field public static final long ACTION_PLAY_FROM_URI = 8192L; // 0x2000L
+ field public static final long ACTION_PLAY_PAUSE = 512L; // 0x200L
+ field public static final long ACTION_PREPARE = 16384L; // 0x4000L
+ field public static final long ACTION_PREPARE_FROM_MEDIA_ID = 32768L; // 0x8000L
+ field public static final long ACTION_PREPARE_FROM_SEARCH = 65536L; // 0x10000L
+ field public static final long ACTION_PREPARE_FROM_URI = 131072L; // 0x20000L
+ field public static final long ACTION_REWIND = 8L; // 0x8L
+ field public static final long ACTION_SEEK_TO = 256L; // 0x100L
+ field public static final long ACTION_SET_RATING = 128L; // 0x80L
+ field public static final long ACTION_SET_REPEAT_MODE = 262144L; // 0x40000L
+ field public static final long ACTION_SET_SHUFFLE_MODE_ENABLED = 524288L; // 0x80000L
+ field public static final long ACTION_SKIP_TO_NEXT = 32L; // 0x20L
+ field public static final long ACTION_SKIP_TO_PREVIOUS = 16L; // 0x10L
+ field public static final long ACTION_SKIP_TO_QUEUE_ITEM = 4096L; // 0x1000L
+ field public static final long ACTION_STOP = 1L; // 0x1L
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.session.PlaybackStateCompat> CREATOR;
+ field public static final int ERROR_CODE_ACTION_ABORTED = 10; // 0xa
+ field public static final int ERROR_CODE_APP_ERROR = 1; // 0x1
+ field public static final int ERROR_CODE_AUTHENTICATION_EXPIRED = 3; // 0x3
+ field public static final int ERROR_CODE_CONCURRENT_STREAM_LIMIT = 5; // 0x5
+ field public static final int ERROR_CODE_CONTENT_ALREADY_PLAYING = 8; // 0x8
+ field public static final int ERROR_CODE_END_OF_QUEUE = 11; // 0xb
+ field public static final int ERROR_CODE_NOT_AVAILABLE_IN_REGION = 7; // 0x7
+ field public static final int ERROR_CODE_NOT_SUPPORTED = 2; // 0x2
+ field public static final int ERROR_CODE_PARENTAL_CONTROL_RESTRICTED = 6; // 0x6
+ field public static final int ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED = 4; // 0x4
+ field public static final int ERROR_CODE_SKIP_LIMIT_REACHED = 9; // 0x9
+ field public static final int ERROR_CODE_UNKNOWN_ERROR = 0; // 0x0
+ field public static final long PLAYBACK_POSITION_UNKNOWN = -1L; // 0xffffffffffffffffL
+ field public static final int REPEAT_MODE_ALL = 2; // 0x2
+ field public static final int REPEAT_MODE_NONE = 0; // 0x0
+ field public static final int REPEAT_MODE_ONE = 1; // 0x1
+ field public static final int STATE_BUFFERING = 6; // 0x6
+ field public static final int STATE_CONNECTING = 8; // 0x8
+ field public static final int STATE_ERROR = 7; // 0x7
+ field public static final int STATE_FAST_FORWARDING = 4; // 0x4
+ field public static final int STATE_NONE = 0; // 0x0
+ field public static final int STATE_PAUSED = 2; // 0x2
+ field public static final int STATE_PLAYING = 3; // 0x3
+ field public static final int STATE_REWINDING = 5; // 0x5
+ field public static final int STATE_SKIPPING_TO_NEXT = 10; // 0xa
+ field public static final int STATE_SKIPPING_TO_PREVIOUS = 9; // 0x9
+ field public static final int STATE_SKIPPING_TO_QUEUE_ITEM = 11; // 0xb
+ field public static final int STATE_STOPPED = 1; // 0x1
+ }
+
+ public static final class PlaybackStateCompat.Builder {
+ ctor public PlaybackStateCompat.Builder();
+ ctor public PlaybackStateCompat.Builder(android.support.v4.media.session.PlaybackStateCompat);
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder addCustomAction(java.lang.String, java.lang.String, int);
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder addCustomAction(android.support.v4.media.session.PlaybackStateCompat.CustomAction);
+ method public android.support.v4.media.session.PlaybackStateCompat build();
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder setActions(long);
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder setActiveQueueItemId(long);
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder setBufferedPosition(long);
+ method public deprecated android.support.v4.media.session.PlaybackStateCompat.Builder setErrorMessage(java.lang.CharSequence);
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder setErrorMessage(int, java.lang.CharSequence);
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder setExtras(android.os.Bundle);
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder setState(int, long, float);
+ method public android.support.v4.media.session.PlaybackStateCompat.Builder setState(int, long, float, long);
+ }
+
+ public static final class PlaybackStateCompat.CustomAction implements android.os.Parcelable {
+ method public int describeContents();
+ method public static android.support.v4.media.session.PlaybackStateCompat.CustomAction fromCustomAction(java.lang.Object);
+ method public java.lang.String getAction();
+ method public java.lang.Object getCustomAction();
+ method public android.os.Bundle getExtras();
+ method public int getIcon();
+ method public java.lang.CharSequence getName();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.media.session.PlaybackStateCompat.CustomAction> CREATOR;
+ }
+
+ public static final class PlaybackStateCompat.CustomAction.Builder {
+ ctor public PlaybackStateCompat.CustomAction.Builder(java.lang.String, java.lang.CharSequence, int);
+ method public android.support.v4.media.session.PlaybackStateCompat.CustomAction build();
+ method public android.support.v4.media.session.PlaybackStateCompat.CustomAction.Builder setExtras(android.os.Bundle);
+ }
+
+}
+
+package android.support.v4.net {
+
+ public final class ConnectivityManagerCompat {
+ method public static android.net.NetworkInfo getNetworkInfoFromBroadcast(android.net.ConnectivityManager, android.content.Intent);
+ method public static int getRestrictBackgroundStatus(android.net.ConnectivityManager);
+ method public static boolean isActiveNetworkMetered(android.net.ConnectivityManager);
+ field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
+ field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
+ field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
+ }
+
+ public final class TrafficStatsCompat {
+ method public static deprecated void clearThreadStatsTag();
+ method public static deprecated int getThreadStatsTag();
+ method public static deprecated void incrementOperationCount(int);
+ method public static deprecated void incrementOperationCount(int, int);
+ method public static deprecated void setThreadStatsTag(int);
+ method public static void tagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
+ method public static deprecated void tagSocket(java.net.Socket) throws java.net.SocketException;
+ method public static void untagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
+ method public static deprecated void untagSocket(java.net.Socket) throws java.net.SocketException;
+ }
+
+}
+
+package android.support.v4.os {
+
+ public final deprecated class AsyncTaskCompat {
+ method public static deprecated <Params, Progress, Result> android.os.AsyncTask<Params, Progress, Result> executeParallel(android.os.AsyncTask<Params, Progress, Result>, Params...);
+ }
+
+ public class BuildCompat {
+ method public static boolean isAtLeastN();
+ method public static boolean isAtLeastNMR1();
+ method public static boolean isAtLeastO();
+ }
+
+ public final class CancellationSignal {
+ ctor public CancellationSignal();
+ method public void cancel();
+ method public java.lang.Object getCancellationSignalObject();
+ method public boolean isCanceled();
+ method public void setOnCancelListener(android.support.v4.os.CancellationSignal.OnCancelListener);
+ method public void throwIfCanceled();
+ }
+
+ public static abstract interface CancellationSignal.OnCancelListener {
+ method public abstract void onCancel();
+ }
+
+ public final class EnvironmentCompat {
+ method public static java.lang.String getStorageState(java.io.File);
+ field public static final java.lang.String MEDIA_UNKNOWN = "unknown";
+ }
+
+ public class OperationCanceledException extends java.lang.RuntimeException {
+ ctor public OperationCanceledException();
+ ctor public OperationCanceledException(java.lang.String);
+ }
+
+ public final class ParcelableCompat {
+ method public static <T> android.os.Parcelable.Creator<T> newCreator(android.support.v4.os.ParcelableCompatCreatorCallbacks<T>);
+ }
+
+ public abstract interface ParcelableCompatCreatorCallbacks<T> {
+ method public abstract T createFromParcel(android.os.Parcel, java.lang.ClassLoader);
+ method public abstract T[] newArray(int);
+ }
+
+ public final class TraceCompat {
+ method public static void beginSection(java.lang.String);
+ method public static void endSection();
+ }
+
+ public class UserManagerCompat {
+ method public static boolean isUserUnlocked(android.content.Context);
+ }
+
+}
+
+package android.support.v4.print {
+
+ public final class PrintHelper {
+ ctor public PrintHelper(android.content.Context);
+ method public int getColorMode();
+ method public int getOrientation();
+ method public int getScaleMode();
+ method public void printBitmap(java.lang.String, android.graphics.Bitmap);
+ method public void printBitmap(java.lang.String, android.graphics.Bitmap, android.support.v4.print.PrintHelper.OnPrintFinishCallback);
+ method public void printBitmap(java.lang.String, android.net.Uri) throws java.io.FileNotFoundException;
+ method public void printBitmap(java.lang.String, android.net.Uri, android.support.v4.print.PrintHelper.OnPrintFinishCallback) throws java.io.FileNotFoundException;
+ method public void setColorMode(int);
+ method public void setOrientation(int);
+ method public void setScaleMode(int);
+ method public static boolean systemSupportsPrint();
+ field public static final int COLOR_MODE_COLOR = 2; // 0x2
+ field public static final int COLOR_MODE_MONOCHROME = 1; // 0x1
+ field public static final int ORIENTATION_LANDSCAPE = 1; // 0x1
+ field public static final int ORIENTATION_PORTRAIT = 2; // 0x2
+ field public static final int SCALE_MODE_FILL = 2; // 0x2
+ field public static final int SCALE_MODE_FIT = 1; // 0x1
+ }
+
+ public static abstract interface PrintHelper.OnPrintFinishCallback {
+ method public abstract void onFinish();
+ }
+
+}
+
+package android.support.v4.provider {
+
+ public abstract class DocumentFile {
+ method public abstract boolean canRead();
+ method public abstract boolean canWrite();
+ method public abstract android.support.v4.provider.DocumentFile createDirectory(java.lang.String);
+ method public abstract android.support.v4.provider.DocumentFile createFile(java.lang.String, java.lang.String);
+ method public abstract boolean delete();
+ method public abstract boolean exists();
+ method public android.support.v4.provider.DocumentFile findFile(java.lang.String);
+ method public static android.support.v4.provider.DocumentFile fromFile(java.io.File);
+ method public static android.support.v4.provider.DocumentFile fromSingleUri(android.content.Context, android.net.Uri);
+ method public static android.support.v4.provider.DocumentFile fromTreeUri(android.content.Context, android.net.Uri);
+ method public abstract java.lang.String getName();
+ method public android.support.v4.provider.DocumentFile getParentFile();
+ method public abstract java.lang.String getType();
+ method public abstract android.net.Uri getUri();
+ method public abstract boolean isDirectory();
+ method public static boolean isDocumentUri(android.content.Context, android.net.Uri);
+ method public abstract boolean isFile();
+ method public abstract boolean isVirtual();
+ method public abstract long lastModified();
+ method public abstract long length();
+ method public abstract android.support.v4.provider.DocumentFile[] listFiles();
+ method public abstract boolean renameTo(java.lang.String);
+ }
+
+}
+
+package android.support.v4.text {
+
+ public final class BidiFormatter {
+ method public static android.support.v4.text.BidiFormatter getInstance();
+ method public static android.support.v4.text.BidiFormatter getInstance(boolean);
+ method public static android.support.v4.text.BidiFormatter getInstance(java.util.Locale);
+ method public boolean getStereoReset();
+ method public boolean isRtl(java.lang.String);
+ method public boolean isRtl(java.lang.CharSequence);
+ method public boolean isRtlContext();
+ method public java.lang.String unicodeWrap(java.lang.String, android.support.v4.text.TextDirectionHeuristicCompat, boolean);
+ method public java.lang.CharSequence unicodeWrap(java.lang.CharSequence, android.support.v4.text.TextDirectionHeuristicCompat, boolean);
+ method public java.lang.String unicodeWrap(java.lang.String, android.support.v4.text.TextDirectionHeuristicCompat);
+ method public java.lang.CharSequence unicodeWrap(java.lang.CharSequence, android.support.v4.text.TextDirectionHeuristicCompat);
+ method public java.lang.String unicodeWrap(java.lang.String, boolean);
+ method public java.lang.CharSequence unicodeWrap(java.lang.CharSequence, boolean);
+ method public java.lang.String unicodeWrap(java.lang.String);
+ method public java.lang.CharSequence unicodeWrap(java.lang.CharSequence);
+ }
+
+ public static final class BidiFormatter.Builder {
+ ctor public BidiFormatter.Builder();
+ ctor public BidiFormatter.Builder(boolean);
+ ctor public BidiFormatter.Builder(java.util.Locale);
+ method public android.support.v4.text.BidiFormatter build();
+ method public android.support.v4.text.BidiFormatter.Builder setTextDirectionHeuristic(android.support.v4.text.TextDirectionHeuristicCompat);
+ method public android.support.v4.text.BidiFormatter.Builder stereoReset(boolean);
+ }
+
+ public final class ICUCompat {
+ method public static java.lang.String maximizeAndGetScript(java.util.Locale);
+ }
+
+ public abstract interface TextDirectionHeuristicCompat {
+ method public abstract boolean isRtl(char[], int, int);
+ method public abstract boolean isRtl(java.lang.CharSequence, int, int);
+ }
+
+ public final class TextDirectionHeuristicsCompat {
+ field public static final android.support.v4.text.TextDirectionHeuristicCompat ANYRTL_LTR;
+ field public static final android.support.v4.text.TextDirectionHeuristicCompat FIRSTSTRONG_LTR;
+ field public static final android.support.v4.text.TextDirectionHeuristicCompat FIRSTSTRONG_RTL;
+ field public static final android.support.v4.text.TextDirectionHeuristicCompat LOCALE;
+ field public static final android.support.v4.text.TextDirectionHeuristicCompat LTR;
+ field public static final android.support.v4.text.TextDirectionHeuristicCompat RTL;
+ }
+
+ public final class TextUtilsCompat {
+ method public static int getLayoutDirectionFromLocale(java.util.Locale);
+ method public static java.lang.String htmlEncode(java.lang.String);
+ field public static final java.util.Locale ROOT;
+ }
+
+}
+
+package android.support.v4.text.util {
+
+ public final class LinkifyCompat {
+ method public static final boolean addLinks(android.text.Spannable, int);
+ method public static final boolean addLinks(android.widget.TextView, int);
+ method public static final void addLinks(android.widget.TextView, java.util.regex.Pattern, java.lang.String);
+ method public static final void addLinks(android.widget.TextView, java.util.regex.Pattern, java.lang.String, android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter);
+ method public static final void addLinks(android.widget.TextView, java.util.regex.Pattern, java.lang.String, java.lang.String[], android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter);
+ method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String);
+ method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String, android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter);
+ method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String, java.lang.String[], android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter);
+ }
+
+ public static abstract class LinkifyCompat.LinkifyMask implements java.lang.annotation.Annotation {
+ }
+
+}
+
+package android.support.v4.util {
+
+ public class ArrayMap<K, V> extends android.support.v4.util.SimpleArrayMap implements java.util.Map {
+ ctor public ArrayMap();
+ ctor public ArrayMap(int);
+ ctor public ArrayMap(android.support.v4.util.SimpleArrayMap);
+ method public boolean containsAll(java.util.Collection<?>);
+ method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+ method public java.util.Set<K> keySet();
+ method public void putAll(java.util.Map<? extends K, ? extends V>);
+ method public boolean removeAll(java.util.Collection<?>);
+ method public boolean retainAll(java.util.Collection<?>);
+ method public java.util.Collection<V> values();
+ }
+
+ public final class ArraySet<E> implements java.util.Collection java.util.Set {
+ ctor public ArraySet();
+ ctor public ArraySet(int);
+ ctor public ArraySet(android.support.v4.util.ArraySet<E>);
+ method public boolean add(E);
+ method public void addAll(android.support.v4.util.ArraySet<? extends E>);
+ method public boolean addAll(java.util.Collection<? extends E>);
+ method public void clear();
+ method public boolean contains(java.lang.Object);
+ method public boolean containsAll(java.util.Collection<?>);
+ method public void ensureCapacity(int);
+ method public int indexOf(java.lang.Object);
+ method public boolean isEmpty();
+ method public java.util.Iterator<E> iterator();
+ method public boolean remove(java.lang.Object);
+ method public boolean removeAll(android.support.v4.util.ArraySet<? extends E>);
+ method public boolean removeAll(java.util.Collection<?>);
+ method public E removeAt(int);
+ method public boolean retainAll(java.util.Collection<?>);
+ method public int size();
+ method public java.lang.Object[] toArray();
+ method public <T> T[] toArray(T[]);
+ method public E valueAt(int);
+ }
+
+ public class AtomicFile {
+ ctor public AtomicFile(java.io.File);
+ method public void delete();
+ method public void failWrite(java.io.FileOutputStream);
+ method public void finishWrite(java.io.FileOutputStream);
+ method public java.io.File getBaseFile();
+ method public java.io.FileInputStream openRead() throws java.io.FileNotFoundException;
+ method public byte[] readFully() throws java.io.IOException;
+ method public java.io.FileOutputStream startWrite() throws java.io.IOException;
+ }
+
+ public final class CircularArray<E> {
+ ctor public CircularArray();
+ ctor public CircularArray(int);
+ method public void addFirst(E);
+ method public void addLast(E);
+ method public void clear();
+ method public E get(int);
+ method public E getFirst();
+ method public E getLast();
+ method public boolean isEmpty();
+ method public E popFirst();
+ method public E popLast();
+ method public void removeFromEnd(int);
+ method public void removeFromStart(int);
+ method public int size();
+ }
+
+ public final class CircularIntArray {
+ ctor public CircularIntArray();
+ ctor public CircularIntArray(int);
+ method public void addFirst(int);
+ method public void addLast(int);
+ method public void clear();
+ method public int get(int);
+ method public int getFirst();
+ method public int getLast();
+ method public boolean isEmpty();
+ method public int popFirst();
+ method public int popLast();
+ method public void removeFromEnd(int);
+ method public void removeFromStart(int);
+ method public int size();
+ }
+
+ public class LongSparseArray<E> {
+ ctor public LongSparseArray();
+ ctor public LongSparseArray(int);
+ method public void append(long, E);
+ method public void clear();
+ method public android.support.v4.util.LongSparseArray<E> clone();
+ method public void delete(long);
+ method public E get(long);
+ method public E get(long, E);
+ method public int indexOfKey(long);
+ method public int indexOfValue(E);
+ method public long keyAt(int);
+ method public void put(long, E);
+ method public void remove(long);
+ method public void removeAt(int);
+ method public void setValueAt(int, E);
+ method public int size();
+ method public E valueAt(int);
+ }
+
+ public class LruCache<K, V> {
+ ctor public LruCache(int);
+ method protected V create(K);
+ method public final synchronized int createCount();
+ method protected void entryRemoved(boolean, K, V, V);
+ method public final void evictAll();
+ method public final synchronized int evictionCount();
+ method public final V get(K);
+ method public final synchronized int hitCount();
+ method public final synchronized int maxSize();
+ method public final synchronized int missCount();
+ method public final V put(K, V);
+ method public final synchronized int putCount();
+ method public final V remove(K);
+ method public void resize(int);
+ method public final synchronized int size();
+ method protected int sizeOf(K, V);
+ method public final synchronized java.util.Map<K, V> snapshot();
+ method public final synchronized java.lang.String toString();
+ method public void trimToSize(int);
+ }
+
+ public class Pair<F, S> {
+ ctor public Pair(F, S);
+ method public static <A, B> android.support.v4.util.Pair<A, B> create(A, B);
+ field public final F first;
+ field public final S second;
+ }
+
+ public final class PatternsCompat {
+ field public static final java.util.regex.Pattern DOMAIN_NAME;
+ field public static final java.util.regex.Pattern EMAIL_ADDRESS;
+ field public static final java.util.regex.Pattern IP_ADDRESS;
+ field public static final java.util.regex.Pattern WEB_URL;
+ }
+
+ public final class Pools {
+ }
+
+ public static abstract interface Pools.Pool<T> {
+ method public abstract T acquire();
+ method public abstract boolean release(T);
+ }
+
+ public static class Pools.SimplePool<T> implements android.support.v4.util.Pools.Pool {
+ ctor public Pools.SimplePool(int);
+ method public T acquire();
+ method public boolean release(T);
+ }
+
+ public static class Pools.SynchronizedPool<T> extends android.support.v4.util.Pools.SimplePool {
+ ctor public Pools.SynchronizedPool(int);
+ }
+
+ public class SimpleArrayMap<K, V> {
+ ctor public SimpleArrayMap();
+ ctor public SimpleArrayMap(int);
+ ctor public SimpleArrayMap(android.support.v4.util.SimpleArrayMap);
+ method public void clear();
+ method public boolean containsKey(java.lang.Object);
+ method public boolean containsValue(java.lang.Object);
+ method public void ensureCapacity(int);
+ method public V get(java.lang.Object);
+ method public int indexOfKey(java.lang.Object);
+ method public boolean isEmpty();
+ method public K keyAt(int);
+ method public V put(K, V);
+ method public void putAll(android.support.v4.util.SimpleArrayMap<? extends K, ? extends V>);
+ method public V remove(java.lang.Object);
+ method public V removeAt(int);
+ method public V setValueAt(int, V);
+ method public int size();
+ method public V valueAt(int);
+ }
+
+ public class SparseArrayCompat<E> {
+ ctor public SparseArrayCompat();
+ ctor public SparseArrayCompat(int);
+ method public void append(int, E);
+ method public void clear();
+ method public android.support.v4.util.SparseArrayCompat<E> clone();
+ method public void delete(int);
+ method public E get(int);
+ method public E get(int, E);
+ method public int indexOfKey(int);
+ method public int indexOfValue(E);
+ method public int keyAt(int);
+ method public void put(int, E);
+ method public void remove(int);
+ method public void removeAt(int);
+ method public void removeAtRange(int, int);
+ method public void setValueAt(int, E);
+ method public int size();
+ method public E valueAt(int);
+ }
+
+}
+
+package android.support.v4.view {
+
+ public abstract class AbsSavedState implements android.os.Parcelable {
+ ctor protected AbsSavedState(android.os.Parcelable);
+ ctor protected AbsSavedState(android.os.Parcel);
+ ctor protected AbsSavedState(android.os.Parcel, java.lang.ClassLoader);
+ method public int describeContents();
+ method public final android.os.Parcelable getSuperState();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.support.v4.view.AbsSavedState> CREATOR;
+ field public static final android.support.v4.view.AbsSavedState EMPTY_STATE;
+ }
+
+ public class AccessibilityDelegateCompat {
+ ctor public AccessibilityDelegateCompat();
+ method public boolean dispatchPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+ method public android.support.v4.view.accessibility.AccessibilityNodeProviderCompat getAccessibilityNodeProvider(android.view.View);
+ method public void onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+ method public void onInitializeAccessibilityNodeInfo(android.view.View, android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+ method public void onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+ method public boolean onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent);
+ method public boolean performAccessibilityAction(android.view.View, int, android.os.Bundle);
+ method public void sendAccessibilityEvent(android.view.View, int);
+ method public void sendAccessibilityEventUnchecked(android.view.View, android.view.accessibility.AccessibilityEvent);
+ }
+
+ public abstract class ActionProvider {
+ ctor public ActionProvider(android.content.Context);
+ method public android.content.Context getContext();
+ method public boolean hasSubMenu();
+ method public boolean isVisible();
+ method public abstract android.view.View onCreateActionView();
+ method public android.view.View onCreateActionView(android.view.MenuItem);
+ method public boolean onPerformDefaultAction();
+ method public void onPrepareSubMenu(android.view.SubMenu);
+ method public boolean overridesItemVisibility();
+ method public void refreshVisibility();
+ method public void setVisibilityListener(android.support.v4.view.ActionProvider.VisibilityListener);
+ }
+
+ public static abstract interface ActionProvider.VisibilityListener {
+ method public abstract void onActionProviderVisibilityChanged(boolean);
+ }
+
+ public final class AsyncLayoutInflater {
+ ctor public AsyncLayoutInflater(android.content.Context);
+ method public void inflate(int, android.view.ViewGroup, android.support.v4.view.AsyncLayoutInflater.OnInflateFinishedListener);
+ }
+
+ public static abstract interface AsyncLayoutInflater.OnInflateFinishedListener {
+ method public abstract void onInflateFinished(android.view.View, int, android.view.ViewGroup);
+ }
+
+ public final class GestureDetectorCompat {
+ ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener);
+ ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler);
+ method public boolean isLongpressEnabled();
+ method public boolean onTouchEvent(android.view.MotionEvent);
+ method public void setIsLongpressEnabled(boolean);
+ method public void setOnDoubleTapListener(android.view.GestureDetector.OnDoubleTapListener);
+ }
+
+ public final class GravityCompat {
+ method public static void apply(int, int, int, android.graphics.Rect, android.graphics.Rect, int);
+ method public static void apply(int, int, int, android.graphics.Rect, int, int, android.graphics.Rect, int);
+ method public static void applyDisplay(int, android.graphics.Rect, android.graphics.Rect, int);
+ method public static int getAbsoluteGravity(int, int);
+ field public static final int END = 8388613; // 0x800005
+ field public static final int RELATIVE_HORIZONTAL_GRAVITY_MASK = 8388615; // 0x800007
+ field public static final int RELATIVE_LAYOUT_DIRECTION = 8388608; // 0x800000
+ field public static final int START = 8388611; // 0x800003
+ }
+
+ public final class InputDeviceCompat {
+ field public static final int SOURCE_ANY = -256; // 0xffffff00
+ field public static final int SOURCE_CLASS_BUTTON = 1; // 0x1
+ field public static final int SOURCE_CLASS_JOYSTICK = 16; // 0x10
+ field public static final int SOURCE_CLASS_MASK = 255; // 0xff
+ field public static final int SOURCE_CLASS_NONE = 0; // 0x0
+ field public static final int SOURCE_CLASS_POINTER = 2; // 0x2
+ field public static final int SOURCE_CLASS_POSITION = 8; // 0x8
+ field public static final int SOURCE_CLASS_TRACKBALL = 4; // 0x4
+ field public static final int SOURCE_DPAD = 513; // 0x201
+ field public static final int SOURCE_GAMEPAD = 1025; // 0x401
+ field public static final int SOURCE_HDMI = 33554433; // 0x2000001
+ field public static final int SOURCE_JOYSTICK = 16777232; // 0x1000010
+ field public static final int SOURCE_KEYBOARD = 257; // 0x101
+ field public static final int SOURCE_MOUSE = 8194; // 0x2002
+ field public static final int SOURCE_STYLUS = 16386; // 0x4002
+ field public static final int SOURCE_TOUCHPAD = 1048584; // 0x100008
+ field public static final int SOURCE_TOUCHSCREEN = 4098; // 0x1002
+ field public static final int SOURCE_TOUCH_NAVIGATION = 2097152; // 0x200000
+ field public static final int SOURCE_TRACKBALL = 65540; // 0x10004
+ field public static final int SOURCE_UNKNOWN = 0; // 0x0
+ }
+
+ public final deprecated class KeyEventCompat {
+ method public static deprecated boolean dispatch(android.view.KeyEvent, android.view.KeyEvent.Callback, java.lang.Object, java.lang.Object);
+ method public static deprecated java.lang.Object getKeyDispatcherState(android.view.View);
+ method public static deprecated boolean hasModifiers(android.view.KeyEvent, int);
+ method public static deprecated boolean hasNoModifiers(android.view.KeyEvent);
+ method public static deprecated boolean isCtrlPressed(android.view.KeyEvent);
+ method public static deprecated boolean isTracking(android.view.KeyEvent);
+ method public static deprecated boolean metaStateHasModifiers(int, int);
+ method public static deprecated boolean metaStateHasNoModifiers(int);
+ method public static deprecated int normalizeMetaState(int);
+ method public static deprecated void startTracking(android.view.KeyEvent);
+ }
+
+ public final class LayoutInflaterCompat {
+ method public static deprecated android.support.v4.view.LayoutInflaterFactory getFactory(android.view.LayoutInflater);
+ method public static deprecated void setFactory(android.view.LayoutInflater, android.support.v4.view.LayoutInflaterFactory);
+ method public static void setFactory2(android.view.LayoutInflater, android.view.LayoutInflater.Factory2);
+ }
+
+ public abstract deprecated interface LayoutInflaterFactory {
+ method public abstract android.view.View onCreateView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet);
+ }
+
+ public final class MarginLayoutParamsCompat {
+ method public static int getLayoutDirection(android.view.ViewGroup.MarginLayoutParams);
+ method public static int getMarginEnd(android.view.ViewGroup.MarginLayoutParams);
+ method public static int getMarginStart(android.view.ViewGroup.MarginLayoutParams);
+ method public static boolean isMarginRelative(android.view.ViewGroup.MarginLayoutParams);
+ method public static void resolveLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
+ method public static void setLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
+ method public static void setMarginEnd(android.view.ViewGroup.MarginLayoutParams, int);
+ method public static void setMarginStart(android.view.ViewGroup.MarginLayoutParams, int);
+ }
+
+ public final class MenuCompat {
+ method public static deprecated void setShowAsAction(android.view.MenuItem, int);
+ }
+
+ public final class MenuItemCompat {
+ method public static boolean collapseActionView(android.view.MenuItem);
+ method public static boolean expandActionView(android.view.MenuItem);
+ method public static android.support.v4.view.ActionProvider getActionProvider(android.view.MenuItem);
+ method public static android.view.View getActionView(android.view.MenuItem);
+ method public static java.lang.CharSequence getContentDescription(android.view.MenuItem);
+ method public static java.lang.CharSequence getTooltipText(android.view.MenuItem);
+ method public static boolean isActionViewExpanded(android.view.MenuItem);
+ method public static android.view.MenuItem setActionProvider(android.view.MenuItem, android.support.v4.view.ActionProvider);
+ method public static android.view.MenuItem setActionView(android.view.MenuItem, android.view.View);
+ method public static android.view.MenuItem setActionView(android.view.MenuItem, int);
+ method public static void setContentDescription(android.view.MenuItem, java.lang.CharSequence);
+ method public static android.view.MenuItem setOnActionExpandListener(android.view.MenuItem, android.support.v4.view.MenuItemCompat.OnActionExpandListener);
+ method public static void setShowAsAction(android.view.MenuItem, int);
+ method public static void setTooltipText(android.view.MenuItem, java.lang.CharSequence);
+ field public static final int SHOW_AS_ACTION_ALWAYS = 2; // 0x2
+ field public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8; // 0x8
+ field public static final int SHOW_AS_ACTION_IF_ROOM = 1; // 0x1
+ field public static final int SHOW_AS_ACTION_NEVER = 0; // 0x0
+ field public static final int SHOW_AS_ACTION_WITH_TEXT = 4; // 0x4
+ }
+
+ public static abstract interface MenuItemCompat.OnActionExpandListener {
+ method public abstract boolean onMenuItemActionCollapse(android.view.MenuItem);
+ method public abstract boolean onMenuItemActionExpand(android.view.MenuItem);
+ }
+
+ public final class MotionEventCompat {
+ method public static deprecated int findPointerIndex(android.view.MotionEvent, int);
+ method public static deprecated int getActionIndex(android.view.MotionEvent);
+ method public static deprecated int getActionMasked(android.view.MotionEvent);
+ method public static deprecated float getAxisValue(android.view.MotionEvent, int);
+ method public static deprecated float getAxisValue(android.view.MotionEvent, int, int);
+ method public static deprecated int getButtonState(android.view.MotionEvent);
+ method public static deprecated int getPointerCount(android.view.MotionEvent);
+ method public static deprecated int getPointerId(android.view.MotionEvent, int);
+ method public static deprecated int getSource(android.view.MotionEvent);
+ method public static deprecated float getX(android.view.MotionEvent, int);
+ method public static deprecated float getY(android.view.MotionEvent, int);
+ method public static boolean isFromSource(android.view.MotionEvent, int);
+ field public static final deprecated int ACTION_HOVER_ENTER = 9; // 0x9
+ field public static final deprecated int ACTION_HOVER_EXIT = 10; // 0xa
+ field public static final deprecated int ACTION_HOVER_MOVE = 7; // 0x7
+ field public static final deprecated int ACTION_MASK = 255; // 0xff
+ field public static final deprecated int ACTION_POINTER_DOWN = 5; // 0x5
+ field public static final deprecated int ACTION_POINTER_INDEX_MASK = 65280; // 0xff00
+ field public static final deprecated int ACTION_POINTER_INDEX_SHIFT = 8; // 0x8
+ field public static final deprecated int ACTION_POINTER_UP = 6; // 0x6
+ field public static final deprecated int ACTION_SCROLL = 8; // 0x8
+ field public static final deprecated int AXIS_BRAKE = 23; // 0x17
+ field public static final deprecated int AXIS_DISTANCE = 24; // 0x18
+ field public static final deprecated int AXIS_GAS = 22; // 0x16
+ field public static final deprecated int AXIS_GENERIC_1 = 32; // 0x20
+ field public static final deprecated int AXIS_GENERIC_10 = 41; // 0x29
+ field public static final deprecated int AXIS_GENERIC_11 = 42; // 0x2a
+ field public static final deprecated int AXIS_GENERIC_12 = 43; // 0x2b
+ field public static final deprecated int AXIS_GENERIC_13 = 44; // 0x2c
+ field public static final deprecated int AXIS_GENERIC_14 = 45; // 0x2d
+ field public static final deprecated int AXIS_GENERIC_15 = 46; // 0x2e
+ field public static final deprecated int AXIS_GENERIC_16 = 47; // 0x2f
+ field public static final deprecated int AXIS_GENERIC_2 = 33; // 0x21
+ field public static final deprecated int AXIS_GENERIC_3 = 34; // 0x22
+ field public static final deprecated int AXIS_GENERIC_4 = 35; // 0x23
+ field public static final deprecated int AXIS_GENERIC_5 = 36; // 0x24
+ field public static final deprecated int AXIS_GENERIC_6 = 37; // 0x25
+ field public static final deprecated int AXIS_GENERIC_7 = 38; // 0x26
+ field public static final deprecated int AXIS_GENERIC_8 = 39; // 0x27
+ field public static final deprecated int AXIS_GENERIC_9 = 40; // 0x28
+ field public static final deprecated int AXIS_HAT_X = 15; // 0xf
+ field public static final deprecated int AXIS_HAT_Y = 16; // 0x10
+ field public static final deprecated int AXIS_HSCROLL = 10; // 0xa
+ field public static final deprecated int AXIS_LTRIGGER = 17; // 0x11
+ field public static final deprecated int AXIS_ORIENTATION = 8; // 0x8
+ field public static final deprecated int AXIS_PRESSURE = 2; // 0x2
+ field public static final int AXIS_RELATIVE_X = 27; // 0x1b
+ field public static final int AXIS_RELATIVE_Y = 28; // 0x1c
+ field public static final deprecated int AXIS_RTRIGGER = 18; // 0x12
+ field public static final deprecated int AXIS_RUDDER = 20; // 0x14
+ field public static final deprecated int AXIS_RX = 12; // 0xc
+ field public static final deprecated int AXIS_RY = 13; // 0xd
+ field public static final deprecated int AXIS_RZ = 14; // 0xe
+ field public static final deprecated int AXIS_SIZE = 3; // 0x3
+ field public static final deprecated int AXIS_THROTTLE = 19; // 0x13
+ field public static final deprecated int AXIS_TILT = 25; // 0x19
+ field public static final deprecated int AXIS_TOOL_MAJOR = 6; // 0x6
+ field public static final deprecated int AXIS_TOOL_MINOR = 7; // 0x7
+ field public static final deprecated int AXIS_TOUCH_MAJOR = 4; // 0x4
+ field public static final deprecated int AXIS_TOUCH_MINOR = 5; // 0x5
+ field public static final deprecated int AXIS_VSCROLL = 9; // 0x9
+ field public static final deprecated int AXIS_WHEEL = 21; // 0x15
+ field public static final deprecated int AXIS_X = 0; // 0x0
+ field public static final deprecated int AXIS_Y = 1; // 0x1
+ field public static final deprecated int AXIS_Z = 11; // 0xb
+ field public static final deprecated int BUTTON_PRIMARY = 1; // 0x1
+ }
+
+ public abstract interface NestedScrollingChild {
+ method public abstract boolean dispatchNestedFling(float, float, boolean);
+ method public abstract boolean dispatchNestedPreFling(float, float);
+ method public abstract boolean dispatchNestedPreScroll(int, int, int[], int[]);
+ method public abstract boolean dispatchNestedScroll(int, int, int, int, int[]);
+ method public abstract boolean hasNestedScrollingParent();
+ method public abstract boolean isNestedScrollingEnabled();
+ method public abstract void setNestedScrollingEnabled(boolean);
+ method public abstract boolean startNestedScroll(int);
+ method public abstract void stopNestedScroll();
+ }
+
+ public class NestedScrollingChildHelper {
+ ctor public NestedScrollingChildHelper(android.view.View);
+ method public boolean dispatchNestedFling(float, float, boolean);
+ method public boolean dispatchNestedPreFling(float, float);
+ method public boolean dispatchNestedPreScroll(int, int, int[], int[]);
+ method public boolean dispatchNestedScroll(int, int, int, int, int[]);
+ method public boolean hasNestedScrollingParent();
+ method public boolean isNestedScrollingEnabled();
+ method public void onDetachedFromWindow();
+ method public void onStopNestedScroll(android.view.View);
+ method public void setNestedScrollingEnabled(boolean);
+ method public boolean startNestedScroll(int);
+ method public void stopNestedScroll();
+ }
+
+ public abstract interface NestedScrollingParent {
+ method public abstract int getNestedScrollAxes();
+ method public abstract boolean onNestedFling(android.view.View, float, float, boolean);
+ method public abstract boolean onNestedPreFling(android.view.View, float, float);
+ method public abstract void onNestedPreScroll(android.view.View, int, int, int[]);
+ method public abstract void onNestedScroll(android.view.View, int, int, int, int);
+ method public abstract void onNestedScrollAccepted(android.view.View, android.view.View, int);
+ method public abstract boolean onStartNestedScroll(android.view.View, android.view.View, int);
+ method public abstract void onStopNestedScroll(android.view.View);
+ }
+
+ public class NestedScrollingParentHelper {
+ ctor public NestedScrollingParentHelper(android.view.ViewGroup);
+ method public int getNestedScrollAxes();
+ method public void onNestedScrollAccepted(android.view.View, android.view.View, int);
+ method public void onStopNestedScroll(android.view.View);
+ }
+
+ public abstract interface OnApplyWindowInsetsListener {
+ method public abstract android.support.v4.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, android.support.v4.view.WindowInsetsCompat);
+ }
+
+ public abstract class PagerAdapter {
+ ctor public PagerAdapter();
+ method public void destroyItem(android.view.ViewGroup, int, java.lang.Object);
+ method public deprecated void destroyItem(android.view.View, int, java.lang.Object);
+ method public void finishUpdate(android.view.ViewGroup);
+ method public deprecated void finishUpdate(android.view.View);
+ method public abstract int getCount();
+ method public int getItemPosition(java.lang.Object);
+ method public java.lang.CharSequence getPageTitle(int);
+ method public float getPageWidth(int);
+ method public java.lang.Object instantiateItem(android.view.ViewGroup, int);
+ method public deprecated java.lang.Object instantiateItem(android.view.View, int);
+ method public abstract boolean isViewFromObject(android.view.View, java.lang.Object);
+ method public void notifyDataSetChanged();
+ method public void registerDataSetObserver(android.database.DataSetObserver);
+ method public void restoreState(android.os.Parcelable, java.lang.ClassLoader);
+ method public android.os.Parcelable saveState();
+ method public void setPrimaryItem(android.view.ViewGroup, int, java.lang.Object);
+ method public deprecated void setPrimaryItem(android.view.View, int, java.lang.Object);
+ method public void startUpdate(android.view.ViewGroup);
+ method public deprecated void startUpdate(android.view.View);
+ method public void unregisterDataSetObserver(android.database.DataSetObserver);
+ field public static final int POSITION_NONE = -2; // 0xfffffffe
+ field public static final int POSITION_UNCHANGED = -1; // 0xffffffff
+ }
+
+ public class PagerTabStrip extends android.support.v4.view.PagerTitleStrip {
+ ctor public PagerTabStrip(android.content.Context);
+ ctor public PagerTabStrip(android.content.Context, android.util.AttributeSet);
+ method public boolean getDrawFullUnderline();
+ method public int getTabIndicatorColor();
+ method public void setDrawFullUnderline(boolean);
+ method public void setTabIndicatorColor(int);
+ method public void setTabIndicatorColorResource(int);
+ }
+
+ public class PagerTitleStrip extends android.view.ViewGroup {
+ ctor public PagerTitleStrip(android.content.Context);
+ ctor public PagerTitleStrip(android.content.Context, android.util.AttributeSet);
+ method public int getTextSpacing();
+ method protected void onLayout(boolean, int, int, int, int);
+ method public void setGravity(int);
+ method public void setNonPrimaryAlpha(float);
+ method public void setTextColor(int);
+ method public void setTextSize(int, float);
+ method public void setTextSpacing(int);
+ }
+
+ public final class PointerIconCompat {
+ method public static android.support.v4.view.PointerIconCompat create(android.graphics.Bitmap, float, float);
+ method public static android.support.v4.view.PointerIconCompat getSystemIcon(android.content.Context, int);
+ method public static android.support.v4.view.PointerIconCompat load(android.content.res.Resources, int);
+ field public static final int TYPE_ALIAS = 1010; // 0x3f2
+ field public static final int TYPE_ALL_SCROLL = 1013; // 0x3f5
+ field public static final int TYPE_ARROW = 1000; // 0x3e8
+ field public static final int TYPE_CELL = 1006; // 0x3ee
+ field public static final int TYPE_CONTEXT_MENU = 1001; // 0x3e9
+ field public static final int TYPE_COPY = 1011; // 0x3f3
+ field public static final int TYPE_CROSSHAIR = 1007; // 0x3ef
+ field public static final int TYPE_DEFAULT = 1000; // 0x3e8
+ field public static final int TYPE_GRAB = 1020; // 0x3fc
+ field public static final int TYPE_GRABBING = 1021; // 0x3fd
+ field public static final int TYPE_HAND = 1002; // 0x3ea
+ field public static final int TYPE_HELP = 1003; // 0x3eb
+ field public static final int TYPE_HORIZONTAL_DOUBLE_ARROW = 1014; // 0x3f6
+ field public static final int TYPE_NO_DROP = 1012; // 0x3f4
+ field public static final int TYPE_NULL = 0; // 0x0
+ field public static final int TYPE_TEXT = 1008; // 0x3f0
+ field public static final int TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW = 1017; // 0x3f9
+ field public static final int TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW = 1016; // 0x3f8
+ field public static final int TYPE_VERTICAL_DOUBLE_ARROW = 1015; // 0x3f7
+ field public static final int TYPE_VERTICAL_TEXT = 1009; // 0x3f1
+ field public static final int TYPE_WAIT = 1004; // 0x3ec
+ field public static final int TYPE_ZOOM_IN = 1018; // 0x3fa
+ field public static final int TYPE_ZOOM_OUT = 1019; // 0x3fb
+ }
+
+ public final class ScaleGestureDetectorCompat {
+ method public static boolean isQuickScaleEnabled(java.lang.Object);
+ method public static void setQuickScaleEnabled(java.lang.Object, boolean);
+ }
+
+ public abstract interface ScrollingView {
+ method public abstract int computeHorizontalScrollExtent();
+ method public abstract int computeHorizontalScrollOffset();
+ method public abstract int computeHorizontalScrollRange();
+ method public abstract int computeVerticalScrollExtent();
+ method public abstract int computeVerticalScrollOffset();
+ method public abstract int computeVerticalScrollRange();
+ }
+
+ public abstract interface TintableBackgroundView {
+ method public abstract android.content.res.ColorStateList getSupportBackgroundTintList();
+ method public abstract android.graphics.PorterDuff.Mode getSupportBackgroundTintMode();
+ method public abstract void setSupportBackgroundTintList(android.content.res.ColorStateList);
+ method public abstract void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode);
+ }
+
+ public final deprecated class VelocityTrackerCompat {
+ method public static deprecated float getXVelocity(android.view.VelocityTracker, int);
+ method public static deprecated float getYVelocity(android.view.VelocityTracker, int);
+ }
+
+ public class ViewCompat {
+ ctor protected ViewCompat();
+ method public static android.support.v4.view.ViewPropertyAnimatorCompat animate(android.view.View);
+ method public static boolean canScrollHorizontally(android.view.View, int);
+ method public static boolean canScrollVertically(android.view.View, int);
+ method public static deprecated int combineMeasuredStates(int, int);
+ method public static android.support.v4.view.WindowInsetsCompat dispatchApplyWindowInsets(android.view.View, android.support.v4.view.WindowInsetsCompat);
+ method public static void dispatchFinishTemporaryDetach(android.view.View);
+ method public static boolean dispatchNestedFling(android.view.View, float, float, boolean);
+ method public static boolean dispatchNestedPreFling(android.view.View, float, float);
+ method public static boolean dispatchNestedPreScroll(android.view.View, int, int, int[], int[]);
+ method public static boolean dispatchNestedScroll(android.view.View, int, int, int, int, int[]);
+ method public static void dispatchStartTemporaryDetach(android.view.View);
+ method public static int getAccessibilityLiveRegion(android.view.View);
+ method public static android.support.v4.view.accessibility.AccessibilityNodeProviderCompat getAccessibilityNodeProvider(android.view.View);
+ method public static deprecated float getAlpha(android.view.View);
+ method public static android.content.res.ColorStateList getBackgroundTintList(android.view.View);
+ method public static android.graphics.PorterDuff.Mode getBackgroundTintMode(android.view.View);
+ method public static android.graphics.Rect getClipBounds(android.view.View);
+ method public static android.view.Display getDisplay(android.view.View);
+ method public static float getElevation(android.view.View);
+ method public static boolean getFitsSystemWindows(android.view.View);
+ method public static int getImportantForAccessibility(android.view.View);
+ method public static int getLabelFor(android.view.View);
+ method public static deprecated int getLayerType(android.view.View);
+ method public static int getLayoutDirection(android.view.View);
+ method public static deprecated android.graphics.Matrix getMatrix(android.view.View);
+ method public static deprecated int getMeasuredHeightAndState(android.view.View);
+ method public static deprecated int getMeasuredState(android.view.View);
+ method public static deprecated int getMeasuredWidthAndState(android.view.View);
+ method public static int getMinimumHeight(android.view.View);
+ method public static int getMinimumWidth(android.view.View);
+ method public static deprecated int getOverScrollMode(android.view.View);
+ method public static int getPaddingEnd(android.view.View);
+ method public static int getPaddingStart(android.view.View);
+ method public static android.view.ViewParent getParentForAccessibility(android.view.View);
+ method public static deprecated float getPivotX(android.view.View);
+ method public static deprecated float getPivotY(android.view.View);
+ method public static deprecated float getRotation(android.view.View);
+ method public static deprecated float getRotationX(android.view.View);
+ method public static deprecated float getRotationY(android.view.View);
+ method public static deprecated float getScaleX(android.view.View);
+ method public static deprecated float getScaleY(android.view.View);
+ method public static int getScrollIndicators(android.view.View);
+ method public static java.lang.String getTransitionName(android.view.View);
+ method public static deprecated float getTranslationX(android.view.View);
+ method public static deprecated float getTranslationY(android.view.View);
+ method public static float getTranslationZ(android.view.View);
+ method public static int getWindowSystemUiVisibility(android.view.View);
+ method public static deprecated float getX(android.view.View);
+ method public static deprecated float getY(android.view.View);
+ method public static float getZ(android.view.View);
+ method public static boolean hasAccessibilityDelegate(android.view.View);
+ method public static boolean hasNestedScrollingParent(android.view.View);
+ method public static boolean hasOnClickListeners(android.view.View);
+ method public static boolean hasOverlappingRendering(android.view.View);
+ method public static boolean hasTransientState(android.view.View);
+ method public static boolean isAttachedToWindow(android.view.View);
+ method public static boolean isImportantForAccessibility(android.view.View);
+ method public static boolean isInLayout(android.view.View);
+ method public static boolean isLaidOut(android.view.View);
+ method public static boolean isLayoutDirectionResolved(android.view.View);
+ method public static boolean isNestedScrollingEnabled(android.view.View);
+ method public static deprecated boolean isOpaque(android.view.View);
+ method public static boolean isPaddingRelative(android.view.View);
+ method public static deprecated void jumpDrawablesToCurrentState(android.view.View);
+ method public static void offsetLeftAndRight(android.view.View, int);
+ method public static void offsetTopAndBottom(android.view.View, int);
+ method public static android.support.v4.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, android.support.v4.view.WindowInsetsCompat);
+ method public static void onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+ method public static void onInitializeAccessibilityNodeInfo(android.view.View, android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+ method public static void onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+ method public static boolean performAccessibilityAction(android.view.View, int, android.os.Bundle);
+ method public static void postInvalidateOnAnimation(android.view.View);
+ method public static void postInvalidateOnAnimation(android.view.View, int, int, int, int);
+ method public static void postOnAnimation(android.view.View, java.lang.Runnable);
+ method public static void postOnAnimationDelayed(android.view.View, java.lang.Runnable, long);
+ method public static void requestApplyInsets(android.view.View);
+ method public static deprecated int resolveSizeAndState(int, int, int);
+ method public static void setAccessibilityDelegate(android.view.View, android.support.v4.view.AccessibilityDelegateCompat);
+ method public static void setAccessibilityLiveRegion(android.view.View, int);
+ method public static deprecated void setActivated(android.view.View, boolean);
+ method public static deprecated void setAlpha(android.view.View, float);
+ method public static void setBackground(android.view.View, android.graphics.drawable.Drawable);
+ method public static void setBackgroundTintList(android.view.View, android.content.res.ColorStateList);
+ method public static void setBackgroundTintMode(android.view.View, android.graphics.PorterDuff.Mode);
+ method public static void setChildrenDrawingOrderEnabled(android.view.ViewGroup, boolean);
+ method public static void setClipBounds(android.view.View, android.graphics.Rect);
+ method public static void setElevation(android.view.View, float);
+ method public static void setFitsSystemWindows(android.view.View, boolean);
+ method public static void setHasTransientState(android.view.View, boolean);
+ method public static void setImportantForAccessibility(android.view.View, int);
+ method public static void setLabelFor(android.view.View, int);
+ method public static void setLayerPaint(android.view.View, android.graphics.Paint);
+ method public static deprecated void setLayerType(android.view.View, int, android.graphics.Paint);
+ method public static void setLayoutDirection(android.view.View, int);
+ method public static void setNestedScrollingEnabled(android.view.View, boolean);
+ method public static void setOnApplyWindowInsetsListener(android.view.View, android.support.v4.view.OnApplyWindowInsetsListener);
+ method public static deprecated void setOverScrollMode(android.view.View, int);
+ method public static void setPaddingRelative(android.view.View, int, int, int, int);
+ method public static deprecated void setPivotX(android.view.View, float);
+ method public static deprecated void setPivotY(android.view.View, float);
+ method public static void setPointerIcon(android.view.View, android.support.v4.view.PointerIconCompat);
+ method public static deprecated void setRotation(android.view.View, float);
+ method public static deprecated void setRotationX(android.view.View, float);
+ method public static deprecated void setRotationY(android.view.View, float);
+ method public static deprecated void setSaveFromParentEnabled(android.view.View, boolean);
+ method public static deprecated void setScaleX(android.view.View, float);
+ method public static deprecated void setScaleY(android.view.View, float);
+ method public static void setScrollIndicators(android.view.View, int);
+ method public static void setScrollIndicators(android.view.View, int, int);
+ method public static void setTooltipText(android.view.View, java.lang.CharSequence);
+ method public static void setTransitionName(android.view.View, java.lang.String);
+ method public static deprecated void setTranslationX(android.view.View, float);
+ method public static deprecated void setTranslationY(android.view.View, float);
+ method public static void setTranslationZ(android.view.View, float);
+ method public static deprecated void setX(android.view.View, float);
+ method public static deprecated void setY(android.view.View, float);
+ method public static void setZ(android.view.View, float);
+ method public static boolean startNestedScroll(android.view.View, int);
+ method public static void stopNestedScroll(android.view.View);
+ field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2
+ field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
+ field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
+ field public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0; // 0x0
+ field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 2; // 0x2
+ field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 4; // 0x4
+ field public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 1; // 0x1
+ field public static final int LAYER_TYPE_HARDWARE = 2; // 0x2
+ field public static final int LAYER_TYPE_NONE = 0; // 0x0
+ field public static final int LAYER_TYPE_SOFTWARE = 1; // 0x1
+ field public static final int LAYOUT_DIRECTION_INHERIT = 2; // 0x2
+ field public static final int LAYOUT_DIRECTION_LOCALE = 3; // 0x3
+ field public static final int LAYOUT_DIRECTION_LTR = 0; // 0x0
+ field public static final int LAYOUT_DIRECTION_RTL = 1; // 0x1
+ field public static final deprecated int MEASURED_HEIGHT_STATE_SHIFT = 16; // 0x10
+ field public static final deprecated int MEASURED_SIZE_MASK = 16777215; // 0xffffff
+ field public static final deprecated int MEASURED_STATE_MASK = -16777216; // 0xff000000
+ field public static final deprecated int MEASURED_STATE_TOO_SMALL = 16777216; // 0x1000000
+ field public static final deprecated int OVER_SCROLL_ALWAYS = 0; // 0x0
+ field public static final deprecated int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; // 0x1
+ field public static final deprecated int OVER_SCROLL_NEVER = 2; // 0x2
+ field public static final int SCROLL_AXIS_HORIZONTAL = 1; // 0x1
+ field public static final int SCROLL_AXIS_NONE = 0; // 0x0
+ field public static final int SCROLL_AXIS_VERTICAL = 2; // 0x2
+ field public static final int SCROLL_INDICATOR_BOTTOM = 2; // 0x2
+ field public static final int SCROLL_INDICATOR_END = 32; // 0x20
+ field public static final int SCROLL_INDICATOR_LEFT = 4; // 0x4
+ field public static final int SCROLL_INDICATOR_RIGHT = 8; // 0x8
+ field public static final int SCROLL_INDICATOR_START = 16; // 0x10
+ field public static final int SCROLL_INDICATOR_TOP = 1; // 0x1
+ }
+
+ public final class ViewConfigurationCompat {
+ method public static deprecated int getScaledPagingTouchSlop(android.view.ViewConfiguration);
+ method public static boolean hasPermanentMenuKey(android.view.ViewConfiguration);
+ }
+
+ public final class ViewGroupCompat {
+ method public static int getLayoutMode(android.view.ViewGroup);
+ method public static int getNestedScrollAxes(android.view.ViewGroup);
+ method public static boolean isTransitionGroup(android.view.ViewGroup);
+ method public static boolean onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent);
+ method public static void setLayoutMode(android.view.ViewGroup, int);
+ method public static void setMotionEventSplittingEnabled(android.view.ViewGroup, boolean);
+ method public static void setTransitionGroup(android.view.ViewGroup, boolean);
+ field public static final int LAYOUT_MODE_CLIP_BOUNDS = 0; // 0x0
+ field public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1; // 0x1
+ }
+
+ public class ViewPager extends android.view.ViewGroup {
+ ctor public ViewPager(android.content.Context);
+ ctor public ViewPager(android.content.Context, android.util.AttributeSet);
+ method public void addOnAdapterChangeListener(android.support.v4.view.ViewPager.OnAdapterChangeListener);
+ method public void addOnPageChangeListener(android.support.v4.view.ViewPager.OnPageChangeListener);
+ method public boolean arrowScroll(int);
+ method public boolean beginFakeDrag();
+ method protected boolean canScroll(android.view.View, boolean, int, int, int);
+ method public void clearOnPageChangeListeners();
+ method public void endFakeDrag();
+ method public boolean executeKeyEvent(android.view.KeyEvent);
+ method public void fakeDragBy(float);
+ method public android.support.v4.view.PagerAdapter getAdapter();
+ method public int getCurrentItem();
+ method public int getOffscreenPageLimit();
+ method public int getPageMargin();
+ method public boolean isFakeDragging();
+ method protected void onLayout(boolean, int, int, int, int);
+ method protected void onPageScrolled(int, float, int);
+ method public void onRestoreInstanceState(android.os.Parcelable);
+ method public android.os.Parcelable onSaveInstanceState();
+ method public void removeOnAdapterChangeListener(android.support.v4.view.ViewPager.OnAdapterChangeListener);
+ method public void removeOnPageChangeListener(android.support.v4.view.ViewPager.OnPageChangeListener);
+ method public void setAdapter(android.support.v4.view.PagerAdapter);
+ method public void setCurrentItem(int);
+ method public void setCurrentItem(int, boolean);
+ method public void setOffscreenPageLimit(int);
+ method public deprecated void setOnPageChangeListener(android.support.v4.view.ViewPager.OnPageChangeListener);
+ method public void setPageMargin(int);
+ method public void setPageMarginDrawable(android.graphics.drawable.Drawable);
+ method public void setPageMarginDrawable(int);
+ method public void setPageTransformer(boolean, android.support.v4.view.ViewPager.PageTransformer);
+ method public void setPageTransformer(boolean, android.support.v4.view.ViewPager.PageTransformer, int);
+ field public static final int SCROLL_STATE_DRAGGING = 1; // 0x1
+ field public static final int SCROLL_STATE_IDLE = 0; // 0x0
+ field public static final int SCROLL_STATE_SETTLING = 2; // 0x2
+ }
+
+ public static abstract class ViewPager.DecorView implements java.lang.annotation.Annotation {
+ }
+
+ public static class ViewPager.LayoutParams extends android.view.ViewGroup.LayoutParams {
+ ctor public ViewPager.LayoutParams();
+ ctor public ViewPager.LayoutParams(android.content.Context, android.util.AttributeSet);
+ field public int gravity;
+ field public boolean isDecor;
+ }
+
+ public static abstract interface ViewPager.OnAdapterChangeListener {
+ method public abstract void onAdapterChanged(android.support.v4.view.ViewPager, android.support.v4.view.PagerAdapter, android.support.v4.view.PagerAdapter);
+ }
+
+ public static abstract interface ViewPager.OnPageChangeListener {
+ method public abstract void onPageScrollStateChanged(int);
+ method public abstract void onPageScrolled(int, float, int);
+ method public abstract void onPageSelected(int);
+ }
+
+ public static abstract interface ViewPager.PageTransformer {
+ method public abstract void transformPage(android.view.View, float);
+ }
+
+ public static class ViewPager.SavedState extends android.support.v4.view.AbsSavedState {
+ ctor public ViewPager.SavedState(android.os.Parcelable);
+ field public static final android.os.Parcelable.Creator<android.support.v4.view.ViewPager.SavedState> CREATOR;
+ }
+
+ public static class ViewPager.SimpleOnPageChangeListener implements android.support.v4.view.ViewPager.OnPageChangeListener {
+ ctor public ViewPager.SimpleOnPageChangeListener();
+ method public void onPageScrollStateChanged(int);
+ method public void onPageScrolled(int, float, int);
+ method public void onPageSelected(int);
+ }
+
+ public final class ViewParentCompat {
+ method public static void notifySubtreeAccessibilityStateChanged(android.view.ViewParent, android.view.View, android.view.View, int);
+ method public static boolean onNestedFling(android.view.ViewParent, android.view.View, float, float, boolean);
+ method public static boolean onNestedPreFling(android.view.ViewParent, android.view.View, float, float);
+ method public static void onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[]);
+ method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int);
+ method public static void onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int);
+ method public static boolean onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int);
+ method public static void onStopNestedScroll(android.view.ViewParent, android.view.View);
+ method public static boolean requestSendAccessibilityEvent(android.view.ViewParent, android.view.View, android.view.accessibility.AccessibilityEvent);
+ }
+
+ public final class ViewPropertyAnimatorCompat {
+ method public android.support.v4.view.ViewPropertyAnimatorCompat alpha(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat alphaBy(float);
+ method public void cancel();
+ method public long getDuration();
+ method public android.view.animation.Interpolator getInterpolator();
+ method public long getStartDelay();
+ method public android.support.v4.view.ViewPropertyAnimatorCompat rotation(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat rotationBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat rotationX(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat rotationXBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat rotationY(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat rotationYBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat scaleX(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat scaleXBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat scaleY(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat scaleYBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat setDuration(long);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat setInterpolator(android.view.animation.Interpolator);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat setListener(android.support.v4.view.ViewPropertyAnimatorListener);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat setStartDelay(long);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat setUpdateListener(android.support.v4.view.ViewPropertyAnimatorUpdateListener);
+ method public void start();
+ method public android.support.v4.view.ViewPropertyAnimatorCompat translationX(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat translationXBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat translationY(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat translationYBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat translationZ(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat translationZBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat withEndAction(java.lang.Runnable);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat withLayer();
+ method public android.support.v4.view.ViewPropertyAnimatorCompat withStartAction(java.lang.Runnable);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat x(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat xBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat y(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat yBy(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat z(float);
+ method public android.support.v4.view.ViewPropertyAnimatorCompat zBy(float);
+ }
+
+ public abstract interface ViewPropertyAnimatorListener {
+ method public abstract void onAnimationCancel(android.view.View);
+ method public abstract void onAnimationEnd(android.view.View);
+ method public abstract void onAnimationStart(android.view.View);
+ }
+
+ public class ViewPropertyAnimatorListenerAdapter implements android.support.v4.view.ViewPropertyAnimatorListener {
+ ctor public ViewPropertyAnimatorListenerAdapter();
+ method public void onAnimationCancel(android.view.View);
+ method public void onAnimationEnd(android.view.View);
+ method public void onAnimationStart(android.view.View);
+ }
+
+ public abstract interface ViewPropertyAnimatorUpdateListener {
+ method public abstract void onAnimationUpdate(android.view.View);
+ }
+
+ public final class WindowCompat {
+ field public static final int FEATURE_ACTION_BAR = 8; // 0x8
+ field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
+ field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+ }
+
+ public class WindowInsetsCompat {
+ ctor public WindowInsetsCompat(android.support.v4.view.WindowInsetsCompat);
+ method public android.support.v4.view.WindowInsetsCompat consumeStableInsets();
+ method public android.support.v4.view.WindowInsetsCompat consumeSystemWindowInsets();
+ method public int getStableInsetBottom();
+ method public int getStableInsetLeft();
+ method public int getStableInsetRight();
+ method public int getStableInsetTop();
+ method public int getSystemWindowInsetBottom();
+ method public int getSystemWindowInsetLeft();
+ method public int getSystemWindowInsetRight();
+ method public int getSystemWindowInsetTop();
+ method public boolean hasInsets();
+ method public boolean hasStableInsets();
+ method public boolean hasSystemWindowInsets();
+ method public boolean isConsumed();
+ method public boolean isRound();
+ method public android.support.v4.view.WindowInsetsCompat replaceSystemWindowInsets(int, int, int, int);
+ method public android.support.v4.view.WindowInsetsCompat replaceSystemWindowInsets(android.graphics.Rect);
+ }
+
+}
+
+package android.support.v4.view.accessibility {
+
+ public final class AccessibilityEventCompat {
+ method public static void appendRecord(android.view.accessibility.AccessibilityEvent, android.support.v4.view.accessibility.AccessibilityRecordCompat);
+ method public static android.support.v4.view.accessibility.AccessibilityRecordCompat asRecord(android.view.accessibility.AccessibilityEvent);
+ method public int getAction(android.view.accessibility.AccessibilityEvent);
+ method public static int getContentChangeTypes(android.view.accessibility.AccessibilityEvent);
+ method public int getMovementGranularity(android.view.accessibility.AccessibilityEvent);
+ method public static android.support.v4.view.accessibility.AccessibilityRecordCompat getRecord(android.view.accessibility.AccessibilityEvent, int);
+ method public static int getRecordCount(android.view.accessibility.AccessibilityEvent);
+ method public void setAction(android.view.accessibility.AccessibilityEvent, int);
+ method public static void setContentChangeTypes(android.view.accessibility.AccessibilityEvent, int);
+ method public void setMovementGranularity(android.view.accessibility.AccessibilityEvent, int);
+ field public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 4; // 0x4
+ field public static final int CONTENT_CHANGE_TYPE_SUBTREE = 1; // 0x1
+ field public static final int CONTENT_CHANGE_TYPE_TEXT = 2; // 0x2
+ field public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0; // 0x0
+ field public static final int TYPES_ALL_MASK = -1; // 0xffffffff
+ field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000
+ field public static final int TYPE_ASSIST_READING_CONTEXT = 16777216; // 0x1000000
+ field public static final int TYPE_GESTURE_DETECTION_END = 524288; // 0x80000
+ field public static final int TYPE_GESTURE_DETECTION_START = 262144; // 0x40000
+ field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1024; // 0x400
+ field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 512; // 0x200
+ field public static final int TYPE_TOUCH_INTERACTION_END = 2097152; // 0x200000
+ field public static final int TYPE_TOUCH_INTERACTION_START = 1048576; // 0x100000
+ field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 32768; // 0x8000
+ field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 65536; // 0x10000
+ field public static final int TYPE_VIEW_CONTEXT_CLICKED = 8388608; // 0x800000
+ field public static final int TYPE_VIEW_HOVER_ENTER = 128; // 0x80
+ field public static final int TYPE_VIEW_HOVER_EXIT = 256; // 0x100
+ field public static final int TYPE_VIEW_SCROLLED = 4096; // 0x1000
+ field public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192; // 0x2000
+ field public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072; // 0x20000
+ field public static final int TYPE_WINDOWS_CHANGED = 4194304; // 0x400000
+ field public static final int TYPE_WINDOW_CONTENT_CHANGED = 2048; // 0x800
+ }
+
+ public final class AccessibilityManagerCompat {
+ method public static boolean addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager, android.support.v4.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener);
+ method public static boolean addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, android.support.v4.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener);
+ method public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getEnabledAccessibilityServiceList(android.view.accessibility.AccessibilityManager, int);
+ method public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getInstalledAccessibilityServiceList(android.view.accessibility.AccessibilityManager);
+ method public static boolean isTouchExplorationEnabled(android.view.accessibility.AccessibilityManager);
+ method public static boolean removeAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager, android.support.v4.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener);
+ method public static boolean removeTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, android.support.v4.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener);
+ }
+
+ public static abstract interface AccessibilityManagerCompat.AccessibilityStateChangeListener {
+ method public abstract void onAccessibilityStateChanged(boolean);
+ }
+
+ public static abstract deprecated class AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat implements android.support.v4.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener {
+ ctor public AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat();
+ }
+
+ public static abstract interface AccessibilityManagerCompat.TouchExplorationStateChangeListener {
+ method public abstract void onTouchExplorationStateChanged(boolean);
+ }
+
+ public class AccessibilityNodeInfoCompat {
+ ctor public AccessibilityNodeInfoCompat(java.lang.Object);
+ method public void addAction(int);
+ method public void addAction(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat);
+ method public void addChild(android.view.View);
+ method public void addChild(android.view.View, int);
+ method public boolean canOpenPopup();
+ method public java.util.List<android.support.v4.view.accessibility.AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(java.lang.String);
+ method public java.util.List<android.support.v4.view.accessibility.AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByViewId(java.lang.String);
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat findFocus(int);
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat focusSearch(int);
+ method public java.util.List<android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat> getActionList();
+ method public int getActions();
+ method public void getBoundsInParent(android.graphics.Rect);
+ method public void getBoundsInScreen(android.graphics.Rect);
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getChild(int);
+ method public int getChildCount();
+ method public java.lang.CharSequence getClassName();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat getCollectionInfo();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat getCollectionItemInfo();
+ method public java.lang.CharSequence getContentDescription();
+ method public int getDrawingOrder();
+ method public java.lang.CharSequence getError();
+ method public android.os.Bundle getExtras();
+ method public java.lang.Object getInfo();
+ method public int getInputType();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getLabelFor();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getLabeledBy();
+ method public int getLiveRegion();
+ method public int getMaxTextLength();
+ method public int getMovementGranularities();
+ method public java.lang.CharSequence getPackageName();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getParent();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat getRangeInfo();
+ method public java.lang.CharSequence getRoleDescription();
+ method public java.lang.CharSequence getText();
+ method public int getTextSelectionEnd();
+ method public int getTextSelectionStart();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getTraversalAfter();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getTraversalBefore();
+ method public java.lang.String getViewIdResourceName();
+ method public android.support.v4.view.accessibility.AccessibilityWindowInfoCompat getWindow();
+ method public int getWindowId();
+ method public boolean isAccessibilityFocused();
+ method public boolean isCheckable();
+ method public boolean isChecked();
+ method public boolean isClickable();
+ method public boolean isContentInvalid();
+ method public boolean isContextClickable();
+ method public boolean isDismissable();
+ method public boolean isEditable();
+ method public boolean isEnabled();
+ method public boolean isFocusable();
+ method public boolean isFocused();
+ method public boolean isImportantForAccessibility();
+ method public boolean isLongClickable();
+ method public boolean isMultiLine();
+ method public boolean isPassword();
+ method public boolean isScrollable();
+ method public boolean isSelected();
+ method public boolean isVisibleToUser();
+ method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat obtain(android.view.View);
+ method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat obtain(android.view.View, int);
+ method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat obtain();
+ method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat obtain(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+ method public boolean performAction(int);
+ method public boolean performAction(int, android.os.Bundle);
+ method public void recycle();
+ method public boolean refresh();
+ method public boolean removeAction(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat);
+ method public boolean removeChild(android.view.View);
+ method public boolean removeChild(android.view.View, int);
+ method public void setAccessibilityFocused(boolean);
+ method public void setBoundsInParent(android.graphics.Rect);
+ method public void setBoundsInScreen(android.graphics.Rect);
+ method public void setCanOpenPopup(boolean);
+ method public void setCheckable(boolean);
+ method public void setChecked(boolean);
+ method public void setClassName(java.lang.CharSequence);
+ method public void setClickable(boolean);
+ method public void setCollectionInfo(java.lang.Object);
+ method public void setCollectionItemInfo(java.lang.Object);
+ method public void setContentDescription(java.lang.CharSequence);
+ method public void setContentInvalid(boolean);
+ method public void setContextClickable(boolean);
+ method public void setDismissable(boolean);
+ method public void setDrawingOrder(int);
+ method public void setEditable(boolean);
+ method public void setEnabled(boolean);
+ method public void setError(java.lang.CharSequence);
+ method public void setFocusable(boolean);
+ method public void setFocused(boolean);
+ method public void setImportantForAccessibility(boolean);
+ method public void setInputType(int);
+ method public void setLabelFor(android.view.View);
+ method public void setLabelFor(android.view.View, int);
+ method public void setLabeledBy(android.view.View);
+ method public void setLabeledBy(android.view.View, int);
+ method public void setLiveRegion(int);
+ method public void setLongClickable(boolean);
+ method public void setMaxTextLength(int);
+ method public void setMovementGranularities(int);
+ method public void setMultiLine(boolean);
+ method public void setPackageName(java.lang.CharSequence);
+ method public void setParent(android.view.View);
+ method public void setParent(android.view.View, int);
+ method public void setPassword(boolean);
+ method public void setRangeInfo(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat);
+ method public void setRoleDescription(java.lang.CharSequence);
+ method public void setScrollable(boolean);
+ method public void setSelected(boolean);
+ method public void setSource(android.view.View);
+ method public void setSource(android.view.View, int);
+ method public void setText(java.lang.CharSequence);
+ method public void setTextSelection(int, int);
+ method public void setTraversalAfter(android.view.View);
+ method public void setTraversalAfter(android.view.View, int);
+ method public void setTraversalBefore(android.view.View);
+ method public void setTraversalBefore(android.view.View, int);
+ method public void setViewIdResourceName(java.lang.String);
+ method public void setVisibleToUser(boolean);
+ field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
+ field public static final java.lang.String ACTION_ARGUMENT_COLUMN_INT = "android.view.accessibility.action.ARGUMENT_COLUMN_INT";
+ field public static final java.lang.String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
+ field public static final java.lang.String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
+ field public static final java.lang.String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
+ field public static final java.lang.String ACTION_ARGUMENT_PROGRESS_VALUE = "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE";
+ field public static final java.lang.String ACTION_ARGUMENT_ROW_INT = "android.view.accessibility.action.ARGUMENT_ROW_INT";
+ field public static final java.lang.String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
+ field public static final java.lang.String ACTION_ARGUMENT_SELECTION_START_INT = "ACTION_ARGUMENT_SELECTION_START_INT";
+ field public static final java.lang.String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE = "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
+ field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 128; // 0x80
+ field public static final int ACTION_CLEAR_FOCUS = 2; // 0x2
+ field public static final int ACTION_CLEAR_SELECTION = 8; // 0x8
+ field public static final int ACTION_CLICK = 16; // 0x10
+ field public static final int ACTION_COLLAPSE = 524288; // 0x80000
+ field public static final int ACTION_COPY = 16384; // 0x4000
+ field public static final int ACTION_CUT = 65536; // 0x10000
+ field public static final int ACTION_DISMISS = 1048576; // 0x100000
+ field public static final int ACTION_EXPAND = 262144; // 0x40000
+ field public static final int ACTION_FOCUS = 1; // 0x1
+ field public static final int ACTION_LONG_CLICK = 32; // 0x20
+ field public static final int ACTION_NEXT_AT_MOVEMENT_GRANULARITY = 256; // 0x100
+ field public static final int ACTION_NEXT_HTML_ELEMENT = 1024; // 0x400
+ field public static final int ACTION_PASTE = 32768; // 0x8000
+ field public static final int ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY = 512; // 0x200
+ field public static final int ACTION_PREVIOUS_HTML_ELEMENT = 2048; // 0x800
+ field public static final int ACTION_SCROLL_BACKWARD = 8192; // 0x2000
+ field public static final int ACTION_SCROLL_FORWARD = 4096; // 0x1000
+ field public static final int ACTION_SELECT = 4; // 0x4
+ field public static final int ACTION_SET_SELECTION = 131072; // 0x20000
+ field public static final int ACTION_SET_TEXT = 2097152; // 0x200000
+ field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2
+ field public static final int FOCUS_INPUT = 1; // 0x1
+ field public static final int MOVEMENT_GRANULARITY_CHARACTER = 1; // 0x1
+ field public static final int MOVEMENT_GRANULARITY_LINE = 4; // 0x4
+ field public static final int MOVEMENT_GRANULARITY_PAGE = 16; // 0x10
+ field public static final int MOVEMENT_GRANULARITY_PARAGRAPH = 8; // 0x8
+ field public static final int MOVEMENT_GRANULARITY_WORD = 2; // 0x2
+ }
+
+ public static class AccessibilityNodeInfoCompat.AccessibilityActionCompat {
+ ctor public AccessibilityNodeInfoCompat.AccessibilityActionCompat(int, java.lang.CharSequence);
+ method public int getId();
+ method public java.lang.CharSequence getLabel();
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_ACCESSIBILITY_FOCUS;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CLEAR_ACCESSIBILITY_FOCUS;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CLEAR_FOCUS;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CLEAR_SELECTION;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CLICK;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_COLLAPSE;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CONTEXT_CLICK;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_COPY;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_CUT;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DISMISS;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_EXPAND;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_FOCUS;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_LONG_CLICK;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_NEXT_HTML_ELEMENT;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PASTE;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PREVIOUS_HTML_ELEMENT;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_BACKWARD;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_DOWN;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_FORWARD;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_LEFT;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_RIGHT;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_TO_POSITION;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_UP;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SELECT;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SET_PROGRESS;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SET_SELECTION;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SET_TEXT;
+ field public static final android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SHOW_ON_SCREEN;
+ }
+
+ public static class AccessibilityNodeInfoCompat.CollectionInfoCompat {
+ method public int getColumnCount();
+ method public int getRowCount();
+ method public int getSelectionMode();
+ method public boolean isHierarchical();
+ method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat obtain(int, int, boolean, int);
+ method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat obtain(int, int, boolean);
+ field public static final int SELECTION_MODE_MULTIPLE = 2; // 0x2
+ field public static final int SELECTION_MODE_NONE = 0; // 0x0
+ field public static final int SELECTION_MODE_SINGLE = 1; // 0x1
+ }
+
+ public static class AccessibilityNodeInfoCompat.CollectionItemInfoCompat {
+ method public int getColumnIndex();
+ method public int getColumnSpan();
+ method public int getRowIndex();
+ method public int getRowSpan();
+ method public boolean isHeading();
+ method public boolean isSelected();
+ method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat obtain(int, int, int, int, boolean, boolean);
+ method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat obtain(int, int, int, int, boolean);
+ }
+
+ public static class AccessibilityNodeInfoCompat.RangeInfoCompat {
+ method public float getCurrent();
+ method public float getMax();
+ method public float getMin();
+ method public int getType();
+ method public static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat obtain(int, float, float, float);
+ field public static final int RANGE_TYPE_FLOAT = 1; // 0x1
+ field public static final int RANGE_TYPE_INT = 0; // 0x0
+ field public static final int RANGE_TYPE_PERCENT = 2; // 0x2
+ }
+
+ public class AccessibilityNodeProviderCompat {
+ ctor public AccessibilityNodeProviderCompat();
+ ctor public AccessibilityNodeProviderCompat(java.lang.Object);
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int);
+ method public java.util.List<android.support.v4.view.accessibility.AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(java.lang.String, int);
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat findFocus(int);
+ method public java.lang.Object getProvider();
+ method public boolean performAction(int, int, android.os.Bundle);
+ field public static final int HOST_VIEW_ID = -1; // 0xffffffff
+ }
+
+ public class AccessibilityRecordCompat {
+ ctor public deprecated AccessibilityRecordCompat(java.lang.Object);
+ method public int getAddedCount();
+ method public java.lang.CharSequence getBeforeText();
+ method public java.lang.CharSequence getClassName();
+ method public java.lang.CharSequence getContentDescription();
+ method public int getCurrentItemIndex();
+ method public int getFromIndex();
+ method public deprecated java.lang.Object getImpl();
+ method public int getItemCount();
+ method public int getMaxScrollX();
+ method public int getMaxScrollY();
+ method public android.os.Parcelable getParcelableData();
+ method public int getRemovedCount();
+ method public int getScrollX();
+ method public int getScrollY();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getSource();
+ method public java.util.List<java.lang.CharSequence> getText();
+ method public int getToIndex();
+ method public int getWindowId();
+ method public boolean isChecked();
+ method public boolean isEnabled();
+ method public boolean isFullScreen();
+ method public boolean isPassword();
+ method public boolean isScrollable();
+ method public static android.support.v4.view.accessibility.AccessibilityRecordCompat obtain(android.support.v4.view.accessibility.AccessibilityRecordCompat);
+ method public static android.support.v4.view.accessibility.AccessibilityRecordCompat obtain();
+ method public void recycle();
+ method public void setAddedCount(int);
+ method public void setBeforeText(java.lang.CharSequence);
+ method public void setChecked(boolean);
+ method public void setClassName(java.lang.CharSequence);
+ method public void setContentDescription(java.lang.CharSequence);
+ method public void setCurrentItemIndex(int);
+ method public void setEnabled(boolean);
+ method public void setFromIndex(int);
+ method public void setFullScreen(boolean);
+ method public void setItemCount(int);
+ method public void setMaxScrollX(int);
+ method public void setMaxScrollY(int);
+ method public void setParcelableData(android.os.Parcelable);
+ method public void setPassword(boolean);
+ method public void setRemovedCount(int);
+ method public void setScrollX(int);
+ method public void setScrollY(int);
+ method public void setScrollable(boolean);
+ method public void setSource(android.view.View);
+ method public void setSource(android.view.View, int);
+ method public void setToIndex(int);
+ }
+
+ public class AccessibilityWindowInfoCompat {
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getAnchor();
+ method public void getBoundsInScreen(android.graphics.Rect);
+ method public android.support.v4.view.accessibility.AccessibilityWindowInfoCompat getChild(int);
+ method public int getChildCount();
+ method public int getId();
+ method public int getLayer();
+ method public android.support.v4.view.accessibility.AccessibilityWindowInfoCompat getParent();
+ method public android.support.v4.view.accessibility.AccessibilityNodeInfoCompat getRoot();
+ method public java.lang.CharSequence getTitle();
+ method public int getType();
+ method public boolean isAccessibilityFocused();
+ method public boolean isActive();
+ method public boolean isFocused();
+ method public static android.support.v4.view.accessibility.AccessibilityWindowInfoCompat obtain();
+ method public static android.support.v4.view.accessibility.AccessibilityWindowInfoCompat obtain(android.support.v4.view.accessibility.AccessibilityWindowInfoCompat);
+ method public void recycle();
+ field public static final int TYPE_ACCESSIBILITY_OVERLAY = 4; // 0x4
+ field public static final int TYPE_APPLICATION = 1; // 0x1
+ field public static final int TYPE_INPUT_METHOD = 2; // 0x2
+ field public static final int TYPE_SPLIT_SCREEN_DIVIDER = 5; // 0x5
+ field public static final int TYPE_SYSTEM = 3; // 0x3
+ }
+
+}
+
+package android.support.v4.view.animation {
+
+ public class FastOutLinearInInterpolator extends android.support.v4.view.animation.LookupTableInterpolator {
+ ctor public FastOutLinearInInterpolator();
+ }
+
+ public class FastOutSlowInInterpolator extends android.support.v4.view.animation.LookupTableInterpolator {
+ ctor public FastOutSlowInInterpolator();
+ }
+
+ public class LinearOutSlowInInterpolator extends android.support.v4.view.animation.LookupTableInterpolator {
+ ctor public LinearOutSlowInInterpolator();
+ }
+
+ abstract class LookupTableInterpolator implements android.view.animation.Interpolator {
+ ctor public LookupTableInterpolator(float[]);
+ method public float getInterpolation(float);
+ }
+
+ public final class PathInterpolatorCompat {
+ method public static android.view.animation.Interpolator create(android.graphics.Path);
+ method public static android.view.animation.Interpolator create(float, float);
+ method public static android.view.animation.Interpolator create(float, float, float, float);
+ }
+
+}
+
+package android.support.v4.widget {
+
+ public abstract class AutoScrollHelper implements android.view.View.OnTouchListener {
+ ctor public AutoScrollHelper(android.view.View);
+ method public abstract boolean canTargetScrollHorizontally(int);
+ method public abstract boolean canTargetScrollVertically(int);
+ method public boolean isEnabled();
+ method public boolean isExclusive();
+ method public boolean onTouch(android.view.View, android.view.MotionEvent);
+ method public abstract void scrollTargetBy(int, int);
+ method public android.support.v4.widget.AutoScrollHelper setActivationDelay(int);
+ method public android.support.v4.widget.AutoScrollHelper setEdgeType(int);
+ method public android.support.v4.widget.AutoScrollHelper setEnabled(boolean);
+ method public android.support.v4.widget.AutoScrollHelper setExclusive(boolean);
+ method public android.support.v4.widget.AutoScrollHelper setMaximumEdges(float, float);
+ method public android.support.v4.widget.AutoScrollHelper setMaximumVelocity(float, float);
+ method public android.support.v4.widget.AutoScrollHelper setMinimumVelocity(float, float);
+ method public android.support.v4.widget.AutoScrollHelper setRampDownDuration(int);
+ method public android.support.v4.widget.AutoScrollHelper setRampUpDuration(int);
+ method public android.support.v4.widget.AutoScrollHelper setRelativeEdges(float, float);
+ method public android.support.v4.widget.AutoScrollHelper setRelativeVelocity(float, float);
+ field public static final int EDGE_TYPE_INSIDE = 0; // 0x0
+ field public static final int EDGE_TYPE_INSIDE_EXTEND = 1; // 0x1
+ field public static final int EDGE_TYPE_OUTSIDE = 2; // 0x2
+ field public static final float NO_MAX = 3.4028235E38f;
+ field public static final float NO_MIN = 0.0f;
+ field public static final float RELATIVE_UNSPECIFIED = 0.0f;
+ }
+
+ public final class CompoundButtonCompat {
+ method public static android.graphics.drawable.Drawable getButtonDrawable(android.widget.CompoundButton);
+ method public static android.content.res.ColorStateList getButtonTintList(android.widget.CompoundButton);
+ method public static android.graphics.PorterDuff.Mode getButtonTintMode(android.widget.CompoundButton);
+ method public static void setButtonTintList(android.widget.CompoundButton, android.content.res.ColorStateList);
+ method public static void setButtonTintMode(android.widget.CompoundButton, android.graphics.PorterDuff.Mode);
+ }
+
+ public class ContentLoadingProgressBar extends android.widget.ProgressBar {
+ ctor public ContentLoadingProgressBar(android.content.Context);
+ ctor public ContentLoadingProgressBar(android.content.Context, android.util.AttributeSet);
+ method public void hide();
+ method public void onAttachedToWindow();
+ method public void onDetachedFromWindow();
+ method public void show();
+ }
+
+ public abstract class CursorAdapter extends android.widget.BaseAdapter {
+ ctor public deprecated CursorAdapter(android.content.Context, android.database.Cursor);
+ ctor public CursorAdapter(android.content.Context, android.database.Cursor, boolean);
+ ctor public CursorAdapter(android.content.Context, android.database.Cursor, int);
+ method public abstract void bindView(android.view.View, android.content.Context, android.database.Cursor);
+ method public void changeCursor(android.database.Cursor);
+ method public java.lang.CharSequence convertToString(android.database.Cursor);
+ method public int getCount();
+ method public android.database.Cursor getCursor();
+ method public android.widget.Filter getFilter();
+ method public android.widget.FilterQueryProvider getFilterQueryProvider();
+ method public java.lang.Object getItem(int);
+ method public long getItemId(int);
+ method public android.view.View getView(int, android.view.View, android.view.ViewGroup);
+ method protected deprecated void init(android.content.Context, android.database.Cursor, boolean);
+ method public android.view.View newDropDownView(android.content.Context, android.database.Cursor, android.view.ViewGroup);
+ method public abstract android.view.View newView(android.content.Context, android.database.Cursor, android.view.ViewGroup);
+ method protected void onContentChanged();
+ method public android.database.Cursor runQueryOnBackgroundThread(java.lang.CharSequence);
+ method public void setFilterQueryProvider(android.widget.FilterQueryProvider);
+ method public android.database.Cursor swapCursor(android.database.Cursor);
+ field public static final deprecated int FLAG_AUTO_REQUERY = 1; // 0x1
+ field public static final int FLAG_REGISTER_CONTENT_OBSERVER = 2; // 0x2
+ }
+
+ public class DrawerLayout extends android.view.ViewGroup {
+ ctor public DrawerLayout(android.content.Context);
+ ctor public DrawerLayout(android.content.Context, android.util.AttributeSet);
+ ctor public DrawerLayout(android.content.Context, android.util.AttributeSet, int);
+ method public void addDrawerListener(android.support.v4.widget.DrawerLayout.DrawerListener);
+ method public void closeDrawer(android.view.View);
+ method public void closeDrawer(android.view.View, boolean);
+ method public void closeDrawer(int);
+ method public void closeDrawer(int, boolean);
+ method public void closeDrawers();
+ method public float getDrawerElevation();
+ method public int getDrawerLockMode(int);
+ method public int getDrawerLockMode(android.view.View);
+ method public java.lang.CharSequence getDrawerTitle(int);
+ method public android.graphics.drawable.Drawable getStatusBarBackgroundDrawable();
+ method public boolean isDrawerOpen(android.view.View);
+ method public boolean isDrawerOpen(int);
+ method public boolean isDrawerVisible(android.view.View);
+ method public boolean isDrawerVisible(int);
+ method public void onDraw(android.graphics.Canvas);
+ method protected void onLayout(boolean, int, int, int, int);
+ method public void openDrawer(android.view.View);
+ method public void openDrawer(android.view.View, boolean);
+ method public void openDrawer(int);
+ method public void openDrawer(int, boolean);
+ method public void removeDrawerListener(android.support.v4.widget.DrawerLayout.DrawerListener);
+ method public void setDrawerElevation(float);
+ method public deprecated void setDrawerListener(android.support.v4.widget.DrawerLayout.DrawerListener);
+ method public void setDrawerLockMode(int);
+ method public void setDrawerLockMode(int, int);
+ method public void setDrawerLockMode(int, android.view.View);
+ method public void setDrawerShadow(android.graphics.drawable.Drawable, int);
+ method public void setDrawerShadow(int, int);
+ method public void setDrawerTitle(int, java.lang.CharSequence);
+ method public void setScrimColor(int);
+ method public void setStatusBarBackground(android.graphics.drawable.Drawable);
+ method public void setStatusBarBackground(int);
+ method public void setStatusBarBackgroundColor(int);
+ field public static final int LOCK_MODE_LOCKED_CLOSED = 1; // 0x1
+ field public static final int LOCK_MODE_LOCKED_OPEN = 2; // 0x2
+ field public static final int LOCK_MODE_UNDEFINED = 3; // 0x3
+ field public static final int LOCK_MODE_UNLOCKED = 0; // 0x0
+ field public static final int STATE_DRAGGING = 1; // 0x1
+ field public static final int STATE_IDLE = 0; // 0x0
+ field public static final int STATE_SETTLING = 2; // 0x2
+ }
+
+ public static abstract interface DrawerLayout.DrawerListener {
+ method public abstract void onDrawerClosed(android.view.View);
+ method public abstract void onDrawerOpened(android.view.View);
+ method public abstract void onDrawerSlide(android.view.View, float);
+ method public abstract void onDrawerStateChanged(int);
+ }
+
+ public static class DrawerLayout.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+ ctor public DrawerLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+ ctor public DrawerLayout.LayoutParams(int, int);
+ ctor public DrawerLayout.LayoutParams(int, int, int);
+ ctor public DrawerLayout.LayoutParams(android.support.v4.widget.DrawerLayout.LayoutParams);
+ ctor public DrawerLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+ ctor public DrawerLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ field public int gravity;
+ }
+
+ protected static class DrawerLayout.SavedState extends android.support.v4.view.AbsSavedState {
+ ctor public DrawerLayout.SavedState(android.os.Parcel, java.lang.ClassLoader);
+ ctor public DrawerLayout.SavedState(android.os.Parcelable);
+ field public static final android.os.Parcelable.Creator<android.support.v4.widget.DrawerLayout.SavedState> CREATOR;
+ }
+
+ public static abstract class DrawerLayout.SimpleDrawerListener implements android.support.v4.widget.DrawerLayout.DrawerListener {
+ ctor public DrawerLayout.SimpleDrawerListener();
+ method public void onDrawerClosed(android.view.View);
+ method public void onDrawerOpened(android.view.View);
+ method public void onDrawerSlide(android.view.View, float);
+ method public void onDrawerStateChanged(int);
+ }
+
+ public final class EdgeEffectCompat {
+ ctor public EdgeEffectCompat(android.content.Context);
+ method public boolean draw(android.graphics.Canvas);
+ method public void finish();
+ method public boolean isFinished();
+ method public boolean onAbsorb(int);
+ method public deprecated boolean onPull(float);
+ method public boolean onPull(float, float);
+ method public boolean onRelease();
+ method public void setSize(int, int);
+ }
+
+ public abstract class ExploreByTouchHelper extends android.support.v4.view.AccessibilityDelegateCompat {
+ ctor public ExploreByTouchHelper(android.view.View);
+ method public final boolean clearKeyboardFocusForVirtualView(int);
+ method public final boolean dispatchHoverEvent(android.view.MotionEvent);
+ method public final boolean dispatchKeyEvent(android.view.KeyEvent);
+ method public final int getAccessibilityFocusedVirtualViewId();
+ method public deprecated int getFocusedVirtualView();
+ method public final int getKeyboardFocusedVirtualViewId();
+ method protected abstract int getVirtualViewAt(float, float);
+ method protected abstract void getVisibleVirtualViews(java.util.List<java.lang.Integer>);
+ method public final void invalidateRoot();
+ method public final void invalidateVirtualView(int);
+ method public final void invalidateVirtualView(int, int);
+ method public final void onFocusChanged(boolean, int, android.graphics.Rect);
+ method protected abstract boolean onPerformActionForVirtualView(int, int, android.os.Bundle);
+ method protected void onPopulateEventForHost(android.view.accessibility.AccessibilityEvent);
+ method protected void onPopulateEventForVirtualView(int, android.view.accessibility.AccessibilityEvent);
+ method protected void onPopulateNodeForHost(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+ method protected abstract void onPopulateNodeForVirtualView(int, android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+ method protected void onVirtualViewKeyboardFocusChanged(int, boolean);
+ method public final boolean requestKeyboardFocusForVirtualView(int);
+ method public final boolean sendEventForVirtualView(int, int);
+ field public static final int HOST_ID = -1; // 0xffffffff
+ field public static final int INVALID_ID = -2147483648; // 0x80000000
+ }
+
+ public final class ListPopupWindowCompat {
+ method public static android.view.View.OnTouchListener createDragToOpenListener(java.lang.Object, android.view.View);
+ }
+
+ public class ListViewAutoScrollHelper extends android.support.v4.widget.AutoScrollHelper {
+ ctor public ListViewAutoScrollHelper(android.widget.ListView);
+ method public boolean canTargetScrollHorizontally(int);
+ method public boolean canTargetScrollVertically(int);
+ method public void scrollTargetBy(int, int);
+ }
+
+ public final class ListViewCompat {
+ method public static void scrollListBy(android.widget.ListView, int);
+ }
+
+ public class NestedScrollView extends android.widget.FrameLayout implements android.support.v4.view.NestedScrollingChild android.support.v4.view.NestedScrollingParent android.support.v4.view.ScrollingView {
+ ctor public NestedScrollView(android.content.Context);
+ ctor public NestedScrollView(android.content.Context, android.util.AttributeSet);
+ ctor public NestedScrollView(android.content.Context, android.util.AttributeSet, int);
+ method public boolean arrowScroll(int);
+ method protected int computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect);
+ method public boolean executeKeyEvent(android.view.KeyEvent);
+ method public void fling(int);
+ method public boolean fullScroll(int);
+ method public int getMaxScrollAmount();
+ method public boolean isFillViewport();
+ method public boolean isSmoothScrollingEnabled();
+ method public void onAttachedToWindow();
+ method public boolean pageScroll(int);
+ method public void setFillViewport(boolean);
+ method public void setOnScrollChangeListener(android.support.v4.widget.NestedScrollView.OnScrollChangeListener);
+ method public void setSmoothScrollingEnabled(boolean);
+ method public final void smoothScrollBy(int, int);
+ method public final void smoothScrollTo(int, int);
+ }
+
+ public static abstract interface NestedScrollView.OnScrollChangeListener {
+ method public abstract void onScrollChange(android.support.v4.widget.NestedScrollView, int, int, int, int);
+ }
+
+ public final class PopupMenuCompat {
+ method public static android.view.View.OnTouchListener getDragToOpenListener(java.lang.Object);
+ }
+
+ public final class PopupWindowCompat {
+ method public static boolean getOverlapAnchor(android.widget.PopupWindow);
+ method public static int getWindowLayoutType(android.widget.PopupWindow);
+ method public static void setOverlapAnchor(android.widget.PopupWindow, boolean);
+ method public static void setWindowLayoutType(android.widget.PopupWindow, int);
+ method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
+ }
+
+ public abstract class ResourceCursorAdapter extends android.support.v4.widget.CursorAdapter {
+ ctor public deprecated ResourceCursorAdapter(android.content.Context, int, android.database.Cursor);
+ ctor public deprecated ResourceCursorAdapter(android.content.Context, int, android.database.Cursor, boolean);
+ ctor public ResourceCursorAdapter(android.content.Context, int, android.database.Cursor, int);
+ method public android.view.View newView(android.content.Context, android.database.Cursor, android.view.ViewGroup);
+ method public void setDropDownViewResource(int);
+ method public void setViewResource(int);
+ }
+
+ public final class ScrollerCompat {
+ method public void abortAnimation();
+ method public boolean computeScrollOffset();
+ method public static android.support.v4.widget.ScrollerCompat create(android.content.Context);
+ method public static android.support.v4.widget.ScrollerCompat create(android.content.Context, android.view.animation.Interpolator);
+ method public void fling(int, int, int, int, int, int, int, int);
+ method public void fling(int, int, int, int, int, int, int, int, int, int);
+ method public float getCurrVelocity();
+ method public int getCurrX();
+ method public int getCurrY();
+ method public int getFinalX();
+ method public int getFinalY();
+ method public boolean isFinished();
+ method public boolean isOverScrolled();
+ method public void notifyHorizontalEdgeReached(int, int, int);
+ method public void notifyVerticalEdgeReached(int, int, int);
+ method public boolean springBack(int, int, int, int, int, int);
+ method public void startScroll(int, int, int, int);
+ method public void startScroll(int, int, int, int, int);
+ }
+
+ public final deprecated class SearchViewCompat {
+ method public static deprecated java.lang.CharSequence getQuery(android.view.View);
+ method public static deprecated boolean isIconified(android.view.View);
+ method public static deprecated boolean isQueryRefinementEnabled(android.view.View);
+ method public static deprecated boolean isSubmitButtonEnabled(android.view.View);
+ method public static deprecated android.view.View newSearchView(android.content.Context);
+ method public static deprecated void setIconified(android.view.View, boolean);
+ method public static deprecated void setImeOptions(android.view.View, int);
+ method public static deprecated void setInputType(android.view.View, int);
+ method public static deprecated void setMaxWidth(android.view.View, int);
+ method public static deprecated void setOnCloseListener(android.view.View, android.support.v4.widget.SearchViewCompat.OnCloseListener);
+ method public static deprecated void setOnQueryTextListener(android.view.View, android.support.v4.widget.SearchViewCompat.OnQueryTextListener);
+ method public static deprecated void setQuery(android.view.View, java.lang.CharSequence, boolean);
+ method public static deprecated void setQueryHint(android.view.View, java.lang.CharSequence);
+ method public static deprecated void setQueryRefinementEnabled(android.view.View, boolean);
+ method public static deprecated void setSearchableInfo(android.view.View, android.content.ComponentName);
+ method public static deprecated void setSubmitButtonEnabled(android.view.View, boolean);
+ }
+
+ public static abstract deprecated interface SearchViewCompat.OnCloseListener {
+ method public abstract boolean onClose();
+ }
+
+ public static abstract deprecated class SearchViewCompat.OnCloseListenerCompat implements android.support.v4.widget.SearchViewCompat.OnCloseListener {
+ ctor public SearchViewCompat.OnCloseListenerCompat();
+ method public boolean onClose();
+ }
+
+ public static abstract deprecated interface SearchViewCompat.OnQueryTextListener {
+ method public abstract boolean onQueryTextChange(java.lang.String);
+ method public abstract boolean onQueryTextSubmit(java.lang.String);
+ }
+
+ public static abstract deprecated class SearchViewCompat.OnQueryTextListenerCompat implements android.support.v4.widget.SearchViewCompat.OnQueryTextListener {
+ ctor public SearchViewCompat.OnQueryTextListenerCompat();
+ method public boolean onQueryTextChange(java.lang.String);
+ method public boolean onQueryTextSubmit(java.lang.String);
+ }
+
+ public class SimpleCursorAdapter extends android.support.v4.widget.ResourceCursorAdapter {
+ ctor public deprecated SimpleCursorAdapter(android.content.Context, int, android.database.Cursor, java.lang.String[], int[]);
+ ctor public SimpleCursorAdapter(android.content.Context, int, android.database.Cursor, java.lang.String[], int[], int);
+ method public void bindView(android.view.View, android.content.Context, android.database.Cursor);
+ method public void changeCursorAndColumns(android.database.Cursor, java.lang.String[], int[]);
+ method public android.support.v4.widget.SimpleCursorAdapter.CursorToStringConverter getCursorToStringConverter();
+ method public int getStringConversionColumn();
+ method public android.support.v4.widget.SimpleCursorAdapter.ViewBinder getViewBinder();
+ method public void setCursorToStringConverter(android.support.v4.widget.SimpleCursorAdapter.CursorToStringConverter);
+ method public void setStringConversionColumn(int);
+ method public void setViewBinder(android.support.v4.widget.SimpleCursorAdapter.ViewBinder);
+ method public void setViewImage(android.widget.ImageView, java.lang.String);
+ method public void setViewText(android.widget.TextView, java.lang.String);
+ }
+
+ public static abstract interface SimpleCursorAdapter.CursorToStringConverter {
+ method public abstract java.lang.CharSequence convertToString(android.database.Cursor);
+ }
+
+ public static abstract interface SimpleCursorAdapter.ViewBinder {
+ method public abstract boolean setViewValue(android.view.View, android.database.Cursor, int);
+ }
+
+ public class SlidingPaneLayout extends android.view.ViewGroup {
+ ctor public SlidingPaneLayout(android.content.Context);
+ ctor public SlidingPaneLayout(android.content.Context, android.util.AttributeSet);
+ ctor public SlidingPaneLayout(android.content.Context, android.util.AttributeSet, int);
+ method protected boolean canScroll(android.view.View, boolean, int, int, int);
+ method public deprecated boolean canSlide();
+ method public boolean closePane();
+ method public int getCoveredFadeColor();
+ method public int getParallaxDistance();
+ method public int getSliderFadeColor();
+ method public boolean isOpen();
+ method public boolean isSlideable();
+ method protected void onLayout(boolean, int, int, int, int);
+ method public boolean openPane();
+ method public void setCoveredFadeColor(int);
+ method public void setPanelSlideListener(android.support.v4.widget.SlidingPaneLayout.PanelSlideListener);
+ method public void setParallaxDistance(int);
+ method public deprecated void setShadowDrawable(android.graphics.drawable.Drawable);
+ method public void setShadowDrawableLeft(android.graphics.drawable.Drawable);
+ method public void setShadowDrawableRight(android.graphics.drawable.Drawable);
+ method public deprecated void setShadowResource(int);
+ method public void setShadowResourceLeft(int);
+ method public void setShadowResourceRight(int);
+ method public void setSliderFadeColor(int);
+ method public deprecated void smoothSlideClosed();
+ method public deprecated void smoothSlideOpen();
+ }
+
+ public static class SlidingPaneLayout.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+ ctor public SlidingPaneLayout.LayoutParams();
+ ctor public SlidingPaneLayout.LayoutParams(int, int);
+ ctor public SlidingPaneLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+ ctor public SlidingPaneLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ ctor public SlidingPaneLayout.LayoutParams(android.support.v4.widget.SlidingPaneLayout.LayoutParams);
+ ctor public SlidingPaneLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+ field public float weight;
+ }
+
+ public static abstract interface SlidingPaneLayout.PanelSlideListener {
+ method public abstract void onPanelClosed(android.view.View);
+ method public abstract void onPanelOpened(android.view.View);
+ method public abstract void onPanelSlide(android.view.View, float);
+ }
+
+ public static class SlidingPaneLayout.SimplePanelSlideListener implements android.support.v4.widget.SlidingPaneLayout.PanelSlideListener {
+ ctor public SlidingPaneLayout.SimplePanelSlideListener();
+ method public void onPanelClosed(android.view.View);
+ method public void onPanelOpened(android.view.View);
+ method public void onPanelSlide(android.view.View, float);
+ }
+
+ public class Space extends android.view.View {
+ ctor public Space(android.content.Context, android.util.AttributeSet, int);
+ ctor public Space(android.content.Context, android.util.AttributeSet);
+ ctor public Space(android.content.Context);
+ }
+
+ public class SwipeRefreshLayout extends android.view.ViewGroup implements android.support.v4.view.NestedScrollingChild android.support.v4.view.NestedScrollingParent {
+ ctor public SwipeRefreshLayout(android.content.Context);
+ ctor public SwipeRefreshLayout(android.content.Context, android.util.AttributeSet);
+ method public boolean canChildScrollUp();
+ method public int getProgressCircleDiameter();
+ method public int getProgressViewEndOffset();
+ method public int getProgressViewStartOffset();
+ method public boolean isRefreshing();
+ method protected void onLayout(boolean, int, int, int, int);
+ method public void onMeasure(int, int);
+ method public deprecated void setColorScheme(int...);
+ method public void setColorSchemeColors(int...);
+ method public void setColorSchemeResources(int...);
+ method public void setDistanceToTriggerSync(int);
+ method public void setOnChildScrollUpCallback(android.support.v4.widget.SwipeRefreshLayout.OnChildScrollUpCallback);
+ method public void setOnRefreshListener(android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener);
+ method public deprecated void setProgressBackgroundColor(int);
+ method public void setProgressBackgroundColorSchemeColor(int);
+ method public void setProgressBackgroundColorSchemeResource(int);
+ method public void setProgressViewEndTarget(boolean, int);
+ method public void setProgressViewOffset(boolean, int, int);
+ method public void setRefreshing(boolean);
+ method public void setSize(int);
+ field public static final int DEFAULT = 1; // 0x1
+ field public static final int LARGE = 0; // 0x0
+ field protected int mFrom;
+ field protected int mOriginalOffsetTop;
+ }
+
+ public static abstract interface SwipeRefreshLayout.OnChildScrollUpCallback {
+ method public abstract boolean canChildScrollUp(android.support.v4.widget.SwipeRefreshLayout, android.view.View);
+ }
+
+ public static abstract interface SwipeRefreshLayout.OnRefreshListener {
+ method public abstract void onRefresh();
+ }
+
+ public final class TextViewCompat {
+ method public static android.graphics.drawable.Drawable[] getCompoundDrawablesRelative(android.widget.TextView);
+ method public static int getMaxLines(android.widget.TextView);
+ method public static int getMinLines(android.widget.TextView);
+ method public static void setCompoundDrawablesRelative(android.widget.TextView, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
+ method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
+ method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, int, int, int, int);
+ method public static void setTextAppearance(android.widget.TextView, int);
+ }
+
+ public abstract interface TintableCompoundButton {
+ method public abstract android.content.res.ColorStateList getSupportButtonTintList();
+ method public abstract android.graphics.PorterDuff.Mode getSupportButtonTintMode();
+ method public abstract void setSupportButtonTintList(android.content.res.ColorStateList);
+ method public abstract void setSupportButtonTintMode(android.graphics.PorterDuff.Mode);
+ }
+
+ public class ViewDragHelper {
+ method public void abort();
+ method protected boolean canScroll(android.view.View, boolean, int, int, int, int);
+ method public void cancel();
+ method public void captureChildView(android.view.View, int);
+ method public boolean checkTouchSlop(int);
+ method public boolean checkTouchSlop(int, int);
+ method public boolean continueSettling(boolean);
+ method public static android.support.v4.widget.ViewDragHelper create(android.view.ViewGroup, android.support.v4.widget.ViewDragHelper.Callback);
+ method public static android.support.v4.widget.ViewDragHelper create(android.view.ViewGroup, float, android.support.v4.widget.ViewDragHelper.Callback);
+ method public android.view.View findTopChildUnder(int, int);
+ method public void flingCapturedView(int, int, int, int);
+ method public int getActivePointerId();
+ method public android.view.View getCapturedView();
+ method public int getEdgeSize();
+ method public float getMinVelocity();
+ method public int getTouchSlop();
+ method public int getViewDragState();
+ method public boolean isCapturedViewUnder(int, int);
+ method public boolean isEdgeTouched(int);
+ method public boolean isEdgeTouched(int, int);
+ method public boolean isPointerDown(int);
+ method public boolean isViewUnder(android.view.View, int, int);
+ method public void processTouchEvent(android.view.MotionEvent);
+ method public void setEdgeTrackingEnabled(int);
+ method public void setMinVelocity(float);
+ method public boolean settleCapturedViewAt(int, int);
+ method public boolean shouldInterceptTouchEvent(android.view.MotionEvent);
+ method public boolean smoothSlideViewTo(android.view.View, int, int);
+ field public static final int DIRECTION_ALL = 3; // 0x3
+ field public static final int DIRECTION_HORIZONTAL = 1; // 0x1
+ field public static final int DIRECTION_VERTICAL = 2; // 0x2
+ field public static final int EDGE_ALL = 15; // 0xf
+ field public static final int EDGE_BOTTOM = 8; // 0x8
+ field public static final int EDGE_LEFT = 1; // 0x1
+ field public static final int EDGE_RIGHT = 2; // 0x2
+ field public static final int EDGE_TOP = 4; // 0x4
+ field public static final int INVALID_POINTER = -1; // 0xffffffff
+ field public static final int STATE_DRAGGING = 1; // 0x1
+ field public static final int STATE_IDLE = 0; // 0x0
+ field public static final int STATE_SETTLING = 2; // 0x2
+ }
+
+ public static abstract class ViewDragHelper.Callback {
+ ctor public ViewDragHelper.Callback();
+ method public int clampViewPositionHorizontal(android.view.View, int, int);
+ method public int clampViewPositionVertical(android.view.View, int, int);
+ method public int getOrderedChildIndex(int);
+ method public int getViewHorizontalDragRange(android.view.View);
+ method public int getViewVerticalDragRange(android.view.View);
+ method public void onEdgeDragStarted(int, int);
+ method public boolean onEdgeLock(int);
+ method public void onEdgeTouched(int, int);
+ method public void onViewCaptured(android.view.View, int);
+ method public void onViewDragStateChanged(int);
+ method public void onViewPositionChanged(android.view.View, int, int, int, int);
+ method public void onViewReleased(android.view.View, float, float);
+ method public abstract boolean tryCaptureView(android.view.View, int);
+ }
+
+}
+
+package android.support.v7.app {
+
+ public abstract class ActionBar {
+ ctor public ActionBar();
+ method public abstract void addOnMenuVisibilityListener(android.support.v7.app.ActionBar.OnMenuVisibilityListener);
+ method public abstract deprecated void addTab(android.support.v7.app.ActionBar.Tab);
+ method public abstract deprecated void addTab(android.support.v7.app.ActionBar.Tab, boolean);
+ method public abstract deprecated void addTab(android.support.v7.app.ActionBar.Tab, int);
+ method public abstract deprecated void addTab(android.support.v7.app.ActionBar.Tab, int, boolean);
+ method public abstract android.view.View getCustomView();
+ method public abstract int getDisplayOptions();
+ method public float getElevation();
+ method public abstract int getHeight();
+ method public int getHideOffset();
+ method public abstract deprecated int getNavigationItemCount();
+ method public abstract deprecated int getNavigationMode();
+ method public abstract deprecated int getSelectedNavigationIndex();
+ method public abstract deprecated android.support.v7.app.ActionBar.Tab getSelectedTab();
+ method public abstract java.lang.CharSequence getSubtitle();
+ method public abstract deprecated android.support.v7.app.ActionBar.Tab getTabAt(int);
+ method public abstract deprecated int getTabCount();
+ method public android.content.Context getThemedContext();
+ method public abstract java.lang.CharSequence getTitle();
+ method public abstract void hide();
+ method public boolean isHideOnContentScrollEnabled();
+ method public abstract boolean isShowing();
+ method public abstract deprecated android.support.v7.app.ActionBar.Tab newTab();
+ method public abstract deprecated void removeAllTabs();
+ method public abstract void removeOnMenuVisibilityListener(android.support.v7.app.ActionBar.OnMenuVisibilityListener);
+ method public abstract deprecated void removeTab(android.support.v7.app.ActionBar.Tab);
+ method public abstract deprecated void removeTabAt(int);
+ method public abstract deprecated void selectTab(android.support.v7.app.ActionBar.Tab);
+ method public abstract void setBackgroundDrawable(android.graphics.drawable.Drawable);
+ method public abstract void setCustomView(android.view.View);
+ method public abstract void setCustomView(android.view.View, android.support.v7.app.ActionBar.LayoutParams);
+ method public abstract void setCustomView(int);
+ method public abstract void setDisplayHomeAsUpEnabled(boolean);
+ method public abstract void setDisplayOptions(int);
+ method public abstract void setDisplayOptions(int, int);
+ method public abstract void setDisplayShowCustomEnabled(boolean);
+ method public abstract void setDisplayShowHomeEnabled(boolean);
+ method public abstract void setDisplayShowTitleEnabled(boolean);
+ method public abstract void setDisplayUseLogoEnabled(boolean);
+ method public void setElevation(float);
+ method public void setHideOffset(int);
+ method public void setHideOnContentScrollEnabled(boolean);
+ method public void setHomeActionContentDescription(java.lang.CharSequence);
+ method public void setHomeActionContentDescription(int);
+ method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable);
+ method public void setHomeAsUpIndicator(int);
+ method public void setHomeButtonEnabled(boolean);
+ method public abstract void setIcon(int);
+ method public abstract void setIcon(android.graphics.drawable.Drawable);
+ method public abstract deprecated void setListNavigationCallbacks(android.widget.SpinnerAdapter, android.support.v7.app.ActionBar.OnNavigationListener);
+ method public abstract void setLogo(int);
+ method public abstract void setLogo(android.graphics.drawable.Drawable);
+ method public abstract deprecated void setNavigationMode(int);
+ method public abstract deprecated void setSelectedNavigationItem(int);
+ method public void setSplitBackgroundDrawable(android.graphics.drawable.Drawable);
+ method public void setStackedBackgroundDrawable(android.graphics.drawable.Drawable);
+ method public abstract void setSubtitle(java.lang.CharSequence);
+ method public abstract void setSubtitle(int);
+ method public abstract void setTitle(java.lang.CharSequence);
+ method public abstract void setTitle(int);
+ method public abstract void show();
+ field public static final int DISPLAY_HOME_AS_UP = 4; // 0x4
+ field public static final int DISPLAY_SHOW_CUSTOM = 16; // 0x10
+ field public static final int DISPLAY_SHOW_HOME = 2; // 0x2
+ field public static final int DISPLAY_SHOW_TITLE = 8; // 0x8
+ field public static final int DISPLAY_USE_LOGO = 1; // 0x1
+ field public static final deprecated int NAVIGATION_MODE_LIST = 1; // 0x1
+ field public static final deprecated int NAVIGATION_MODE_STANDARD = 0; // 0x0
+ field public static final deprecated int NAVIGATION_MODE_TABS = 2; // 0x2
+ }
+
+ public static class ActionBar.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+ ctor public ActionBar.LayoutParams(android.content.Context, android.util.AttributeSet);
+ ctor public ActionBar.LayoutParams(int, int);
+ ctor public ActionBar.LayoutParams(int, int, int);
+ ctor public ActionBar.LayoutParams(int);
+ ctor public ActionBar.LayoutParams(android.support.v7.app.ActionBar.LayoutParams);
+ ctor public ActionBar.LayoutParams(android.view.ViewGroup.LayoutParams);
+ field public int gravity;
+ }
+
+ public static abstract interface ActionBar.OnMenuVisibilityListener {
+ method public abstract void onMenuVisibilityChanged(boolean);
+ }
+
+ public static abstract deprecated interface ActionBar.OnNavigationListener {
+ method public abstract boolean onNavigationItemSelected(int, long);
+ }
+
+ public static abstract deprecated class ActionBar.Tab {
+ ctor public ActionBar.Tab();
+ method public abstract java.lang.CharSequence getContentDescription();
+ method public abstract android.view.View getCustomView();
+ method public abstract android.graphics.drawable.Drawable getIcon();
+ method public abstract int getPosition();
+ method public abstract java.lang.Object getTag();
+ method public abstract java.lang.CharSequence getText();
+ method public abstract void select();
+ method public abstract android.support.v7.app.ActionBar.Tab setContentDescription(int);
+ method public abstract android.support.v7.app.ActionBar.Tab setContentDescription(java.lang.CharSequence);
+ method public abstract android.support.v7.app.ActionBar.Tab setCustomView(android.view.View);
+ method public abstract android.support.v7.app.ActionBar.Tab setCustomView(int);
+ method public abstract android.support.v7.app.ActionBar.Tab setIcon(android.graphics.drawable.Drawable);
+ method public abstract android.support.v7.app.ActionBar.Tab setIcon(int);
+ method public abstract android.support.v7.app.ActionBar.Tab setTabListener(android.support.v7.app.ActionBar.TabListener);
+ method public abstract android.support.v7.app.ActionBar.Tab setTag(java.lang.Object);
+ method public abstract android.support.v7.app.ActionBar.Tab setText(java.lang.CharSequence);
+ method public abstract android.support.v7.app.ActionBar.Tab setText(int);
+ field public static final int INVALID_POSITION = -1; // 0xffffffff
+ }
+
+ public static abstract deprecated interface ActionBar.TabListener {
+ method public abstract void onTabReselected(android.support.v7.app.ActionBar.Tab, android.support.v4.app.FragmentTransaction);
+ method public abstract void onTabSelected(android.support.v7.app.ActionBar.Tab, android.support.v4.app.FragmentTransaction);
+ method public abstract void onTabUnselected(android.support.v7.app.ActionBar.Tab, android.support.v4.app.FragmentTransaction);
+ }
+
+ public deprecated class ActionBarActivity extends android.support.v7.app.AppCompatActivity {
+ ctor public ActionBarActivity();
+ }
+
+ public class ActionBarDrawerToggle implements android.support.v4.widget.DrawerLayout.DrawerListener {
+ ctor public ActionBarDrawerToggle(android.app.Activity, android.support.v4.widget.DrawerLayout, int, int);
+ ctor public ActionBarDrawerToggle(android.app.Activity, android.support.v4.widget.DrawerLayout, android.support.v7.widget.Toolbar, int, int);
+ method public android.support.v7.graphics.drawable.DrawerArrowDrawable getDrawerArrowDrawable();
+ method public android.view.View.OnClickListener getToolbarNavigationClickListener();
+ method public boolean isDrawerIndicatorEnabled();
+ method public void onConfigurationChanged(android.content.res.Configuration);
+ method public void onDrawerClosed(android.view.View);
+ method public void onDrawerOpened(android.view.View);
+ method public void onDrawerSlide(android.view.View, float);
+ method public void onDrawerStateChanged(int);
+ method public boolean onOptionsItemSelected(android.view.MenuItem);
+ method public void setDrawerArrowDrawable(android.support.v7.graphics.drawable.DrawerArrowDrawable);
+ method public void setDrawerIndicatorEnabled(boolean);
+ method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable);
+ method public void setHomeAsUpIndicator(int);
+ method public void setToolbarNavigationClickListener(android.view.View.OnClickListener);
+ method public void syncState();
+ }
+
+ public static abstract interface ActionBarDrawerToggle.Delegate {
+ method public abstract android.content.Context getActionBarThemedContext();
+ method public abstract android.graphics.drawable.Drawable getThemeUpIndicator();
+ method public abstract boolean isNavigationVisible();
+ method public abstract void setActionBarDescription(int);
+ method public abstract void setActionBarUpIndicator(android.graphics.drawable.Drawable, int);
+ }
+
+ public static abstract interface ActionBarDrawerToggle.DelegateProvider {
+ method public abstract android.support.v7.app.ActionBarDrawerToggle.Delegate getDrawerToggleDelegate();
+ }
+
+ public class AlertDialog extends android.support.v7.app.AppCompatDialog implements android.content.DialogInterface {
+ ctor protected AlertDialog(android.content.Context);
+ ctor protected AlertDialog(android.content.Context, int);
+ ctor protected AlertDialog(android.content.Context, boolean, android.content.DialogInterface.OnCancelListener);
+ method public android.widget.Button getButton(int);
+ method public android.widget.ListView getListView();
+ method public void setButton(int, java.lang.CharSequence, android.os.Message);
+ method public void setButton(int, java.lang.CharSequence, android.content.DialogInterface.OnClickListener);
+ method public void setCustomTitle(android.view.View);
+ method public void setIcon(int);
+ method public void setIcon(android.graphics.drawable.Drawable);
+ method public void setIconAttribute(int);
+ method public void setMessage(java.lang.CharSequence);
+ method public void setView(android.view.View);
+ method public void setView(android.view.View, int, int, int, int);
+ }
+
+ public static class AlertDialog.Builder {
+ ctor public AlertDialog.Builder(android.content.Context);
+ ctor public AlertDialog.Builder(android.content.Context, int);
+ method public android.support.v7.app.AlertDialog create();
+ method public android.content.Context getContext();
+ method public android.support.v7.app.AlertDialog.Builder setAdapter(android.widget.ListAdapter, android.content.DialogInterface.OnClickListener);
+ method public android.support.v7.app.AlertDialog.Builder setCancelable(boolean);
+ method public android.support.v7.app.AlertDialog.Builder setCursor(android.database.Cursor, android.content.DialogInterface.OnClickListener, java.lang.String);
+ method public android.support.v7.app.AlertDialog.Builder setCustomTitle(android.view.View);
+ method public android.support.v7.app.AlertDialog.Builder setIcon(int);
+ method public android.support.v7.app.AlertDialog.Builder setIcon(android.graphics.drawable.Drawable);
+ method public android.support.v7.app.AlertDialog.Builder setIconAttribute(int);
+ method public deprecated android.support.v7.app.AlertDialog.Builder setInverseBackgroundForced(boolean);
+ method public android.support.v7.app.AlertDialog.Builder setItems(int, android.content.DialogInterface.OnClickListener);
+ method public android.support.v7.app.AlertDialog.Builder setItems(java.lang.CharSequence[], android.content.DialogInterface.OnClickListener);
+ method public android.support.v7.app.AlertDialog.Builder setMessage(int);
+ method public android.support.v7.app.AlertDialog.Builder setMessage(java.lang.CharSequence);
+ method public android.support.v7.app.AlertDialog.Builder setMultiChoiceItems(int, boolean[], android.content.DialogInterface.OnMultiChoiceClickListener);
+ method public android.support.v7.app.AlertDialog.Builder setMultiChoiceItems(java.lang.CharSequence[], boolean[], android.content.DialogInterface.OnMultiChoiceClickListener);
+ method public android.support.v7.app.AlertDialog.Builder setMultiChoiceItems(android.database.Cursor, java.lang.String, java.lang.String, android.content.DialogInterface.OnMultiChoiceClickListener);
+ method public android.support.v7.app.AlertDialog.Builder setNegativeButton(int, android.content.DialogInterface.OnClickListener);
+ method public android.support.v7.app.AlertDialog.Builder setNegativeButton(java.lang.CharSequence, android.content.DialogInterface.OnClickListener);
+ method public android.support.v7.app.AlertDialog.Builder setNeutralButton(int, android.content.DialogInterface.OnClickListener);
+ method public android.support.v7.app.AlertDialog.Builder setNeutralButton(java.lang.CharSequence, android.content.DialogInterface.OnClickListener);
+ method public android.support.v7.app.AlertDialog.Builder setOnCancelListener(android.content.DialogInterface.OnCancelListener);
+ method public android.support.v7.app.AlertDialog.Builder setOnDismissListener(android.content.DialogInterface.OnDismissListener);
+ method public android.support.v7.app.AlertDialog.Builder setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener);
+ method public android.support.v7.app.AlertDialog.Builder setOnKeyListener(android.content.DialogInterface.OnKeyListener);
+ method public android.support.v7.app.AlertDialog.Builder setPositiveButton(int, android.content.DialogInterface.OnClickListener);
+ method public android.support.v7.app.AlertDialog.Builder setPositiveButton(java.lang.CharSequence, android.content.DialogInterface.OnClickListener);
+ method public android.support.v7.app.AlertDialog.Builder setSingleChoiceItems(int, int, android.content.DialogInterface.OnClickListener);
+ method public android.support.v7.app.AlertDialog.Builder setSingleChoiceItems(android.database.Cursor, int, java.lang.String, android.content.DialogInterface.OnClickListener);
+ method public android.support.v7.app.AlertDialog.Builder setSingleChoiceItems(java.lang.CharSequence[], int, android.content.DialogInterface.OnClickListener);
+ method public android.support.v7.app.AlertDialog.Builder setSingleChoiceItems(android.widget.ListAdapter, int, android.content.DialogInterface.OnClickListener);
+ method public android.support.v7.app.AlertDialog.Builder setTitle(int);
+ method public android.support.v7.app.AlertDialog.Builder setTitle(java.lang.CharSequence);
+ method public android.support.v7.app.AlertDialog.Builder setView(int);
+ method public android.support.v7.app.AlertDialog.Builder setView(android.view.View);
+ method public android.support.v7.app.AlertDialog show();
+ }
+
+ public class AppCompatActivity extends android.support.v4.app.FragmentActivity implements android.support.v7.app.ActionBarDrawerToggle.DelegateProvider android.support.v7.app.AppCompatCallback android.support.v4.app.TaskStackBuilder.SupportParentable {
+ ctor public AppCompatActivity();
+ method public android.support.v7.app.AppCompatDelegate getDelegate();
+ method public android.support.v7.app.ActionBarDrawerToggle.Delegate getDrawerToggleDelegate();
+ method public android.support.v7.app.ActionBar getSupportActionBar();
+ method public android.content.Intent getSupportParentActivityIntent();
+ method public void onCreateSupportNavigateUpTaskStack(android.support.v4.app.TaskStackBuilder);
+ method public final boolean onMenuItemSelected(int, android.view.MenuItem);
+ method public void onPrepareSupportNavigateUpTaskStack(android.support.v4.app.TaskStackBuilder);
+ method public void onSupportActionModeFinished(android.support.v7.view.ActionMode);
+ method public void onSupportActionModeStarted(android.support.v7.view.ActionMode);
+ method public deprecated void onSupportContentChanged();
+ method public boolean onSupportNavigateUp();
+ method public android.support.v7.view.ActionMode onWindowStartingSupportActionMode(android.support.v7.view.ActionMode.Callback);
+ method public void setSupportActionBar(android.support.v7.widget.Toolbar);
+ method public deprecated void setSupportProgress(int);
+ method public deprecated void setSupportProgressBarIndeterminate(boolean);
+ method public deprecated void setSupportProgressBarIndeterminateVisibility(boolean);
+ method public deprecated void setSupportProgressBarVisibility(boolean);
+ method public android.support.v7.view.ActionMode startSupportActionMode(android.support.v7.view.ActionMode.Callback);
+ method public void supportNavigateUpTo(android.content.Intent);
+ method public boolean supportRequestWindowFeature(int);
+ method public boolean supportShouldUpRecreateTask(android.content.Intent);
+ }
+
+ public abstract interface AppCompatCallback {
+ method public abstract void onSupportActionModeFinished(android.support.v7.view.ActionMode);
+ method public abstract void onSupportActionModeStarted(android.support.v7.view.ActionMode);
+ method public abstract android.support.v7.view.ActionMode onWindowStartingSupportActionMode(android.support.v7.view.ActionMode.Callback);
+ }
+
+ public abstract class AppCompatDelegate {
+ method public abstract void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
+ method public abstract boolean applyDayNight();
+ method public static android.support.v7.app.AppCompatDelegate create(android.app.Activity, android.support.v7.app.AppCompatCallback);
+ method public static android.support.v7.app.AppCompatDelegate create(android.app.Dialog, android.support.v7.app.AppCompatCallback);
+ method public abstract android.view.View createView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet);
+ method public abstract android.view.View findViewById(int);
+ method public static int getDefaultNightMode();
+ method public abstract android.support.v7.app.ActionBarDrawerToggle.Delegate getDrawerToggleDelegate();
+ method public abstract android.view.MenuInflater getMenuInflater();
+ method public abstract android.support.v7.app.ActionBar getSupportActionBar();
+ method public abstract boolean hasWindowFeature(int);
+ method public abstract void installViewFactory();
+ method public abstract void invalidateOptionsMenu();
+ method public static boolean isCompatVectorFromResourcesEnabled();
+ method public abstract boolean isHandleNativeActionModesEnabled();
+ method public abstract void onConfigurationChanged(android.content.res.Configuration);
+ method public abstract void onCreate(android.os.Bundle);
+ method public abstract void onDestroy();
+ method public abstract void onPostCreate(android.os.Bundle);
+ method public abstract void onPostResume();
+ method public abstract void onSaveInstanceState(android.os.Bundle);
+ method public abstract void onStart();
+ method public abstract void onStop();
+ method public abstract boolean requestWindowFeature(int);
+ method public static void setCompatVectorFromResourcesEnabled(boolean);
+ method public abstract void setContentView(android.view.View);
+ method public abstract void setContentView(int);
+ method public abstract void setContentView(android.view.View, android.view.ViewGroup.LayoutParams);
+ method public static void setDefaultNightMode(int);
+ method public abstract void setHandleNativeActionModesEnabled(boolean);
+ method public abstract void setLocalNightMode(int);
+ method public abstract void setSupportActionBar(android.support.v7.widget.Toolbar);
+ method public abstract void setTitle(java.lang.CharSequence);
+ method public abstract android.support.v7.view.ActionMode startSupportActionMode(android.support.v7.view.ActionMode.Callback);
+ field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+ field public static final int FEATURE_SUPPORT_ACTION_BAR = 108; // 0x6c
+ field public static final int FEATURE_SUPPORT_ACTION_BAR_OVERLAY = 109; // 0x6d
+ field public static final int MODE_NIGHT_AUTO = 0; // 0x0
+ field public static final int MODE_NIGHT_FOLLOW_SYSTEM = -1; // 0xffffffff
+ field public static final int MODE_NIGHT_NO = 1; // 0x1
+ field public static final int MODE_NIGHT_YES = 2; // 0x2
+ }
+
+ public class AppCompatDialog extends android.app.Dialog implements android.support.v7.app.AppCompatCallback {
+ ctor public AppCompatDialog(android.content.Context);
+ ctor public AppCompatDialog(android.content.Context, int);
+ ctor protected AppCompatDialog(android.content.Context, boolean, android.content.DialogInterface.OnCancelListener);
+ method public android.support.v7.app.AppCompatDelegate getDelegate();
+ method public android.support.v7.app.ActionBar getSupportActionBar();
+ method public void onSupportActionModeFinished(android.support.v7.view.ActionMode);
+ method public void onSupportActionModeStarted(android.support.v7.view.ActionMode);
+ method public android.support.v7.view.ActionMode onWindowStartingSupportActionMode(android.support.v7.view.ActionMode.Callback);
+ method public boolean supportRequestWindowFeature(int);
+ }
+
+ public class AppCompatDialogFragment extends android.support.v4.app.DialogFragment {
+ ctor public AppCompatDialogFragment();
+ }
+
+ public class MediaRouteActionProvider extends android.support.v4.view.ActionProvider {
+ ctor public MediaRouteActionProvider(android.content.Context);
+ method public android.support.v7.app.MediaRouteDialogFactory getDialogFactory();
+ method public android.support.v7.app.MediaRouteButton getMediaRouteButton();
+ method public android.support.v7.media.MediaRouteSelector getRouteSelector();
+ method public android.view.View onCreateActionView();
+ method public android.support.v7.app.MediaRouteButton onCreateMediaRouteButton();
+ method public void setDialogFactory(android.support.v7.app.MediaRouteDialogFactory);
+ method public void setRouteSelector(android.support.v7.media.MediaRouteSelector);
+ }
+
+ public class MediaRouteButton extends android.view.View {
+ ctor public MediaRouteButton(android.content.Context);
+ ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet);
+ ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet, int);
+ method public android.support.v7.app.MediaRouteDialogFactory getDialogFactory();
+ method public android.support.v7.media.MediaRouteSelector getRouteSelector();
+ method public void onAttachedToWindow();
+ method public void onDetachedFromWindow();
+ method public void setDialogFactory(android.support.v7.app.MediaRouteDialogFactory);
+ method public void setRemoteIndicatorDrawable(android.graphics.drawable.Drawable);
+ method public void setRouteSelector(android.support.v7.media.MediaRouteSelector);
+ method public boolean showDialog();
+ }
+
+ public class MediaRouteChooserDialog extends android.support.v7.app.AppCompatDialog {
+ ctor public MediaRouteChooserDialog(android.content.Context);
+ ctor public MediaRouteChooserDialog(android.content.Context, int);
+ method public android.support.v7.media.MediaRouteSelector getRouteSelector();
+ method public boolean onFilterRoute(android.support.v7.media.MediaRouter.RouteInfo);
+ method public void onFilterRoutes(java.util.List<android.support.v7.media.MediaRouter.RouteInfo>);
+ method public void refreshRoutes();
+ method public void setRouteSelector(android.support.v7.media.MediaRouteSelector);
+ }
+
+ public class MediaRouteChooserDialogFragment extends android.support.v4.app.DialogFragment {
+ ctor public MediaRouteChooserDialogFragment();
+ method public android.support.v7.media.MediaRouteSelector getRouteSelector();
+ method public android.support.v7.app.MediaRouteChooserDialog onCreateChooserDialog(android.content.Context, android.os.Bundle);
+ method public void setRouteSelector(android.support.v7.media.MediaRouteSelector);
+ }
+
+ public class MediaRouteControllerDialog extends android.support.v7.app.AlertDialog {
+ ctor public MediaRouteControllerDialog(android.content.Context);
+ ctor public MediaRouteControllerDialog(android.content.Context, int);
+ method public android.view.View getMediaControlView();
+ method public android.support.v4.media.session.MediaSessionCompat.Token getMediaSession();
+ method public android.support.v7.media.MediaRouter.RouteInfo getRoute();
+ method public boolean isVolumeControlEnabled();
+ method public android.view.View onCreateMediaControlView(android.os.Bundle);
+ method public void setVolumeControlEnabled(boolean);
+ }
+
+ public class MediaRouteControllerDialogFragment extends android.support.v4.app.DialogFragment {
+ ctor public MediaRouteControllerDialogFragment();
+ method public android.support.v7.app.MediaRouteControllerDialog onCreateControllerDialog(android.content.Context, android.os.Bundle);
+ }
+
+ public class MediaRouteDialogFactory {
+ ctor public MediaRouteDialogFactory();
+ method public static android.support.v7.app.MediaRouteDialogFactory getDefault();
+ method public android.support.v7.app.MediaRouteChooserDialogFragment onCreateChooserDialogFragment();
+ method public android.support.v7.app.MediaRouteControllerDialogFragment onCreateControllerDialogFragment();
+ }
+
+ public class MediaRouteDiscoveryFragment extends android.support.v4.app.Fragment {
+ ctor public MediaRouteDiscoveryFragment();
+ method public android.support.v7.media.MediaRouter getMediaRouter();
+ method public android.support.v7.media.MediaRouteSelector getRouteSelector();
+ method public android.support.v7.media.MediaRouter.Callback onCreateCallback();
+ method public int onPrepareCallbackFlags();
+ method public void setRouteSelector(android.support.v7.media.MediaRouteSelector);
+ }
+
+ public class NotificationCompat extends android.support.v4.app.NotificationCompat {
+ ctor public NotificationCompat();
+ method public static android.support.v4.media.session.MediaSessionCompat.Token getMediaSession(android.app.Notification);
+ }
+
+ public static class NotificationCompat.Builder extends android.support.v4.app.NotificationCompat.Builder {
+ ctor public NotificationCompat.Builder(android.content.Context);
+ }
+
+ public static class NotificationCompat.DecoratedCustomViewStyle extends android.support.v4.app.NotificationCompat.Style {
+ ctor public NotificationCompat.DecoratedCustomViewStyle();
+ }
+
+ public static class NotificationCompat.DecoratedMediaCustomViewStyle extends android.support.v7.app.NotificationCompat.MediaStyle {
+ ctor public NotificationCompat.DecoratedMediaCustomViewStyle();
+ }
+
+ public static class NotificationCompat.MediaStyle extends android.support.v4.app.NotificationCompat.Style {
+ ctor public NotificationCompat.MediaStyle();
+ ctor public NotificationCompat.MediaStyle(android.support.v4.app.NotificationCompat.Builder);
+ method public android.support.v7.app.NotificationCompat.MediaStyle setCancelButtonIntent(android.app.PendingIntent);
+ method public android.support.v7.app.NotificationCompat.MediaStyle setMediaSession(android.support.v4.media.session.MediaSessionCompat.Token);
+ method public android.support.v7.app.NotificationCompat.MediaStyle setShowActionsInCompactView(int...);
+ method public android.support.v7.app.NotificationCompat.MediaStyle setShowCancelButton(boolean);
+ }
+
+}
+
+package android.support.v7.content.res {
+
+ public final class AppCompatResources {
+ method public static android.content.res.ColorStateList getColorStateList(android.content.Context, int);
+ method public static android.graphics.drawable.Drawable getDrawable(android.content.Context, int);
+ }
+
+}
+
+package android.support.v7.graphics {
+
+ public final class Palette {
+ method public static android.support.v7.graphics.Palette.Builder from(android.graphics.Bitmap);
+ method public static android.support.v7.graphics.Palette from(java.util.List<android.support.v7.graphics.Palette.Swatch>);
+ method public static deprecated android.support.v7.graphics.Palette generate(android.graphics.Bitmap);
+ method public static deprecated android.support.v7.graphics.Palette generate(android.graphics.Bitmap, int);
+ method public static deprecated android.os.AsyncTask<android.graphics.Bitmap, java.lang.Void, android.support.v7.graphics.Palette> generateAsync(android.graphics.Bitmap, android.support.v7.graphics.Palette.PaletteAsyncListener);
+ method public static deprecated android.os.AsyncTask<android.graphics.Bitmap, java.lang.Void, android.support.v7.graphics.Palette> generateAsync(android.graphics.Bitmap, int, android.support.v7.graphics.Palette.PaletteAsyncListener);
+ method public int getColorForTarget(android.support.v7.graphics.Target, int);
+ method public int getDarkMutedColor(int);
+ method public android.support.v7.graphics.Palette.Swatch getDarkMutedSwatch();
+ method public int getDarkVibrantColor(int);
+ method public android.support.v7.graphics.Palette.Swatch getDarkVibrantSwatch();
+ method public int getDominantColor(int);
+ method public android.support.v7.graphics.Palette.Swatch getDominantSwatch();
+ method public int getLightMutedColor(int);
+ method public android.support.v7.graphics.Palette.Swatch getLightMutedSwatch();
+ method public int getLightVibrantColor(int);
+ method public android.support.v7.graphics.Palette.Swatch getLightVibrantSwatch();
+ method public int getMutedColor(int);
+ method public android.support.v7.graphics.Palette.Swatch getMutedSwatch();
+ method public android.support.v7.graphics.Palette.Swatch getSwatchForTarget(android.support.v7.graphics.Target);
+ method public java.util.List<android.support.v7.graphics.Palette.Swatch> getSwatches();
+ method public java.util.List<android.support.v7.graphics.Target> getTargets();
+ method public int getVibrantColor(int);
+ method public android.support.v7.graphics.Palette.Swatch getVibrantSwatch();
+ }
+
+ public static final class Palette.Builder {
+ ctor public Palette.Builder(android.graphics.Bitmap);
+ ctor public Palette.Builder(java.util.List<android.support.v7.graphics.Palette.Swatch>);
+ method public android.support.v7.graphics.Palette.Builder addFilter(android.support.v7.graphics.Palette.Filter);
+ method public android.support.v7.graphics.Palette.Builder addTarget(android.support.v7.graphics.Target);
+ method public android.support.v7.graphics.Palette.Builder clearFilters();
+ method public android.support.v7.graphics.Palette.Builder clearRegion();
+ method public android.support.v7.graphics.Palette.Builder clearTargets();
+ method public android.support.v7.graphics.Palette generate();
+ method public android.os.AsyncTask<android.graphics.Bitmap, java.lang.Void, android.support.v7.graphics.Palette> generate(android.support.v7.graphics.Palette.PaletteAsyncListener);
+ method public android.support.v7.graphics.Palette.Builder maximumColorCount(int);
+ method public android.support.v7.graphics.Palette.Builder resizeBitmapArea(int);
+ method public deprecated android.support.v7.graphics.Palette.Builder resizeBitmapSize(int);
+ method public android.support.v7.graphics.Palette.Builder setRegion(int, int, int, int);
+ }
+
+ public static abstract interface Palette.Filter {
+ method public abstract boolean isAllowed(int, float[]);
+ }
+
+ public static abstract interface Palette.PaletteAsyncListener {
+ method public abstract void onGenerated(android.support.v7.graphics.Palette);
+ }
+
+ public static final class Palette.Swatch {
+ ctor public Palette.Swatch(int, int);
+ method public int getBodyTextColor();
+ method public float[] getHsl();
+ method public int getPopulation();
+ method public int getRgb();
+ method public int getTitleTextColor();
+ }
+
+ public final class Target {
+ method public float getLightnessWeight();
+ method public float getMaximumLightness();
+ method public float getMaximumSaturation();
+ method public float getMinimumLightness();
+ method public float getMinimumSaturation();
+ method public float getPopulationWeight();
+ method public float getSaturationWeight();
+ method public float getTargetLightness();
+ method public float getTargetSaturation();
+ method public boolean isExclusive();
+ field public static final android.support.v7.graphics.Target DARK_MUTED;
+ field public static final android.support.v7.graphics.Target DARK_VIBRANT;
+ field public static final android.support.v7.graphics.Target LIGHT_MUTED;
+ field public static final android.support.v7.graphics.Target LIGHT_VIBRANT;
+ field public static final android.support.v7.graphics.Target MUTED;
+ field public static final android.support.v7.graphics.Target VIBRANT;
+ }
+
+ public static final class Target.Builder {
+ ctor public Target.Builder();
+ ctor public Target.Builder(android.support.v7.graphics.Target);
+ method public android.support.v7.graphics.Target build();
+ method public android.support.v7.graphics.Target.Builder setExclusive(boolean);
+ method public android.support.v7.graphics.Target.Builder setLightnessWeight(float);
+ method public android.support.v7.graphics.Target.Builder setMaximumLightness(float);
+ method public android.support.v7.graphics.Target.Builder setMaximumSaturation(float);
+ method public android.support.v7.graphics.Target.Builder setMinimumLightness(float);
+ method public android.support.v7.graphics.Target.Builder setMinimumSaturation(float);
+ method public android.support.v7.graphics.Target.Builder setPopulationWeight(float);
+ method public android.support.v7.graphics.Target.Builder setSaturationWeight(float);
+ method public android.support.v7.graphics.Target.Builder setTargetLightness(float);
+ method public android.support.v7.graphics.Target.Builder setTargetSaturation(float);
+ }
+
+}
+
+package android.support.v7.graphics.drawable {
+
+ public class DrawerArrowDrawable extends android.graphics.drawable.Drawable {
+ ctor public DrawerArrowDrawable(android.content.Context);
+ method public void draw(android.graphics.Canvas);
+ method public float getArrowHeadLength();
+ method public float getArrowShaftLength();
+ method public float getBarLength();
+ method public float getBarThickness();
+ method public int getColor();
+ method public int getDirection();
+ method public float getGapSize();
+ method public int getOpacity();
+ method public final android.graphics.Paint getPaint();
+ method public float getProgress();
+ method public boolean isSpinEnabled();
+ method public void setAlpha(int);
+ method public void setArrowHeadLength(float);
+ method public void setArrowShaftLength(float);
+ method public void setBarLength(float);
+ method public void setBarThickness(float);
+ method public void setColor(int);
+ method public void setColorFilter(android.graphics.ColorFilter);
+ method public void setDirection(int);
+ method public void setGapSize(float);
+ method public void setProgress(float);
+ method public void setSpinEnabled(boolean);
+ method public void setVerticalMirror(boolean);
+ field public static final int ARROW_DIRECTION_END = 3; // 0x3
+ field public static final int ARROW_DIRECTION_LEFT = 0; // 0x0
+ field public static final int ARROW_DIRECTION_RIGHT = 1; // 0x1
+ field public static final int ARROW_DIRECTION_START = 2; // 0x2
+ }
+
+}
+
+package android.support.v7.media {
+
+ public final class MediaControlIntent {
+ field public static final java.lang.String ACTION_END_SESSION = "android.media.intent.action.END_SESSION";
+ field public static final java.lang.String ACTION_ENQUEUE = "android.media.intent.action.ENQUEUE";
+ field public static final java.lang.String ACTION_GET_SESSION_STATUS = "android.media.intent.action.GET_SESSION_STATUS";
+ field public static final java.lang.String ACTION_GET_STATUS = "android.media.intent.action.GET_STATUS";
+ field public static final java.lang.String ACTION_PAUSE = "android.media.intent.action.PAUSE";
+ field public static final java.lang.String ACTION_PLAY = "android.media.intent.action.PLAY";
+ field public static final java.lang.String ACTION_REMOVE = "android.media.intent.action.REMOVE";
+ field public static final java.lang.String ACTION_RESUME = "android.media.intent.action.RESUME";
+ field public static final java.lang.String ACTION_SEEK = "android.media.intent.action.SEEK";
+ field public static final java.lang.String ACTION_SEND_MESSAGE = "android.media.intent.action.SEND_MESSAGE";
+ field public static final java.lang.String ACTION_START_SESSION = "android.media.intent.action.START_SESSION";
+ field public static final java.lang.String ACTION_STOP = "android.media.intent.action.STOP";
+ field public static final java.lang.String CATEGORY_LIVE_AUDIO = "android.media.intent.category.LIVE_AUDIO";
+ field public static final java.lang.String CATEGORY_LIVE_VIDEO = "android.media.intent.category.LIVE_VIDEO";
+ field public static final java.lang.String CATEGORY_REMOTE_PLAYBACK = "android.media.intent.category.REMOTE_PLAYBACK";
+ field public static final int ERROR_INVALID_ITEM_ID = 3; // 0x3
+ field public static final int ERROR_INVALID_SESSION_ID = 2; // 0x2
+ field public static final int ERROR_UNKNOWN = 0; // 0x0
+ field public static final int ERROR_UNSUPPORTED_OPERATION = 1; // 0x1
+ field public static final java.lang.String EXTRA_ERROR_CODE = "android.media.intent.extra.ERROR_CODE";
+ field public static final java.lang.String EXTRA_ITEM_CONTENT_POSITION = "android.media.intent.extra.ITEM_POSITION";
+ field public static final java.lang.String EXTRA_ITEM_HTTP_HEADERS = "android.media.intent.extra.HTTP_HEADERS";
+ field public static final java.lang.String EXTRA_ITEM_ID = "android.media.intent.extra.ITEM_ID";
+ field public static final java.lang.String EXTRA_ITEM_METADATA = "android.media.intent.extra.ITEM_METADATA";
+ field public static final java.lang.String EXTRA_ITEM_STATUS = "android.media.intent.extra.ITEM_STATUS";
+ field public static final java.lang.String EXTRA_ITEM_STATUS_UPDATE_RECEIVER = "android.media.intent.extra.ITEM_STATUS_UPDATE_RECEIVER";
+ field public static final java.lang.String EXTRA_MESSAGE = "android.media.intent.extra.MESSAGE";
+ field public static final java.lang.String EXTRA_MESSAGE_RECEIVER = "android.media.intent.extra.MESSAGE_RECEIVER";
+ field public static final java.lang.String EXTRA_SESSION_ID = "android.media.intent.extra.SESSION_ID";
+ field public static final java.lang.String EXTRA_SESSION_STATUS = "android.media.intent.extra.SESSION_STATUS";
+ field public static final java.lang.String EXTRA_SESSION_STATUS_UPDATE_RECEIVER = "android.media.intent.extra.SESSION_STATUS_UPDATE_RECEIVER";
+ }
+
+ public final class MediaItemMetadata {
+ field public static final java.lang.String KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST";
+ field public static final java.lang.String KEY_ALBUM_TITLE = "android.media.metadata.ALBUM_TITLE";
+ field public static final java.lang.String KEY_ARTIST = "android.media.metadata.ARTIST";
+ field public static final java.lang.String KEY_ARTWORK_URI = "android.media.metadata.ARTWORK_URI";
+ field public static final java.lang.String KEY_AUTHOR = "android.media.metadata.AUTHOR";
+ field public static final java.lang.String KEY_COMPOSER = "android.media.metadata.COMPOSER";
+ field public static final java.lang.String KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
+ field public static final java.lang.String KEY_DURATION = "android.media.metadata.DURATION";
+ field public static final java.lang.String KEY_TITLE = "android.media.metadata.TITLE";
+ field public static final java.lang.String KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER";
+ field public static final java.lang.String KEY_YEAR = "android.media.metadata.YEAR";
+ }
+
+ public final class MediaItemStatus {
+ method public android.os.Bundle asBundle();
+ method public static android.support.v7.media.MediaItemStatus fromBundle(android.os.Bundle);
+ method public long getContentDuration();
+ method public long getContentPosition();
+ method public android.os.Bundle getExtras();
+ method public int getPlaybackState();
+ method public long getTimestamp();
+ field public static final java.lang.String EXTRA_HTTP_RESPONSE_HEADERS = "android.media.status.extra.HTTP_RESPONSE_HEADERS";
+ field public static final java.lang.String EXTRA_HTTP_STATUS_CODE = "android.media.status.extra.HTTP_STATUS_CODE";
+ field public static final int PLAYBACK_STATE_BUFFERING = 3; // 0x3
+ field public static final int PLAYBACK_STATE_CANCELED = 5; // 0x5
+ field public static final int PLAYBACK_STATE_ERROR = 7; // 0x7
+ field public static final int PLAYBACK_STATE_FINISHED = 4; // 0x4
+ field public static final int PLAYBACK_STATE_INVALIDATED = 6; // 0x6
+ field public static final int PLAYBACK_STATE_PAUSED = 2; // 0x2
+ field public static final int PLAYBACK_STATE_PENDING = 0; // 0x0
+ field public static final int PLAYBACK_STATE_PLAYING = 1; // 0x1
+ }
+
+ public static final class MediaItemStatus.Builder {
+ ctor public MediaItemStatus.Builder(int);
+ ctor public MediaItemStatus.Builder(android.support.v7.media.MediaItemStatus);
+ method public android.support.v7.media.MediaItemStatus build();
+ method public android.support.v7.media.MediaItemStatus.Builder setContentDuration(long);
+ method public android.support.v7.media.MediaItemStatus.Builder setContentPosition(long);
+ method public android.support.v7.media.MediaItemStatus.Builder setExtras(android.os.Bundle);
+ method public android.support.v7.media.MediaItemStatus.Builder setPlaybackState(int);
+ method public android.support.v7.media.MediaItemStatus.Builder setTimestamp(long);
+ }
+
+ public final class MediaRouteDescriptor {
+ method public android.os.Bundle asBundle();
+ method public boolean canDisconnectAndKeepPlaying();
+ method public static android.support.v7.media.MediaRouteDescriptor fromBundle(android.os.Bundle);
+ method public int getConnectionState();
+ method public java.util.List<android.content.IntentFilter> getControlFilters();
+ method public java.lang.String getDescription();
+ method public int getDeviceType();
+ method public android.os.Bundle getExtras();
+ method public android.net.Uri getIconUri();
+ method public java.lang.String getId();
+ method public java.lang.String getName();
+ method public int getPlaybackStream();
+ method public int getPlaybackType();
+ method public int getPresentationDisplayId();
+ method public android.content.IntentSender getSettingsActivity();
+ method public int getVolume();
+ method public int getVolumeHandling();
+ method public int getVolumeMax();
+ method public deprecated boolean isConnecting();
+ method public boolean isEnabled();
+ method public boolean isValid();
+ }
+
+ public static final class MediaRouteDescriptor.Builder {
+ ctor public MediaRouteDescriptor.Builder(java.lang.String, java.lang.String);
+ ctor public MediaRouteDescriptor.Builder(android.support.v7.media.MediaRouteDescriptor);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder addControlFilter(android.content.IntentFilter);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder addControlFilters(java.util.Collection<android.content.IntentFilter>);
+ method public android.support.v7.media.MediaRouteDescriptor build();
+ method public android.support.v7.media.MediaRouteDescriptor.Builder setCanDisconnect(boolean);
+ method public deprecated android.support.v7.media.MediaRouteDescriptor.Builder setConnecting(boolean);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder setConnectionState(int);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder setDescription(java.lang.String);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder setDeviceType(int);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder setEnabled(boolean);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder setExtras(android.os.Bundle);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder setIconUri(android.net.Uri);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder setId(java.lang.String);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder setName(java.lang.String);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder setPlaybackStream(int);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder setPlaybackType(int);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder setPresentationDisplayId(int);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder setSettingsActivity(android.content.IntentSender);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder setVolume(int);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder setVolumeHandling(int);
+ method public android.support.v7.media.MediaRouteDescriptor.Builder setVolumeMax(int);
+ }
+
+ public final class MediaRouteDiscoveryRequest {
+ ctor public MediaRouteDiscoveryRequest(android.support.v7.media.MediaRouteSelector, boolean);
+ method public android.os.Bundle asBundle();
+ method public static android.support.v7.media.MediaRouteDiscoveryRequest fromBundle(android.os.Bundle);
+ method public android.support.v7.media.MediaRouteSelector getSelector();
+ method public boolean isActiveScan();
+ method public boolean isValid();
+ }
+
+ public abstract class MediaRouteProvider {
+ ctor public MediaRouteProvider(android.content.Context);
+ method public final android.content.Context getContext();
+ method public final android.support.v7.media.MediaRouteProviderDescriptor getDescriptor();
+ method public final android.support.v7.media.MediaRouteDiscoveryRequest getDiscoveryRequest();
+ method public final android.os.Handler getHandler();
+ method public final android.support.v7.media.MediaRouteProvider.ProviderMetadata getMetadata();
+ method public android.support.v7.media.MediaRouteProvider.RouteController onCreateRouteController(java.lang.String);
+ method public void onDiscoveryRequestChanged(android.support.v7.media.MediaRouteDiscoveryRequest);
+ method public final void setCallback(android.support.v7.media.MediaRouteProvider.Callback);
+ method public final void setDescriptor(android.support.v7.media.MediaRouteProviderDescriptor);
+ method public final void setDiscoveryRequest(android.support.v7.media.MediaRouteDiscoveryRequest);
+ }
+
+ public static abstract class MediaRouteProvider.Callback {
+ ctor public MediaRouteProvider.Callback();
+ method public void onDescriptorChanged(android.support.v7.media.MediaRouteProvider, android.support.v7.media.MediaRouteProviderDescriptor);
+ }
+
+ public static final class MediaRouteProvider.ProviderMetadata {
+ method public android.content.ComponentName getComponentName();
+ method public java.lang.String getPackageName();
+ }
+
+ public static abstract class MediaRouteProvider.RouteController {
+ ctor public MediaRouteProvider.RouteController();
+ method public boolean onControlRequest(android.content.Intent, android.support.v7.media.MediaRouter.ControlRequestCallback);
+ method public void onRelease();
+ method public void onSelect();
+ method public void onSetVolume(int);
+ method public void onUnselect();
+ method public void onUnselect(int);
+ method public void onUpdateVolume(int);
+ }
+
+ public final class MediaRouteProviderDescriptor {
+ method public android.os.Bundle asBundle();
+ method public static android.support.v7.media.MediaRouteProviderDescriptor fromBundle(android.os.Bundle);
+ method public java.util.List<android.support.v7.media.MediaRouteDescriptor> getRoutes();
+ method public boolean isValid();
+ }
+
+ public static final class MediaRouteProviderDescriptor.Builder {
+ ctor public MediaRouteProviderDescriptor.Builder();
+ ctor public MediaRouteProviderDescriptor.Builder(android.support.v7.media.MediaRouteProviderDescriptor);
+ method public android.support.v7.media.MediaRouteProviderDescriptor.Builder addRoute(android.support.v7.media.MediaRouteDescriptor);
+ method public android.support.v7.media.MediaRouteProviderDescriptor.Builder addRoutes(java.util.Collection<android.support.v7.media.MediaRouteDescriptor>);
+ method public android.support.v7.media.MediaRouteProviderDescriptor build();
+ }
+
+ public abstract class MediaRouteProviderService extends android.app.Service {
+ ctor public MediaRouteProviderService();
+ method public android.support.v7.media.MediaRouteProvider getMediaRouteProvider();
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public abstract android.support.v7.media.MediaRouteProvider onCreateMediaRouteProvider();
+ field public static final java.lang.String SERVICE_INTERFACE = "android.media.MediaRouteProviderService";
+ }
+
+ public final class MediaRouteSelector {
+ method public android.os.Bundle asBundle();
+ method public boolean contains(android.support.v7.media.MediaRouteSelector);
+ method public static android.support.v7.media.MediaRouteSelector fromBundle(android.os.Bundle);
+ method public java.util.List<java.lang.String> getControlCategories();
+ method public boolean hasControlCategory(java.lang.String);
+ method public boolean isEmpty();
+ method public boolean isValid();
+ method public boolean matchesControlFilters(java.util.List<android.content.IntentFilter>);
+ field public static final android.support.v7.media.MediaRouteSelector EMPTY;
+ }
+
+ public static final class MediaRouteSelector.Builder {
+ ctor public MediaRouteSelector.Builder();
+ ctor public MediaRouteSelector.Builder(android.support.v7.media.MediaRouteSelector);
+ method public android.support.v7.media.MediaRouteSelector.Builder addControlCategories(java.util.Collection<java.lang.String>);
+ method public android.support.v7.media.MediaRouteSelector.Builder addControlCategory(java.lang.String);
+ method public android.support.v7.media.MediaRouteSelector.Builder addSelector(android.support.v7.media.MediaRouteSelector);
+ method public android.support.v7.media.MediaRouteSelector build();
+ }
+
+ public final class MediaRouter {
+ method public void addCallback(android.support.v7.media.MediaRouteSelector, android.support.v7.media.MediaRouter.Callback);
+ method public void addCallback(android.support.v7.media.MediaRouteSelector, android.support.v7.media.MediaRouter.Callback, int);
+ method public void addProvider(android.support.v7.media.MediaRouteProvider);
+ method public void addRemoteControlClient(java.lang.Object);
+ method public android.support.v7.media.MediaRouter.RouteInfo getBluetoothRoute();
+ method public android.support.v7.media.MediaRouter.RouteInfo getDefaultRoute();
+ method public static android.support.v7.media.MediaRouter getInstance(android.content.Context);
+ method public android.support.v4.media.session.MediaSessionCompat.Token getMediaSessionToken();
+ method public java.util.List<android.support.v7.media.MediaRouter.ProviderInfo> getProviders();
+ method public java.util.List<android.support.v7.media.MediaRouter.RouteInfo> getRoutes();
+ method public android.support.v7.media.MediaRouter.RouteInfo getSelectedRoute();
+ method public boolean isRouteAvailable(android.support.v7.media.MediaRouteSelector, int);
+ method public void removeCallback(android.support.v7.media.MediaRouter.Callback);
+ method public void removeProvider(android.support.v7.media.MediaRouteProvider);
+ method public void removeRemoteControlClient(java.lang.Object);
+ method public void selectRoute(android.support.v7.media.MediaRouter.RouteInfo);
+ method public void setMediaSession(java.lang.Object);
+ method public void setMediaSessionCompat(android.support.v4.media.session.MediaSessionCompat);
+ method public void unselect(int);
+ method public android.support.v7.media.MediaRouter.RouteInfo updateSelectedRoute(android.support.v7.media.MediaRouteSelector);
+ field public static final int AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE = 1; // 0x1
+ field public static final int AVAILABILITY_FLAG_REQUIRE_MATCH = 2; // 0x2
+ field public static final int CALLBACK_FLAG_FORCE_DISCOVERY = 8; // 0x8
+ field public static final int CALLBACK_FLAG_PERFORM_ACTIVE_SCAN = 1; // 0x1
+ field public static final int CALLBACK_FLAG_REQUEST_DISCOVERY = 4; // 0x4
+ field public static final int CALLBACK_FLAG_UNFILTERED_EVENTS = 2; // 0x2
+ field public static final int UNSELECT_REASON_DISCONNECTED = 1; // 0x1
+ field public static final int UNSELECT_REASON_ROUTE_CHANGED = 3; // 0x3
+ field public static final int UNSELECT_REASON_STOPPED = 2; // 0x2
+ field public static final int UNSELECT_REASON_UNKNOWN = 0; // 0x0
+ }
+
+ public static abstract class MediaRouter.Callback {
+ ctor public MediaRouter.Callback();
+ method public void onProviderAdded(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.ProviderInfo);
+ method public void onProviderChanged(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.ProviderInfo);
+ method public void onProviderRemoved(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.ProviderInfo);
+ method public void onRouteAdded(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.RouteInfo);
+ method public void onRouteChanged(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.RouteInfo);
+ method public void onRoutePresentationDisplayChanged(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.RouteInfo);
+ method public void onRouteRemoved(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.RouteInfo);
+ method public void onRouteSelected(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.RouteInfo);
+ method public void onRouteUnselected(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.RouteInfo);
+ method public void onRouteUnselected(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.RouteInfo, int);
+ method public void onRouteVolumeChanged(android.support.v7.media.MediaRouter, android.support.v7.media.MediaRouter.RouteInfo);
+ }
+
+ public static abstract class MediaRouter.ControlRequestCallback {
+ ctor public MediaRouter.ControlRequestCallback();
+ method public void onError(java.lang.String, android.os.Bundle);
+ method public void onResult(android.os.Bundle);
+ }
+
+ public static final class MediaRouter.ProviderInfo {
+ method public android.content.ComponentName getComponentName();
+ method public java.lang.String getPackageName();
+ method public android.support.v7.media.MediaRouteProvider getProviderInstance();
+ method public java.util.List<android.support.v7.media.MediaRouter.RouteInfo> getRoutes();
+ }
+
+ public static class MediaRouter.RouteInfo {
+ method public boolean canDisconnect();
+ method public int getConnectionState();
+ method public java.util.List<android.content.IntentFilter> getControlFilters();
+ method public java.lang.String getDescription();
+ method public int getDeviceType();
+ method public android.os.Bundle getExtras();
+ method public android.net.Uri getIconUri();
+ method public java.lang.String getId();
+ method public java.lang.String getName();
+ method public int getPlaybackStream();
+ method public int getPlaybackType();
+ method public android.view.Display getPresentationDisplay();
+ method public android.support.v7.media.MediaRouter.ProviderInfo getProvider();
+ method public android.content.IntentSender getSettingsIntent();
+ method public int getVolume();
+ method public int getVolumeHandling();
+ method public int getVolumeMax();
+ method public boolean isBluetooth();
+ method public boolean isConnecting();
+ method public boolean isDefault();
+ method public boolean isDeviceSpeaker();
+ method public boolean isEnabled();
+ method public boolean isSelected();
+ method public boolean matchesSelector(android.support.v7.media.MediaRouteSelector);
+ method public void requestSetVolume(int);
+ method public void requestUpdateVolume(int);
+ method public void select();
+ method public void sendControlRequest(android.content.Intent, android.support.v7.media.MediaRouter.ControlRequestCallback);
+ method public boolean supportsControlAction(java.lang.String, java.lang.String);
+ method public boolean supportsControlCategory(java.lang.String);
+ method public boolean supportsControlRequest(android.content.Intent);
+ field public static final int CONNECTION_STATE_CONNECTED = 2; // 0x2
+ field public static final int CONNECTION_STATE_CONNECTING = 1; // 0x1
+ field public static final int CONNECTION_STATE_DISCONNECTED = 0; // 0x0
+ field public static final int DEVICE_TYPE_SPEAKER = 2; // 0x2
+ field public static final int DEVICE_TYPE_TV = 1; // 0x1
+ field public static final int PLAYBACK_TYPE_LOCAL = 0; // 0x0
+ field public static final int PLAYBACK_TYPE_REMOTE = 1; // 0x1
+ field public static final int PLAYBACK_VOLUME_FIXED = 0; // 0x0
+ field public static final int PLAYBACK_VOLUME_VARIABLE = 1; // 0x1
+ }
+
+ public final class MediaSessionStatus {
+ method public android.os.Bundle asBundle();
+ method public static android.support.v7.media.MediaSessionStatus fromBundle(android.os.Bundle);
+ method public android.os.Bundle getExtras();
+ method public int getSessionState();
+ method public long getTimestamp();
+ method public boolean isQueuePaused();
+ field public static final int SESSION_STATE_ACTIVE = 0; // 0x0
+ field public static final int SESSION_STATE_ENDED = 1; // 0x1
+ field public static final int SESSION_STATE_INVALIDATED = 2; // 0x2
+ }
+
+ public static final class MediaSessionStatus.Builder {
+ ctor public MediaSessionStatus.Builder(int);
+ ctor public MediaSessionStatus.Builder(android.support.v7.media.MediaSessionStatus);
+ method public android.support.v7.media.MediaSessionStatus build();
+ method public android.support.v7.media.MediaSessionStatus.Builder setExtras(android.os.Bundle);
+ method public android.support.v7.media.MediaSessionStatus.Builder setQueuePaused(boolean);
+ method public android.support.v7.media.MediaSessionStatus.Builder setSessionState(int);
+ method public android.support.v7.media.MediaSessionStatus.Builder setTimestamp(long);
+ }
+
+ public class RemotePlaybackClient {
+ ctor public RemotePlaybackClient(android.content.Context, android.support.v7.media.MediaRouter.RouteInfo);
+ method public void endSession(android.os.Bundle, android.support.v7.media.RemotePlaybackClient.SessionActionCallback);
+ method public void enqueue(android.net.Uri, java.lang.String, android.os.Bundle, long, android.os.Bundle, android.support.v7.media.RemotePlaybackClient.ItemActionCallback);
+ method public java.lang.String getSessionId();
+ method public void getSessionStatus(android.os.Bundle, android.support.v7.media.RemotePlaybackClient.SessionActionCallback);
+ method public void getStatus(java.lang.String, android.os.Bundle, android.support.v7.media.RemotePlaybackClient.ItemActionCallback);
+ method public boolean hasSession();
+ method public boolean isMessagingSupported();
+ method public boolean isQueuingSupported();
+ method public boolean isRemotePlaybackSupported();
+ method public boolean isSessionManagementSupported();
+ method public void pause(android.os.Bundle, android.support.v7.media.RemotePlaybackClient.SessionActionCallback);
+ method public void play(android.net.Uri, java.lang.String, android.os.Bundle, long, android.os.Bundle, android.support.v7.media.RemotePlaybackClient.ItemActionCallback);
+ method public void release();
+ method public void remove(java.lang.String, android.os.Bundle, android.support.v7.media.RemotePlaybackClient.ItemActionCallback);
+ method public void resume(android.os.Bundle, android.support.v7.media.RemotePlaybackClient.SessionActionCallback);
+ method public void seek(java.lang.String, long, android.os.Bundle, android.support.v7.media.RemotePlaybackClient.ItemActionCallback);
+ method public void sendMessage(android.os.Bundle, android.support.v7.media.RemotePlaybackClient.SessionActionCallback);
+ method public void setOnMessageReceivedListener(android.support.v7.media.RemotePlaybackClient.OnMessageReceivedListener);
+ method public void setSessionId(java.lang.String);
+ method public void setStatusCallback(android.support.v7.media.RemotePlaybackClient.StatusCallback);
+ method public void startSession(android.os.Bundle, android.support.v7.media.RemotePlaybackClient.SessionActionCallback);
+ method public void stop(android.os.Bundle, android.support.v7.media.RemotePlaybackClient.SessionActionCallback);
+ }
+
+ public static abstract class RemotePlaybackClient.ActionCallback {
+ ctor public RemotePlaybackClient.ActionCallback();
+ method public void onError(java.lang.String, int, android.os.Bundle);
+ }
+
+ public static abstract class RemotePlaybackClient.ItemActionCallback extends android.support.v7.media.RemotePlaybackClient.ActionCallback {
+ ctor public RemotePlaybackClient.ItemActionCallback();
+ method public void onResult(android.os.Bundle, java.lang.String, android.support.v7.media.MediaSessionStatus, java.lang.String, android.support.v7.media.MediaItemStatus);
+ }
+
+ public static abstract interface RemotePlaybackClient.OnMessageReceivedListener {
+ method public abstract void onMessageReceived(java.lang.String, android.os.Bundle);
+ }
+
+ public static abstract class RemotePlaybackClient.SessionActionCallback extends android.support.v7.media.RemotePlaybackClient.ActionCallback {
+ ctor public RemotePlaybackClient.SessionActionCallback();
+ method public void onResult(android.os.Bundle, java.lang.String, android.support.v7.media.MediaSessionStatus);
+ }
+
+ public static abstract class RemotePlaybackClient.StatusCallback {
+ ctor public RemotePlaybackClient.StatusCallback();
+ method public void onItemStatusChanged(android.os.Bundle, java.lang.String, android.support.v7.media.MediaSessionStatus, java.lang.String, android.support.v7.media.MediaItemStatus);
+ method public void onSessionChanged(java.lang.String);
+ method public void onSessionStatusChanged(android.os.Bundle, java.lang.String, android.support.v7.media.MediaSessionStatus);
+ }
+
+}
+
+package android.support.v7.preference {
+
+ public class CheckBoxPreference extends android.support.v7.preference.TwoStatePreference {
+ ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet, int);
+ ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet);
+ ctor public CheckBoxPreference(android.content.Context);
+ }
+
+ public abstract class DialogPreference extends android.support.v7.preference.Preference {
+ ctor public DialogPreference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public DialogPreference(android.content.Context, android.util.AttributeSet, int);
+ ctor public DialogPreference(android.content.Context, android.util.AttributeSet);
+ ctor public DialogPreference(android.content.Context);
+ method public android.graphics.drawable.Drawable getDialogIcon();
+ method public int getDialogLayoutResource();
+ method public java.lang.CharSequence getDialogMessage();
+ method public java.lang.CharSequence getDialogTitle();
+ method public java.lang.CharSequence getNegativeButtonText();
+ method public java.lang.CharSequence getPositiveButtonText();
+ method public void setDialogIcon(android.graphics.drawable.Drawable);
+ method public void setDialogIcon(int);
+ method public void setDialogLayoutResource(int);
+ method public void setDialogMessage(java.lang.CharSequence);
+ method public void setDialogMessage(int);
+ method public void setDialogTitle(java.lang.CharSequence);
+ method public void setDialogTitle(int);
+ method public void setNegativeButtonText(java.lang.CharSequence);
+ method public void setNegativeButtonText(int);
+ method public void setPositiveButtonText(java.lang.CharSequence);
+ method public void setPositiveButtonText(int);
+ }
+
+ public static abstract interface DialogPreference.TargetFragment {
+ method public abstract android.support.v7.preference.Preference findPreference(java.lang.CharSequence);
+ }
+
+ public class DropDownPreference extends android.support.v7.preference.ListPreference {
+ ctor public DropDownPreference(android.content.Context);
+ ctor public DropDownPreference(android.content.Context, android.util.AttributeSet);
+ ctor public DropDownPreference(android.content.Context, android.util.AttributeSet, int);
+ ctor public DropDownPreference(android.content.Context, android.util.AttributeSet, int, int);
+ method protected android.widget.ArrayAdapter createAdapter();
+ }
+
+ public class EditTextPreference extends android.support.v7.preference.DialogPreference {
+ ctor public EditTextPreference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public EditTextPreference(android.content.Context, android.util.AttributeSet, int);
+ ctor public EditTextPreference(android.content.Context, android.util.AttributeSet);
+ ctor public EditTextPreference(android.content.Context);
+ method public java.lang.String getText();
+ method public void setText(java.lang.String);
+ }
+
+ public class EditTextPreferenceDialogFragmentCompat extends android.support.v7.preference.PreferenceDialogFragmentCompat {
+ ctor public EditTextPreferenceDialogFragmentCompat();
+ method public static android.support.v7.preference.EditTextPreferenceDialogFragmentCompat newInstance(java.lang.String);
+ method public void onDialogClosed(boolean);
+ }
+
+ public class ListPreference extends android.support.v7.preference.DialogPreference {
+ ctor public ListPreference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public ListPreference(android.content.Context, android.util.AttributeSet, int);
+ ctor public ListPreference(android.content.Context, android.util.AttributeSet);
+ ctor public ListPreference(android.content.Context);
+ method public int findIndexOfValue(java.lang.String);
+ method public java.lang.CharSequence[] getEntries();
+ method public java.lang.CharSequence getEntry();
+ method public java.lang.CharSequence[] getEntryValues();
+ method public java.lang.String getValue();
+ method public void setEntries(java.lang.CharSequence[]);
+ method public void setEntries(int);
+ method public void setEntryValues(java.lang.CharSequence[]);
+ method public void setEntryValues(int);
+ method public void setValue(java.lang.String);
+ method public void setValueIndex(int);
+ }
+
+ public class ListPreferenceDialogFragmentCompat extends android.support.v7.preference.PreferenceDialogFragmentCompat {
+ ctor public ListPreferenceDialogFragmentCompat();
+ method public static android.support.v7.preference.ListPreferenceDialogFragmentCompat newInstance(java.lang.String);
+ method public void onDialogClosed(boolean);
+ }
+
+ public class MultiSelectListPreferenceDialogFragmentCompat extends android.support.v7.preference.PreferenceDialogFragmentCompat {
+ ctor public MultiSelectListPreferenceDialogFragmentCompat();
+ method public static android.support.v7.preference.MultiSelectListPreferenceDialogFragmentCompat newInstance(java.lang.String);
+ method public void onDialogClosed(boolean);
+ }
+
+ public class Preference implements java.lang.Comparable {
+ ctor public Preference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public Preference(android.content.Context, android.util.AttributeSet, int);
+ ctor public Preference(android.content.Context, android.util.AttributeSet);
+ ctor public Preference(android.content.Context);
+ method public boolean callChangeListener(java.lang.Object);
+ method public int compareTo(android.support.v7.preference.Preference);
+ method protected android.support.v7.preference.Preference findPreferenceInHierarchy(java.lang.String);
+ method public android.content.Context getContext();
+ method public java.lang.String getDependency();
+ method public android.os.Bundle getExtras();
+ method public java.lang.String getFragment();
+ method public android.graphics.drawable.Drawable getIcon();
+ method public android.content.Intent getIntent();
+ method public java.lang.String getKey();
+ method public final int getLayoutResource();
+ method public android.support.v7.preference.Preference.OnPreferenceChangeListener getOnPreferenceChangeListener();
+ method public android.support.v7.preference.Preference.OnPreferenceClickListener getOnPreferenceClickListener();
+ method public int getOrder();
+ method protected boolean getPersistedBoolean(boolean);
+ method protected float getPersistedFloat(float);
+ method protected int getPersistedInt(int);
+ method protected long getPersistedLong(long);
+ method protected java.lang.String getPersistedString(java.lang.String);
+ method public android.support.v7.preference.PreferenceManager getPreferenceManager();
+ method public android.content.SharedPreferences getSharedPreferences();
+ method public boolean getShouldDisableView();
+ method public java.lang.CharSequence getSummary();
+ method public java.lang.CharSequence getTitle();
+ method public final int getWidgetLayoutResource();
+ method public boolean hasKey();
+ method public boolean isEnabled();
+ method public boolean isPersistent();
+ method public boolean isSelectable();
+ method public final boolean isVisible();
+ method protected void notifyChanged();
+ method public void notifyDependencyChange(boolean);
+ method protected void notifyHierarchyChanged();
+ method public void onAttached();
+ method protected void onAttachedToHierarchy(android.support.v7.preference.PreferenceManager);
+ method public void onBindViewHolder(android.support.v7.preference.PreferenceViewHolder);
+ method protected void onClick();
+ method public void onDependencyChanged(android.support.v7.preference.Preference, boolean);
+ method public void onDetached();
+ method protected java.lang.Object onGetDefaultValue(android.content.res.TypedArray, int);
+ method public void onInitializeAccessibilityNodeInfo(android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+ method public void onParentChanged(android.support.v7.preference.Preference, boolean);
+ method protected void onPrepareForRemoval();
+ method protected void onRestoreInstanceState(android.os.Parcelable);
+ method protected android.os.Parcelable onSaveInstanceState();
+ method protected void onSetInitialValue(boolean, java.lang.Object);
+ method public android.os.Bundle peekExtras();
+ method protected boolean persistBoolean(boolean);
+ method protected boolean persistFloat(float);
+ method protected boolean persistInt(int);
+ method protected boolean persistLong(long);
+ method protected boolean persistString(java.lang.String);
+ method public void restoreHierarchyState(android.os.Bundle);
+ method public void saveHierarchyState(android.os.Bundle);
+ method public void setDefaultValue(java.lang.Object);
+ method public void setDependency(java.lang.String);
+ method public void setEnabled(boolean);
+ method public void setFragment(java.lang.String);
+ method public void setIcon(android.graphics.drawable.Drawable);
+ method public void setIcon(int);
+ method public void setIntent(android.content.Intent);
+ method public void setKey(java.lang.String);
+ method public void setLayoutResource(int);
+ method public void setOnPreferenceChangeListener(android.support.v7.preference.Preference.OnPreferenceChangeListener);
+ method public void setOnPreferenceClickListener(android.support.v7.preference.Preference.OnPreferenceClickListener);
+ method public void setOrder(int);
+ method public void setPersistent(boolean);
+ method public void setSelectable(boolean);
+ method public void setShouldDisableView(boolean);
+ method public void setSummary(java.lang.CharSequence);
+ method public void setSummary(int);
+ method public void setTitle(java.lang.CharSequence);
+ method public void setTitle(int);
+ method public void setViewId(int);
+ method public final void setVisible(boolean);
+ method public void setWidgetLayoutResource(int);
+ method public boolean shouldDisableDependents();
+ method protected boolean shouldPersist();
+ field public static final int DEFAULT_ORDER = 2147483647; // 0x7fffffff
+ }
+
+ public static class Preference.BaseSavedState extends android.view.AbsSavedState {
+ ctor public Preference.BaseSavedState(android.os.Parcel);
+ ctor public Preference.BaseSavedState(android.os.Parcelable);
+ field public static final android.os.Parcelable.Creator<android.support.v7.preference.Preference.BaseSavedState> CREATOR;
+ }
+
+ public static abstract interface Preference.OnPreferenceChangeListener {
+ method public abstract boolean onPreferenceChange(android.support.v7.preference.Preference, java.lang.Object);
+ }
+
+ public static abstract interface Preference.OnPreferenceClickListener {
+ method public abstract boolean onPreferenceClick(android.support.v7.preference.Preference);
+ }
+
+ public class PreferenceCategory extends android.support.v7.preference.PreferenceGroup {
+ ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet, int);
+ ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet);
+ ctor public PreferenceCategory(android.content.Context);
+ }
+
+ public abstract class PreferenceDialogFragmentCompat extends android.support.v4.app.DialogFragment implements android.content.DialogInterface.OnClickListener {
+ ctor public PreferenceDialogFragmentCompat();
+ method public android.support.v7.preference.DialogPreference getPreference();
+ method protected void onBindDialogView(android.view.View);
+ method public void onClick(android.content.DialogInterface, int);
+ method protected android.view.View onCreateDialogView(android.content.Context);
+ method public abstract void onDialogClosed(boolean);
+ method protected void onPrepareDialogBuilder(android.support.v7.app.AlertDialog.Builder);
+ field protected static final java.lang.String ARG_KEY = "key";
+ }
+
+ public abstract class PreferenceFragmentCompat extends android.support.v4.app.Fragment implements android.support.v7.preference.DialogPreference.TargetFragment android.support.v7.preference.PreferenceManager.OnDisplayPreferenceDialogListener android.support.v7.preference.PreferenceManager.OnNavigateToScreenListener android.support.v7.preference.PreferenceManager.OnPreferenceTreeClickListener {
+ ctor public PreferenceFragmentCompat();
+ method public void addPreferencesFromResource(int);
+ method public android.support.v7.preference.Preference findPreference(java.lang.CharSequence);
+ method public final android.support.v7.widget.RecyclerView getListView();
+ method public android.support.v7.preference.PreferenceManager getPreferenceManager();
+ method public android.support.v7.preference.PreferenceScreen getPreferenceScreen();
+ method protected android.support.v7.widget.RecyclerView.Adapter onCreateAdapter(android.support.v7.preference.PreferenceScreen);
+ method public android.support.v7.widget.RecyclerView.LayoutManager onCreateLayoutManager();
+ method public abstract void onCreatePreferences(android.os.Bundle, java.lang.String);
+ method public android.support.v7.widget.RecyclerView onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle);
+ method public void onDisplayPreferenceDialog(android.support.v7.preference.Preference);
+ method public void onNavigateToScreen(android.support.v7.preference.PreferenceScreen);
+ method public boolean onPreferenceTreeClick(android.support.v7.preference.Preference);
+ method public void scrollToPreference(java.lang.String);
+ method public void scrollToPreference(android.support.v7.preference.Preference);
+ method public void setDivider(android.graphics.drawable.Drawable);
+ method public void setDividerHeight(int);
+ method public void setPreferenceScreen(android.support.v7.preference.PreferenceScreen);
+ method public void setPreferencesFromResource(int, java.lang.String);
+ field public static final java.lang.String ARG_PREFERENCE_ROOT = "android.support.v7.preference.PreferenceFragmentCompat.PREFERENCE_ROOT";
+ }
+
+ public static abstract interface PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback {
+ method public abstract boolean onPreferenceDisplayDialog(android.support.v7.preference.PreferenceFragmentCompat, android.support.v7.preference.Preference);
+ }
+
+ public static abstract interface PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
+ method public abstract boolean onPreferenceStartFragment(android.support.v7.preference.PreferenceFragmentCompat, android.support.v7.preference.Preference);
+ }
+
+ public static abstract interface PreferenceFragmentCompat.OnPreferenceStartScreenCallback {
+ method public abstract boolean onPreferenceStartScreen(android.support.v7.preference.PreferenceFragmentCompat, android.support.v7.preference.PreferenceScreen);
+ }
+
+ public abstract class PreferenceGroup extends android.support.v7.preference.Preference {
+ ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet, int);
+ ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet);
+ method public void addItemFromInflater(android.support.v7.preference.Preference);
+ method public boolean addPreference(android.support.v7.preference.Preference);
+ method protected void dispatchRestoreInstanceState(android.os.Bundle);
+ method protected void dispatchSaveInstanceState(android.os.Bundle);
+ method public android.support.v7.preference.Preference findPreference(java.lang.CharSequence);
+ method public android.support.v7.preference.Preference getPreference(int);
+ method public int getPreferenceCount();
+ method protected boolean isOnSameScreenAsChildren();
+ method public boolean isOrderingAsAdded();
+ method protected boolean onPrepareAddPreference(android.support.v7.preference.Preference);
+ method public void removeAll();
+ method public boolean removePreference(android.support.v7.preference.Preference);
+ method public void setOrderingAsAdded(boolean);
+ }
+
+ public static abstract interface PreferenceGroup.PreferencePositionCallback {
+ method public abstract int getPreferenceAdapterPosition(java.lang.String);
+ method public abstract int getPreferenceAdapterPosition(android.support.v7.preference.Preference);
+ }
+
+ public class PreferenceManager {
+ method public android.support.v7.preference.PreferenceScreen createPreferenceScreen(android.content.Context);
+ method public android.support.v7.preference.Preference findPreference(java.lang.CharSequence);
+ method public android.content.Context getContext();
+ method public static android.content.SharedPreferences getDefaultSharedPreferences(android.content.Context);
+ method public android.support.v7.preference.PreferenceManager.OnDisplayPreferenceDialogListener getOnDisplayPreferenceDialogListener();
+ method public android.support.v7.preference.PreferenceManager.OnNavigateToScreenListener getOnNavigateToScreenListener();
+ method public android.support.v7.preference.PreferenceManager.OnPreferenceTreeClickListener getOnPreferenceTreeClickListener();
+ method public android.support.v7.preference.PreferenceManager.PreferenceComparisonCallback getPreferenceComparisonCallback();
+ method public android.support.v7.preference.PreferenceScreen getPreferenceScreen();
+ method public android.content.SharedPreferences getSharedPreferences();
+ method public int getSharedPreferencesMode();
+ method public java.lang.String getSharedPreferencesName();
+ method public boolean isStorageDefault();
+ method public boolean isStorageDeviceProtected();
+ method public static void setDefaultValues(android.content.Context, int, boolean);
+ method public static void setDefaultValues(android.content.Context, java.lang.String, int, int, boolean);
+ method public void setOnDisplayPreferenceDialogListener(android.support.v7.preference.PreferenceManager.OnDisplayPreferenceDialogListener);
+ method public void setOnNavigateToScreenListener(android.support.v7.preference.PreferenceManager.OnNavigateToScreenListener);
+ method public void setOnPreferenceTreeClickListener(android.support.v7.preference.PreferenceManager.OnPreferenceTreeClickListener);
+ method public void setPreferenceComparisonCallback(android.support.v7.preference.PreferenceManager.PreferenceComparisonCallback);
+ method public boolean setPreferences(android.support.v7.preference.PreferenceScreen);
+ method public void setSharedPreferencesMode(int);
+ method public void setSharedPreferencesName(java.lang.String);
+ method public void setStorageDefault();
+ method public void setStorageDeviceProtected();
+ method public void showDialog(android.support.v7.preference.Preference);
+ field public static final java.lang.String KEY_HAS_SET_DEFAULT_VALUES = "_has_set_default_values";
+ }
+
+ public static abstract interface PreferenceManager.OnDisplayPreferenceDialogListener {
+ method public abstract void onDisplayPreferenceDialog(android.support.v7.preference.Preference);
+ }
+
+ public static abstract interface PreferenceManager.OnNavigateToScreenListener {
+ method public abstract void onNavigateToScreen(android.support.v7.preference.PreferenceScreen);
+ }
+
+ public static abstract interface PreferenceManager.OnPreferenceTreeClickListener {
+ method public abstract boolean onPreferenceTreeClick(android.support.v7.preference.Preference);
+ }
+
+ public static abstract class PreferenceManager.PreferenceComparisonCallback {
+ ctor public PreferenceManager.PreferenceComparisonCallback();
+ method public abstract boolean arePreferenceContentsTheSame(android.support.v7.preference.Preference, android.support.v7.preference.Preference);
+ method public abstract boolean arePreferenceItemsTheSame(android.support.v7.preference.Preference, android.support.v7.preference.Preference);
+ }
+
+ public static class PreferenceManager.SimplePreferenceComparisonCallback extends android.support.v7.preference.PreferenceManager.PreferenceComparisonCallback {
+ ctor public PreferenceManager.SimplePreferenceComparisonCallback();
+ method public boolean arePreferenceContentsTheSame(android.support.v7.preference.Preference, android.support.v7.preference.Preference);
+ method public boolean arePreferenceItemsTheSame(android.support.v7.preference.Preference, android.support.v7.preference.Preference);
+ }
+
+ public final class PreferenceScreen extends android.support.v7.preference.PreferenceGroup {
+ method public void setShouldUseGeneratedIds(boolean);
+ method public boolean shouldUseGeneratedIds();
+ }
+
+ public class PreferenceViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder {
+ method public android.view.View findViewById(int);
+ method public boolean isDividerAllowedAbove();
+ method public boolean isDividerAllowedBelow();
+ method public void setDividerAllowedAbove(boolean);
+ method public void setDividerAllowedBelow(boolean);
+ }
+
+ public class SeekBarPreference extends android.support.v7.preference.Preference {
+ ctor public SeekBarPreference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public SeekBarPreference(android.content.Context, android.util.AttributeSet, int);
+ ctor public SeekBarPreference(android.content.Context, android.util.AttributeSet);
+ ctor public SeekBarPreference(android.content.Context);
+ method public int getMax();
+ method public int getMin();
+ method public final int getSeekBarIncrement();
+ method public int getValue();
+ method public boolean isAdjustable();
+ method public void setAdjustable(boolean);
+ method public final void setMax(int);
+ method public void setMin(int);
+ method public final void setSeekBarIncrement(int);
+ method public void setValue(int);
+ }
+
+ public class SwitchPreferenceCompat extends android.support.v7.preference.TwoStatePreference {
+ ctor public SwitchPreferenceCompat(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public SwitchPreferenceCompat(android.content.Context, android.util.AttributeSet, int);
+ ctor public SwitchPreferenceCompat(android.content.Context, android.util.AttributeSet);
+ ctor public SwitchPreferenceCompat(android.content.Context);
+ method public java.lang.CharSequence getSwitchTextOff();
+ method public java.lang.CharSequence getSwitchTextOn();
+ method public void setSwitchTextOff(java.lang.CharSequence);
+ method public void setSwitchTextOff(int);
+ method public void setSwitchTextOn(java.lang.CharSequence);
+ method public void setSwitchTextOn(int);
+ }
+
+ public abstract class TwoStatePreference extends android.support.v7.preference.Preference {
+ ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet, int);
+ ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet);
+ ctor public TwoStatePreference(android.content.Context);
+ method public boolean getDisableDependentsState();
+ method public java.lang.CharSequence getSummaryOff();
+ method public java.lang.CharSequence getSummaryOn();
+ method public boolean isChecked();
+ method public void setChecked(boolean);
+ method public void setDisableDependentsState(boolean);
+ method public void setSummaryOff(java.lang.CharSequence);
+ method public void setSummaryOff(int);
+ method public void setSummaryOn(java.lang.CharSequence);
+ method public void setSummaryOn(int);
+ method protected void syncSummaryView(android.support.v7.preference.PreferenceViewHolder);
+ field protected boolean mChecked;
+ }
+
+}
+
+package android.support.v7.util {
+
+ public class AsyncListUtil<T> {
+ ctor public AsyncListUtil(java.lang.Class<T>, int, android.support.v7.util.AsyncListUtil.DataCallback<T>, android.support.v7.util.AsyncListUtil.ViewCallback);
+ method public T getItem(int);
+ method public int getItemCount();
+ method public void onRangeChanged();
+ method public void refresh();
+ }
+
+ public static abstract class AsyncListUtil.DataCallback<T> {
+ ctor public AsyncListUtil.DataCallback();
+ method public abstract void fillData(T[], int, int);
+ method public int getMaxCachedTiles();
+ method public void recycleData(T[], int);
+ method public abstract int refreshData();
+ }
+
+ public static abstract class AsyncListUtil.ViewCallback {
+ ctor public AsyncListUtil.ViewCallback();
+ method public void extendRangeInto(int[], int[], int);
+ method public abstract void getItemRangeInto(int[]);
+ method public abstract void onDataRefresh();
+ method public abstract void onItemLoaded(int);
+ field public static final int HINT_SCROLL_ASC = 2; // 0x2
+ field public static final int HINT_SCROLL_DESC = 1; // 0x1
+ field public static final int HINT_SCROLL_NONE = 0; // 0x0
+ }
+
+ public class BatchingListUpdateCallback implements android.support.v7.util.ListUpdateCallback {
+ ctor public BatchingListUpdateCallback(android.support.v7.util.ListUpdateCallback);
+ method public void dispatchLastEvent();
+ method public void onChanged(int, int, java.lang.Object);
+ method public void onInserted(int, int);
+ method public void onMoved(int, int);
+ method public void onRemoved(int, int);
+ }
+
+ public class DiffUtil {
+ method public static android.support.v7.util.DiffUtil.DiffResult calculateDiff(android.support.v7.util.DiffUtil.Callback);
+ method public static android.support.v7.util.DiffUtil.DiffResult calculateDiff(android.support.v7.util.DiffUtil.Callback, boolean);
+ }
+
+ public static abstract class DiffUtil.Callback {
+ ctor public DiffUtil.Callback();
+ method public abstract boolean areContentsTheSame(int, int);
+ method public abstract boolean areItemsTheSame(int, int);
+ method public java.lang.Object getChangePayload(int, int);
+ method public abstract int getNewListSize();
+ method public abstract int getOldListSize();
+ }
+
+ public static class DiffUtil.DiffResult {
+ method public void dispatchUpdatesTo(android.support.v7.widget.RecyclerView.Adapter);
+ method public void dispatchUpdatesTo(android.support.v7.util.ListUpdateCallback);
+ }
+
+ public abstract interface ListUpdateCallback {
+ method public abstract void onChanged(int, int, java.lang.Object);
+ method public abstract void onInserted(int, int);
+ method public abstract void onMoved(int, int);
+ method public abstract void onRemoved(int, int);
+ }
+
+ public class SortedList<T> {
+ ctor public SortedList(java.lang.Class<T>, android.support.v7.util.SortedList.Callback<T>);
+ ctor public SortedList(java.lang.Class<T>, android.support.v7.util.SortedList.Callback<T>, int);
+ method public int add(T);
+ method public void addAll(T[], boolean);
+ method public void addAll(T...);
+ method public void addAll(java.util.Collection<T>);
+ method public void beginBatchedUpdates();
+ method public void clear();
+ method public void endBatchedUpdates();
+ method public T get(int) throws java.lang.IndexOutOfBoundsException;
+ method public int indexOf(T);
+ method public void recalculatePositionOfItemAt(int);
+ method public boolean remove(T);
+ method public T removeItemAt(int);
+ method public int size();
+ method public void updateItemAt(int, T);
+ field public static final int INVALID_POSITION = -1; // 0xffffffff
+ }
+
+ public static class SortedList.BatchedCallback<T2> extends android.support.v7.util.SortedList.Callback {
+ ctor public SortedList.BatchedCallback(android.support.v7.util.SortedList.Callback<T2>);
+ method public boolean areContentsTheSame(T2, T2);
+ method public boolean areItemsTheSame(T2, T2);
+ method public int compare(T2, T2);
+ method public void dispatchLastEvent();
+ method public void onChanged(int, int);
+ method public void onInserted(int, int);
+ method public void onMoved(int, int);
+ method public void onRemoved(int, int);
+ }
+
+ public static abstract class SortedList.Callback<T2> implements java.util.Comparator android.support.v7.util.ListUpdateCallback {
+ ctor public SortedList.Callback();
+ method public abstract boolean areContentsTheSame(T2, T2);
+ method public abstract boolean areItemsTheSame(T2, T2);
+ method public abstract int compare(T2, T2);
+ method public abstract void onChanged(int, int);
+ method public void onChanged(int, int, java.lang.Object);
+ }
+
+}
+
+package android.support.v7.view {
+
+ public abstract class ActionMode {
+ ctor public ActionMode();
+ method public abstract void finish();
+ method public abstract android.view.View getCustomView();
+ method public abstract android.view.Menu getMenu();
+ method public abstract android.view.MenuInflater getMenuInflater();
+ method public abstract java.lang.CharSequence getSubtitle();
+ method public java.lang.Object getTag();
+ method public abstract java.lang.CharSequence getTitle();
+ method public boolean getTitleOptionalHint();
+ method public abstract void invalidate();
+ method public boolean isTitleOptional();
+ method public abstract void setCustomView(android.view.View);
+ method public abstract void setSubtitle(java.lang.CharSequence);
+ method public abstract void setSubtitle(int);
+ method public void setTag(java.lang.Object);
+ method public abstract void setTitle(java.lang.CharSequence);
+ method public abstract void setTitle(int);
+ method public void setTitleOptionalHint(boolean);
+ }
+
+ public static abstract interface ActionMode.Callback {
+ method public abstract boolean onActionItemClicked(android.support.v7.view.ActionMode, android.view.MenuItem);
+ method public abstract boolean onCreateActionMode(android.support.v7.view.ActionMode, android.view.Menu);
+ method public abstract void onDestroyActionMode(android.support.v7.view.ActionMode);
+ method public abstract boolean onPrepareActionMode(android.support.v7.view.ActionMode, android.view.Menu);
+ }
+
+ public abstract interface CollapsibleActionView {
+ method public abstract void onActionViewCollapsed();
+ method public abstract void onActionViewExpanded();
+ }
+
+}
+
+package android.support.v7.widget {
+
+ public class ActionMenuView extends android.support.v7.widget.LinearLayoutCompat {
+ ctor public ActionMenuView(android.content.Context);
+ ctor public ActionMenuView(android.content.Context, android.util.AttributeSet);
+ method public void dismissPopupMenus();
+ method public android.view.Menu getMenu();
+ method public android.graphics.drawable.Drawable getOverflowIcon();
+ method public int getPopupTheme();
+ method public boolean hideOverflowMenu();
+ method public boolean isOverflowMenuShowing();
+ method public void onConfigurationChanged(android.content.res.Configuration);
+ method public void onDetachedFromWindow();
+ method public void setOnMenuItemClickListener(android.support.v7.widget.ActionMenuView.OnMenuItemClickListener);
+ method public void setOverflowIcon(android.graphics.drawable.Drawable);
+ method public void setPopupTheme(int);
+ method public boolean showOverflowMenu();
+ }
+
+ public static class ActionMenuView.LayoutParams extends android.support.v7.widget.LinearLayoutCompat.LayoutParams {
+ ctor public ActionMenuView.LayoutParams(android.content.Context, android.util.AttributeSet);
+ ctor public ActionMenuView.LayoutParams(android.view.ViewGroup.LayoutParams);
+ ctor public ActionMenuView.LayoutParams(android.support.v7.widget.ActionMenuView.LayoutParams);
+ ctor public ActionMenuView.LayoutParams(int, int);
+ field public int cellsUsed;
+ field public boolean expandable;
+ field public int extraPixels;
+ field public boolean isOverflowButton;
+ field public boolean preventEdgeOffset;
+ }
+
+ public static abstract interface ActionMenuView.OnMenuItemClickListener {
+ method public abstract boolean onMenuItemClick(android.view.MenuItem);
+ }
+
+ public class AppCompatAutoCompleteTextView extends android.widget.AutoCompleteTextView implements android.support.v4.view.TintableBackgroundView {
+ ctor public AppCompatAutoCompleteTextView(android.content.Context);
+ ctor public AppCompatAutoCompleteTextView(android.content.Context, android.util.AttributeSet);
+ ctor public AppCompatAutoCompleteTextView(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public class AppCompatButton extends android.widget.Button implements android.support.v4.view.TintableBackgroundView {
+ ctor public AppCompatButton(android.content.Context);
+ ctor public AppCompatButton(android.content.Context, android.util.AttributeSet);
+ ctor public AppCompatButton(android.content.Context, android.util.AttributeSet, int);
+ method public void setSupportAllCaps(boolean);
+ }
+
+ public class AppCompatCheckBox extends android.widget.CheckBox implements android.support.v4.widget.TintableCompoundButton {
+ ctor public AppCompatCheckBox(android.content.Context);
+ ctor public AppCompatCheckBox(android.content.Context, android.util.AttributeSet);
+ ctor public AppCompatCheckBox(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public class AppCompatCheckedTextView extends android.widget.CheckedTextView {
+ ctor public AppCompatCheckedTextView(android.content.Context);
+ ctor public AppCompatCheckedTextView(android.content.Context, android.util.AttributeSet);
+ ctor public AppCompatCheckedTextView(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public class AppCompatEditText extends android.widget.EditText implements android.support.v4.view.TintableBackgroundView {
+ ctor public AppCompatEditText(android.content.Context);
+ ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet);
+ ctor public AppCompatEditText(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public class AppCompatImageButton extends android.widget.ImageButton implements android.support.v4.view.TintableBackgroundView {
+ ctor public AppCompatImageButton(android.content.Context);
+ ctor public AppCompatImageButton(android.content.Context, android.util.AttributeSet);
+ ctor public AppCompatImageButton(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public class AppCompatImageView extends android.widget.ImageView implements android.support.v4.view.TintableBackgroundView {
+ ctor public AppCompatImageView(android.content.Context);
+ ctor public AppCompatImageView(android.content.Context, android.util.AttributeSet);
+ ctor public AppCompatImageView(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public class AppCompatMultiAutoCompleteTextView extends android.widget.MultiAutoCompleteTextView implements android.support.v4.view.TintableBackgroundView {
+ ctor public AppCompatMultiAutoCompleteTextView(android.content.Context);
+ ctor public AppCompatMultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet);
+ ctor public AppCompatMultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public class AppCompatRadioButton extends android.widget.RadioButton implements android.support.v4.widget.TintableCompoundButton {
+ ctor public AppCompatRadioButton(android.content.Context);
+ ctor public AppCompatRadioButton(android.content.Context, android.util.AttributeSet);
+ ctor public AppCompatRadioButton(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public class AppCompatRatingBar extends android.widget.RatingBar {
+ ctor public AppCompatRatingBar(android.content.Context);
+ ctor public AppCompatRatingBar(android.content.Context, android.util.AttributeSet);
+ ctor public AppCompatRatingBar(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public class AppCompatSeekBar extends android.widget.SeekBar {
+ ctor public AppCompatSeekBar(android.content.Context);
+ ctor public AppCompatSeekBar(android.content.Context, android.util.AttributeSet);
+ ctor public AppCompatSeekBar(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public class AppCompatSpinner extends android.widget.Spinner implements android.support.v4.view.TintableBackgroundView {
+ ctor public AppCompatSpinner(android.content.Context);
+ ctor public AppCompatSpinner(android.content.Context, int);
+ ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet);
+ ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet, int);
+ ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public AppCompatSpinner(android.content.Context, android.util.AttributeSet, int, int, android.content.res.Resources.Theme);
+ }
+
+ public class AppCompatTextView extends android.widget.TextView implements android.support.v4.view.TintableBackgroundView {
+ ctor public AppCompatTextView(android.content.Context);
+ ctor public AppCompatTextView(android.content.Context, android.util.AttributeSet);
+ ctor public AppCompatTextView(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public class CardView extends android.widget.FrameLayout {
+ ctor public CardView(android.content.Context);
+ ctor public CardView(android.content.Context, android.util.AttributeSet);
+ ctor public CardView(android.content.Context, android.util.AttributeSet, int);
+ method public android.content.res.ColorStateList getCardBackgroundColor();
+ method public float getCardElevation();
+ method public int getContentPaddingBottom();
+ method public int getContentPaddingLeft();
+ method public int getContentPaddingRight();
+ method public int getContentPaddingTop();
+ method public float getMaxCardElevation();
+ method public boolean getPreventCornerOverlap();
+ method public float getRadius();
+ method public boolean getUseCompatPadding();
+ method public void setCardBackgroundColor(int);
+ method public void setCardBackgroundColor(android.content.res.ColorStateList);
+ method public void setCardElevation(float);
+ method public void setContentPadding(int, int, int, int);
+ method public void setMaxCardElevation(float);
+ method public void setPreventCornerOverlap(boolean);
+ method public void setRadius(float);
+ method public void setUseCompatPadding(boolean);
+ }
+
+ public class DefaultItemAnimator extends android.support.v7.widget.SimpleItemAnimator {
+ ctor public DefaultItemAnimator();
+ method public boolean animateAdd(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public boolean animateChange(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ViewHolder, int, int, int, int);
+ method public boolean animateMove(android.support.v7.widget.RecyclerView.ViewHolder, int, int, int, int);
+ method public boolean animateRemove(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public void endAnimation(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public void endAnimations();
+ method public boolean isRunning();
+ method public void runPendingAnimations();
+ }
+
+ public class DividerItemDecoration extends android.support.v7.widget.RecyclerView.ItemDecoration {
+ ctor public DividerItemDecoration(android.content.Context, int);
+ method public void setDrawable(android.graphics.drawable.Drawable);
+ method public void setOrientation(int);
+ field public static final int HORIZONTAL = 0; // 0x0
+ field public static final int VERTICAL = 1; // 0x1
+ }
+
+ public class GridLayout extends android.view.ViewGroup {
+ ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
+ ctor public GridLayout(android.content.Context, android.util.AttributeSet);
+ ctor public GridLayout(android.content.Context);
+ method public int getAlignmentMode();
+ method public int getColumnCount();
+ method public int getOrientation();
+ method public android.util.Printer getPrinter();
+ method public int getRowCount();
+ method public boolean getUseDefaultMargins();
+ method public boolean isColumnOrderPreserved();
+ method public boolean isRowOrderPreserved();
+ method protected void onLayout(boolean, int, int, int, int);
+ method public void setAlignmentMode(int);
+ method public void setColumnCount(int);
+ method public void setColumnOrderPreserved(boolean);
+ method public void setOrientation(int);
+ method public void setPrinter(android.util.Printer);
+ method public void setRowCount(int);
+ method public void setRowOrderPreserved(boolean);
+ method public void setUseDefaultMargins(boolean);
+ method public static android.support.v7.widget.GridLayout.Spec spec(int, int, android.support.v7.widget.GridLayout.Alignment, float);
+ method public static android.support.v7.widget.GridLayout.Spec spec(int, android.support.v7.widget.GridLayout.Alignment, float);
+ method public static android.support.v7.widget.GridLayout.Spec spec(int, int, float);
+ method public static android.support.v7.widget.GridLayout.Spec spec(int, float);
+ method public static android.support.v7.widget.GridLayout.Spec spec(int, int, android.support.v7.widget.GridLayout.Alignment);
+ method public static android.support.v7.widget.GridLayout.Spec spec(int, android.support.v7.widget.GridLayout.Alignment);
+ method public static android.support.v7.widget.GridLayout.Spec spec(int, int);
+ method public static android.support.v7.widget.GridLayout.Spec spec(int);
+ field public static final int ALIGN_BOUNDS = 0; // 0x0
+ field public static final int ALIGN_MARGINS = 1; // 0x1
+ field public static final android.support.v7.widget.GridLayout.Alignment BASELINE;
+ field public static final android.support.v7.widget.GridLayout.Alignment BOTTOM;
+ field public static final android.support.v7.widget.GridLayout.Alignment CENTER;
+ field public static final android.support.v7.widget.GridLayout.Alignment END;
+ field public static final android.support.v7.widget.GridLayout.Alignment FILL;
+ field public static final int HORIZONTAL = 0; // 0x0
+ field public static final android.support.v7.widget.GridLayout.Alignment LEFT;
+ field public static final android.support.v7.widget.GridLayout.Alignment RIGHT;
+ field public static final android.support.v7.widget.GridLayout.Alignment START;
+ field public static final android.support.v7.widget.GridLayout.Alignment TOP;
+ field public static final int UNDEFINED = -2147483648; // 0x80000000
+ field public static final int VERTICAL = 1; // 0x1
+ }
+
+ public static abstract class GridLayout.Alignment {
+ }
+
+ public static class GridLayout.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+ ctor public GridLayout.LayoutParams(android.support.v7.widget.GridLayout.Spec, android.support.v7.widget.GridLayout.Spec);
+ ctor public GridLayout.LayoutParams();
+ ctor public GridLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+ ctor public GridLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ ctor public GridLayout.LayoutParams(android.support.v7.widget.GridLayout.LayoutParams);
+ ctor public GridLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+ method public void setGravity(int);
+ field public android.support.v7.widget.GridLayout.Spec columnSpec;
+ field public android.support.v7.widget.GridLayout.Spec rowSpec;
+ }
+
+ public static class GridLayout.Spec {
+ method public android.support.v7.widget.GridLayout.Alignment getAbsoluteAlignment(boolean);
+ }
+
+ public class GridLayoutManager extends android.support.v7.widget.LinearLayoutManager {
+ ctor public GridLayoutManager(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public GridLayoutManager(android.content.Context, int);
+ ctor public GridLayoutManager(android.content.Context, int, int, boolean);
+ method public int getSpanCount();
+ method public android.support.v7.widget.GridLayoutManager.SpanSizeLookup getSpanSizeLookup();
+ method public void setSpanCount(int);
+ method public void setSpanSizeLookup(android.support.v7.widget.GridLayoutManager.SpanSizeLookup);
+ field public static final int DEFAULT_SPAN_COUNT = -1; // 0xffffffff
+ }
+
+ public static final class GridLayoutManager.DefaultSpanSizeLookup extends android.support.v7.widget.GridLayoutManager.SpanSizeLookup {
+ ctor public GridLayoutManager.DefaultSpanSizeLookup();
+ method public int getSpanSize(int);
+ }
+
+ public static class GridLayoutManager.LayoutParams extends android.support.v7.widget.RecyclerView.LayoutParams {
+ ctor public GridLayoutManager.LayoutParams(android.content.Context, android.util.AttributeSet);
+ ctor public GridLayoutManager.LayoutParams(int, int);
+ ctor public GridLayoutManager.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ ctor public GridLayoutManager.LayoutParams(android.view.ViewGroup.LayoutParams);
+ ctor public GridLayoutManager.LayoutParams(android.support.v7.widget.RecyclerView.LayoutParams);
+ method public int getSpanIndex();
+ method public int getSpanSize();
+ field public static final int INVALID_SPAN_ID = -1; // 0xffffffff
+ }
+
+ public static abstract class GridLayoutManager.SpanSizeLookup {
+ ctor public GridLayoutManager.SpanSizeLookup();
+ method public int getSpanGroupIndex(int, int);
+ method public int getSpanIndex(int, int);
+ method public abstract int getSpanSize(int);
+ method public void invalidateSpanIndexCache();
+ method public boolean isSpanIndexCacheEnabled();
+ method public void setSpanIndexCacheEnabled(boolean);
+ }
+
+ public class LinearLayoutCompat extends android.view.ViewGroup {
+ ctor public LinearLayoutCompat(android.content.Context);
+ ctor public LinearLayoutCompat(android.content.Context, android.util.AttributeSet);
+ ctor public LinearLayoutCompat(android.content.Context, android.util.AttributeSet, int);
+ method public int getBaselineAlignedChildIndex();
+ method public android.graphics.drawable.Drawable getDividerDrawable();
+ method public int getDividerPadding();
+ method public int getGravity();
+ method public int getOrientation();
+ method public int getShowDividers();
+ method public float getWeightSum();
+ method public boolean isBaselineAligned();
+ method public boolean isMeasureWithLargestChildEnabled();
+ method protected void onLayout(boolean, int, int, int, int);
+ method public void setBaselineAligned(boolean);
+ method public void setBaselineAlignedChildIndex(int);
+ method public void setDividerDrawable(android.graphics.drawable.Drawable);
+ method public void setDividerPadding(int);
+ method public void setGravity(int);
+ method public void setHorizontalGravity(int);
+ method public void setMeasureWithLargestChildEnabled(boolean);
+ method public void setOrientation(int);
+ method public void setShowDividers(int);
+ method public void setVerticalGravity(int);
+ method public void setWeightSum(float);
+ field public static final int HORIZONTAL = 0; // 0x0
+ field public static final int SHOW_DIVIDER_BEGINNING = 1; // 0x1
+ field public static final int SHOW_DIVIDER_END = 4; // 0x4
+ field public static final int SHOW_DIVIDER_MIDDLE = 2; // 0x2
+ field public static final int SHOW_DIVIDER_NONE = 0; // 0x0
+ field public static final int VERTICAL = 1; // 0x1
+ }
+
+ public static class LinearLayoutCompat.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+ ctor public LinearLayoutCompat.LayoutParams(android.content.Context, android.util.AttributeSet);
+ ctor public LinearLayoutCompat.LayoutParams(int, int);
+ ctor public LinearLayoutCompat.LayoutParams(int, int, float);
+ ctor public LinearLayoutCompat.LayoutParams(android.view.ViewGroup.LayoutParams);
+ ctor public LinearLayoutCompat.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ ctor public LinearLayoutCompat.LayoutParams(android.support.v7.widget.LinearLayoutCompat.LayoutParams);
+ field public int gravity;
+ field public float weight;
+ }
+
+ public class LinearLayoutManager extends android.support.v7.widget.RecyclerView.LayoutManager implements android.support.v7.widget.helper.ItemTouchHelper.ViewDropHandler android.support.v7.widget.RecyclerView.SmoothScroller.ScrollVectorProvider {
+ ctor public LinearLayoutManager(android.content.Context);
+ ctor public LinearLayoutManager(android.content.Context, int, boolean);
+ ctor public LinearLayoutManager(android.content.Context, android.util.AttributeSet, int, int);
+ method public android.graphics.PointF computeScrollVectorForPosition(int);
+ method public int findFirstCompletelyVisibleItemPosition();
+ method public int findFirstVisibleItemPosition();
+ method public int findLastCompletelyVisibleItemPosition();
+ method public int findLastVisibleItemPosition();
+ method public android.support.v7.widget.RecyclerView.LayoutParams generateDefaultLayoutParams();
+ method protected int getExtraLayoutSpace(android.support.v7.widget.RecyclerView.State);
+ method public int getInitialItemPrefetchCount();
+ method public int getOrientation();
+ method public boolean getRecycleChildrenOnDetach();
+ method public boolean getReverseLayout();
+ method public boolean getStackFromEnd();
+ method protected boolean isLayoutRTL();
+ method public boolean isSmoothScrollbarEnabled();
+ method public void scrollToPositionWithOffset(int, int);
+ method public void setInitialPrefetchItemCount(int);
+ method public void setOrientation(int);
+ method public void setRecycleChildrenOnDetach(boolean);
+ method public void setReverseLayout(boolean);
+ method public void setSmoothScrollbarEnabled(boolean);
+ method public void setStackFromEnd(boolean);
+ field public static final int HORIZONTAL = 0; // 0x0
+ field public static final int INVALID_OFFSET = -2147483648; // 0x80000000
+ field public static final int VERTICAL = 1; // 0x1
+ }
+
+ protected static class LinearLayoutManager.LayoutChunkResult {
+ ctor protected LinearLayoutManager.LayoutChunkResult();
+ field public int mConsumed;
+ field public boolean mFinished;
+ field public boolean mFocusable;
+ field public boolean mIgnoreConsumed;
+ }
+
+ public class LinearSmoothScroller extends android.support.v7.widget.RecyclerView.SmoothScroller {
+ ctor public LinearSmoothScroller(android.content.Context);
+ method public int calculateDtToFit(int, int, int, int, int);
+ method public int calculateDxToMakeVisible(android.view.View, int);
+ method public int calculateDyToMakeVisible(android.view.View, int);
+ method protected float calculateSpeedPerPixel(android.util.DisplayMetrics);
+ method protected int calculateTimeForDeceleration(int);
+ method protected int calculateTimeForScrolling(int);
+ method public android.graphics.PointF computeScrollVectorForPosition(int);
+ method protected int getHorizontalSnapPreference();
+ method protected int getVerticalSnapPreference();
+ method protected void onSeekTargetStep(int, int, android.support.v7.widget.RecyclerView.State, android.support.v7.widget.RecyclerView.SmoothScroller.Action);
+ method protected void onStart();
+ method protected void onStop();
+ method protected void onTargetFound(android.view.View, android.support.v7.widget.RecyclerView.State, android.support.v7.widget.RecyclerView.SmoothScroller.Action);
+ method protected void updateActionForInterimTarget(android.support.v7.widget.RecyclerView.SmoothScroller.Action);
+ field public static final int SNAP_TO_ANY = 0; // 0x0
+ field public static final int SNAP_TO_END = 1; // 0x1
+ field public static final int SNAP_TO_START = -1; // 0xffffffff
+ field protected final android.view.animation.DecelerateInterpolator mDecelerateInterpolator;
+ field protected int mInterimTargetDx;
+ field protected int mInterimTargetDy;
+ field protected final android.view.animation.LinearInterpolator mLinearInterpolator;
+ field protected android.graphics.PointF mTargetVector;
+ }
+
+ public class LinearSnapHelper extends android.support.v7.widget.SnapHelper {
+ ctor public LinearSnapHelper();
+ method public int[] calculateDistanceToFinalSnap(android.support.v7.widget.RecyclerView.LayoutManager, android.view.View);
+ method public android.view.View findSnapView(android.support.v7.widget.RecyclerView.LayoutManager);
+ method public int findTargetSnapPosition(android.support.v7.widget.RecyclerView.LayoutManager, int, int);
+ }
+
+ public class ListPopupWindow {
+ ctor public ListPopupWindow(android.content.Context);
+ ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet);
+ ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet, int);
+ ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet, int, int);
+ method public void clearListSelection();
+ method public android.view.View.OnTouchListener createDragToOpenListener(android.view.View);
+ method public void dismiss();
+ method public android.view.View getAnchorView();
+ method public int getAnimationStyle();
+ method public android.graphics.drawable.Drawable getBackground();
+ method public int getHeight();
+ method public int getHorizontalOffset();
+ method public int getInputMethodMode();
+ method public android.widget.ListView getListView();
+ method public int getPromptPosition();
+ method public java.lang.Object getSelectedItem();
+ method public long getSelectedItemId();
+ method public int getSelectedItemPosition();
+ method public android.view.View getSelectedView();
+ method public int getSoftInputMode();
+ method public int getVerticalOffset();
+ method public int getWidth();
+ method public boolean isInputMethodNotNeeded();
+ method public boolean isModal();
+ method public boolean isShowing();
+ method public boolean onKeyDown(int, android.view.KeyEvent);
+ method public boolean onKeyPreIme(int, android.view.KeyEvent);
+ method public boolean onKeyUp(int, android.view.KeyEvent);
+ method public boolean performItemClick(int);
+ method public void postShow();
+ method public void setAdapter(android.widget.ListAdapter);
+ method public void setAnchorView(android.view.View);
+ method public void setAnimationStyle(int);
+ method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
+ method public void setContentWidth(int);
+ method public void setDropDownGravity(int);
+ method public void setHeight(int);
+ method public void setHorizontalOffset(int);
+ method public void setInputMethodMode(int);
+ method public void setListSelector(android.graphics.drawable.Drawable);
+ method public void setModal(boolean);
+ method public void setOnDismissListener(android.widget.PopupWindow.OnDismissListener);
+ method public void setOnItemClickListener(android.widget.AdapterView.OnItemClickListener);
+ method public void setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener);
+ method public void setPromptPosition(int);
+ method public void setPromptView(android.view.View);
+ method public void setSelection(int);
+ method public void setSoftInputMode(int);
+ method public void setVerticalOffset(int);
+ method public void setWidth(int);
+ method public void setWindowLayoutType(int);
+ method public void show();
+ field public static final int INPUT_METHOD_FROM_FOCUSABLE = 0; // 0x0
+ field public static final int INPUT_METHOD_NEEDED = 1; // 0x1
+ field public static final int INPUT_METHOD_NOT_NEEDED = 2; // 0x2
+ field public static final int MATCH_PARENT = -1; // 0xffffffff
+ field public static final int POSITION_PROMPT_ABOVE = 0; // 0x0
+ field public static final int POSITION_PROMPT_BELOW = 1; // 0x1
+ field public static final int WRAP_CONTENT = -2; // 0xfffffffe
+ }
+
+ public abstract class OrientationHelper {
+ method public static android.support.v7.widget.OrientationHelper createHorizontalHelper(android.support.v7.widget.RecyclerView.LayoutManager);
+ method public static android.support.v7.widget.OrientationHelper createOrientationHelper(android.support.v7.widget.RecyclerView.LayoutManager, int);
+ method public static android.support.v7.widget.OrientationHelper createVerticalHelper(android.support.v7.widget.RecyclerView.LayoutManager);
+ method public abstract int getDecoratedEnd(android.view.View);
+ method public abstract int getDecoratedMeasurement(android.view.View);
+ method public abstract int getDecoratedMeasurementInOther(android.view.View);
+ method public abstract int getDecoratedStart(android.view.View);
+ method public abstract int getEnd();
+ method public abstract int getEndAfterPadding();
+ method public abstract int getEndPadding();
+ method public abstract int getMode();
+ method public abstract int getModeInOther();
+ method public abstract int getStartAfterPadding();
+ method public abstract int getTotalSpace();
+ method public int getTotalSpaceChange();
+ method public abstract int getTransformedEndWithDecoration(android.view.View);
+ method public abstract int getTransformedStartWithDecoration(android.view.View);
+ method public abstract void offsetChild(android.view.View, int);
+ method public abstract void offsetChildren(int);
+ method public void onLayoutComplete();
+ field public static final int HORIZONTAL = 0; // 0x0
+ field public static final int VERTICAL = 1; // 0x1
+ field protected final android.support.v7.widget.RecyclerView.LayoutManager mLayoutManager;
+ }
+
+ public class PagerSnapHelper extends android.support.v7.widget.SnapHelper {
+ ctor public PagerSnapHelper();
+ method public int[] calculateDistanceToFinalSnap(android.support.v7.widget.RecyclerView.LayoutManager, android.view.View);
+ method public android.view.View findSnapView(android.support.v7.widget.RecyclerView.LayoutManager);
+ method public int findTargetSnapPosition(android.support.v7.widget.RecyclerView.LayoutManager, int, int);
+ }
+
+ public class PopupMenu {
+ ctor public PopupMenu(android.content.Context, android.view.View);
+ ctor public PopupMenu(android.content.Context, android.view.View, int);
+ ctor public PopupMenu(android.content.Context, android.view.View, int, int, int);
+ method public void dismiss();
+ method public android.view.View.OnTouchListener getDragToOpenListener();
+ method public int getGravity();
+ method public android.view.Menu getMenu();
+ method public android.view.MenuInflater getMenuInflater();
+ method public void inflate(int);
+ method public void setGravity(int);
+ method public void setOnDismissListener(android.support.v7.widget.PopupMenu.OnDismissListener);
+ method public void setOnMenuItemClickListener(android.support.v7.widget.PopupMenu.OnMenuItemClickListener);
+ method public void show();
+ }
+
+ public static abstract interface PopupMenu.OnDismissListener {
+ method public abstract void onDismiss(android.support.v7.widget.PopupMenu);
+ }
+
+ public static abstract interface PopupMenu.OnMenuItemClickListener {
+ method public abstract boolean onMenuItemClick(android.view.MenuItem);
+ }
+
+ public class RecyclerView extends android.view.ViewGroup implements android.support.v4.view.NestedScrollingChild android.support.v4.view.ScrollingView {
+ ctor public RecyclerView(android.content.Context);
+ ctor public RecyclerView(android.content.Context, android.util.AttributeSet);
+ ctor public RecyclerView(android.content.Context, android.util.AttributeSet, int);
+ method public void addItemDecoration(android.support.v7.widget.RecyclerView.ItemDecoration, int);
+ method public void addItemDecoration(android.support.v7.widget.RecyclerView.ItemDecoration);
+ method public void addOnChildAttachStateChangeListener(android.support.v7.widget.RecyclerView.OnChildAttachStateChangeListener);
+ method public void addOnItemTouchListener(android.support.v7.widget.RecyclerView.OnItemTouchListener);
+ method public void addOnScrollListener(android.support.v7.widget.RecyclerView.OnScrollListener);
+ method public void clearOnChildAttachStateChangeListeners();
+ method public void clearOnScrollListeners();
+ method public int computeHorizontalScrollExtent();
+ method public int computeHorizontalScrollOffset();
+ method public int computeHorizontalScrollRange();
+ method public int computeVerticalScrollExtent();
+ method public int computeVerticalScrollOffset();
+ method public int computeVerticalScrollRange();
+ method public boolean drawChild(android.graphics.Canvas, android.view.View, long);
+ method public android.view.View findChildViewUnder(float, float);
+ method public android.view.View findContainingItemView(android.view.View);
+ method public android.support.v7.widget.RecyclerView.ViewHolder findContainingViewHolder(android.view.View);
+ method public android.support.v7.widget.RecyclerView.ViewHolder findViewHolderForAdapterPosition(int);
+ method public android.support.v7.widget.RecyclerView.ViewHolder findViewHolderForItemId(long);
+ method public android.support.v7.widget.RecyclerView.ViewHolder findViewHolderForLayoutPosition(int);
+ method public deprecated android.support.v7.widget.RecyclerView.ViewHolder findViewHolderForPosition(int);
+ method public boolean fling(int, int);
+ method public android.support.v7.widget.RecyclerView.Adapter getAdapter();
+ method public int getChildAdapterPosition(android.view.View);
+ method public long getChildItemId(android.view.View);
+ method public int getChildLayoutPosition(android.view.View);
+ method public deprecated int getChildPosition(android.view.View);
+ method public android.support.v7.widget.RecyclerView.ViewHolder getChildViewHolder(android.view.View);
+ method public android.support.v7.widget.RecyclerViewAccessibilityDelegate getCompatAccessibilityDelegate();
+ method public void getDecoratedBoundsWithMargins(android.view.View, android.graphics.Rect);
+ method public android.support.v7.widget.RecyclerView.ItemAnimator getItemAnimator();
+ method public android.support.v7.widget.RecyclerView.LayoutManager getLayoutManager();
+ method public int getMaxFlingVelocity();
+ method public int getMinFlingVelocity();
+ method public android.support.v7.widget.RecyclerView.OnFlingListener getOnFlingListener();
+ method public boolean getPreserveFocusAfterLayout();
+ method public android.support.v7.widget.RecyclerView.RecycledViewPool getRecycledViewPool();
+ method public int getScrollState();
+ method public boolean hasFixedSize();
+ method public boolean hasPendingAdapterUpdates();
+ method public void invalidateItemDecorations();
+ method public boolean isAnimating();
+ method public boolean isComputingLayout();
+ method public boolean isLayoutFrozen();
+ method public void offsetChildrenHorizontal(int);
+ method public void offsetChildrenVertical(int);
+ method public void onChildAttachedToWindow(android.view.View);
+ method public void onChildDetachedFromWindow(android.view.View);
+ method public void onDraw(android.graphics.Canvas);
+ method protected void onLayout(boolean, int, int, int, int);
+ method public void onScrollStateChanged(int);
+ method public void onScrolled(int, int);
+ method public void removeItemDecoration(android.support.v7.widget.RecyclerView.ItemDecoration);
+ method public void removeOnChildAttachStateChangeListener(android.support.v7.widget.RecyclerView.OnChildAttachStateChangeListener);
+ method public void removeOnItemTouchListener(android.support.v7.widget.RecyclerView.OnItemTouchListener);
+ method public void removeOnScrollListener(android.support.v7.widget.RecyclerView.OnScrollListener);
+ method public void scrollToPosition(int);
+ method public void setAccessibilityDelegateCompat(android.support.v7.widget.RecyclerViewAccessibilityDelegate);
+ method public void setAdapter(android.support.v7.widget.RecyclerView.Adapter);
+ method public void setChildDrawingOrderCallback(android.support.v7.widget.RecyclerView.ChildDrawingOrderCallback);
+ method public void setHasFixedSize(boolean);
+ method public void setItemAnimator(android.support.v7.widget.RecyclerView.ItemAnimator);
+ method public void setItemViewCacheSize(int);
+ method public void setLayoutFrozen(boolean);
+ method public void setLayoutManager(android.support.v7.widget.RecyclerView.LayoutManager);
+ method public void setOnFlingListener(android.support.v7.widget.RecyclerView.OnFlingListener);
+ method public deprecated void setOnScrollListener(android.support.v7.widget.RecyclerView.OnScrollListener);
+ method public void setPreserveFocusAfterLayout(boolean);
+ method public void setRecycledViewPool(android.support.v7.widget.RecyclerView.RecycledViewPool);
+ method public void setRecyclerListener(android.support.v7.widget.RecyclerView.RecyclerListener);
+ method public void setScrollingTouchSlop(int);
+ method public void setViewCacheExtension(android.support.v7.widget.RecyclerView.ViewCacheExtension);
+ method public void smoothScrollBy(int, int);
+ method public void smoothScrollBy(int, int, android.view.animation.Interpolator);
+ method public void smoothScrollToPosition(int);
+ method public void stopScroll();
+ method public void swapAdapter(android.support.v7.widget.RecyclerView.Adapter, boolean);
+ field public static final int HORIZONTAL = 0; // 0x0
+ field public static final int INVALID_TYPE = -1; // 0xffffffff
+ field public static final long NO_ID = -1L; // 0xffffffffffffffffL
+ field public static final int NO_POSITION = -1; // 0xffffffff
+ field public static final int SCROLL_STATE_DRAGGING = 1; // 0x1
+ field public static final int SCROLL_STATE_IDLE = 0; // 0x0
+ field public static final int SCROLL_STATE_SETTLING = 2; // 0x2
+ field public static final int TOUCH_SLOP_DEFAULT = 0; // 0x0
+ field public static final int TOUCH_SLOP_PAGING = 1; // 0x1
+ field public static final int VERTICAL = 1; // 0x1
+ }
+
+ public static abstract class RecyclerView.Adapter<VH extends android.support.v7.widget.RecyclerView.ViewHolder> {
+ ctor public RecyclerView.Adapter();
+ method public final void bindViewHolder(VH, int);
+ method public final VH createViewHolder(android.view.ViewGroup, int);
+ method public abstract int getItemCount();
+ method public long getItemId(int);
+ method public int getItemViewType(int);
+ method public final boolean hasObservers();
+ method public final boolean hasStableIds();
+ method public final void notifyDataSetChanged();
+ method public final void notifyItemChanged(int);
+ method public final void notifyItemChanged(int, java.lang.Object);
+ method public final void notifyItemInserted(int);
+ method public final void notifyItemMoved(int, int);
+ method public final void notifyItemRangeChanged(int, int);
+ method public final void notifyItemRangeChanged(int, int, java.lang.Object);
+ method public final void notifyItemRangeInserted(int, int);
+ method public final void notifyItemRangeRemoved(int, int);
+ method public final void notifyItemRemoved(int);
+ method public void onAttachedToRecyclerView(android.support.v7.widget.RecyclerView);
+ method public abstract void onBindViewHolder(VH, int);
+ method public void onBindViewHolder(VH, int, java.util.List<java.lang.Object>);
+ method public abstract VH onCreateViewHolder(android.view.ViewGroup, int);
+ method public void onDetachedFromRecyclerView(android.support.v7.widget.RecyclerView);
+ method public boolean onFailedToRecycleView(VH);
+ method public void onViewAttachedToWindow(VH);
+ method public void onViewDetachedFromWindow(VH);
+ method public void onViewRecycled(VH);
+ method public void registerAdapterDataObserver(android.support.v7.widget.RecyclerView.AdapterDataObserver);
+ method public void setHasStableIds(boolean);
+ method public void unregisterAdapterDataObserver(android.support.v7.widget.RecyclerView.AdapterDataObserver);
+ }
+
+ public static abstract class RecyclerView.AdapterDataObserver {
+ ctor public RecyclerView.AdapterDataObserver();
+ method public void onChanged();
+ method public void onItemRangeChanged(int, int);
+ method public void onItemRangeChanged(int, int, java.lang.Object);
+ method public void onItemRangeInserted(int, int);
+ method public void onItemRangeMoved(int, int, int);
+ method public void onItemRangeRemoved(int, int);
+ }
+
+ public static abstract interface RecyclerView.ChildDrawingOrderCallback {
+ method public abstract int onGetChildDrawingOrder(int, int);
+ }
+
+ public static abstract class RecyclerView.ItemAnimator {
+ ctor public RecyclerView.ItemAnimator();
+ method public abstract boolean animateAppearance(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+ method public abstract boolean animateChange(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+ method public abstract boolean animateDisappearance(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+ method public abstract boolean animatePersistence(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+ method public boolean canReuseUpdatedViewHolder(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public boolean canReuseUpdatedViewHolder(android.support.v7.widget.RecyclerView.ViewHolder, java.util.List<java.lang.Object>);
+ method public final void dispatchAnimationFinished(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public final void dispatchAnimationStarted(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public final void dispatchAnimationsFinished();
+ method public abstract void endAnimation(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public abstract void endAnimations();
+ method public long getAddDuration();
+ method public long getChangeDuration();
+ method public long getMoveDuration();
+ method public long getRemoveDuration();
+ method public abstract boolean isRunning();
+ method public final boolean isRunning(android.support.v7.widget.RecyclerView.ItemAnimator.ItemAnimatorFinishedListener);
+ method public android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo obtainHolderInfo();
+ method public void onAnimationFinished(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public void onAnimationStarted(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo recordPostLayoutInformation(android.support.v7.widget.RecyclerView.State, android.support.v7.widget.RecyclerView.ViewHolder);
+ method public android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo recordPreLayoutInformation(android.support.v7.widget.RecyclerView.State, android.support.v7.widget.RecyclerView.ViewHolder, int, java.util.List<java.lang.Object>);
+ method public abstract void runPendingAnimations();
+ method public void setAddDuration(long);
+ method public void setChangeDuration(long);
+ method public void setMoveDuration(long);
+ method public void setRemoveDuration(long);
+ field public static final int FLAG_APPEARED_IN_PRE_LAYOUT = 4096; // 0x1000
+ field public static final int FLAG_CHANGED = 2; // 0x2
+ field public static final int FLAG_INVALIDATED = 4; // 0x4
+ field public static final int FLAG_MOVED = 2048; // 0x800
+ field public static final int FLAG_REMOVED = 8; // 0x8
+ }
+
+ public static abstract class RecyclerView.ItemAnimator.AdapterChanges implements java.lang.annotation.Annotation {
+ }
+
+ public static abstract interface RecyclerView.ItemAnimator.ItemAnimatorFinishedListener {
+ method public abstract void onAnimationsFinished();
+ }
+
+ public static class RecyclerView.ItemAnimator.ItemHolderInfo {
+ ctor public RecyclerView.ItemAnimator.ItemHolderInfo();
+ method public android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo setFrom(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo setFrom(android.support.v7.widget.RecyclerView.ViewHolder, int);
+ field public int bottom;
+ field public int changeFlags;
+ field public int left;
+ field public int right;
+ field public int top;
+ }
+
+ public static abstract class RecyclerView.ItemDecoration {
+ ctor public RecyclerView.ItemDecoration();
+ method public deprecated void getItemOffsets(android.graphics.Rect, int, android.support.v7.widget.RecyclerView);
+ method public void getItemOffsets(android.graphics.Rect, android.view.View, android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.State);
+ method public void onDraw(android.graphics.Canvas, android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.State);
+ method public deprecated void onDraw(android.graphics.Canvas, android.support.v7.widget.RecyclerView);
+ method public void onDrawOver(android.graphics.Canvas, android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.State);
+ method public deprecated void onDrawOver(android.graphics.Canvas, android.support.v7.widget.RecyclerView);
+ }
+
+ public static abstract class RecyclerView.LayoutManager {
+ ctor public RecyclerView.LayoutManager();
+ method public void addDisappearingView(android.view.View);
+ method public void addDisappearingView(android.view.View, int);
+ method public void addView(android.view.View);
+ method public void addView(android.view.View, int);
+ method public void assertInLayoutOrScroll(java.lang.String);
+ method public void assertNotInLayoutOrScroll(java.lang.String);
+ method public void attachView(android.view.View, int, android.support.v7.widget.RecyclerView.LayoutParams);
+ method public void attachView(android.view.View, int);
+ method public void attachView(android.view.View);
+ method public void calculateItemDecorationsForChild(android.view.View, android.graphics.Rect);
+ method public boolean canScrollHorizontally();
+ method public boolean canScrollVertically();
+ method public boolean checkLayoutParams(android.support.v7.widget.RecyclerView.LayoutParams);
+ method public static int chooseSize(int, int, int);
+ method public void collectAdjacentPrefetchPositions(int, int, android.support.v7.widget.RecyclerView.State, android.support.v7.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry);
+ method public void collectInitialPrefetchPositions(int, android.support.v7.widget.RecyclerView.LayoutManager.LayoutPrefetchRegistry);
+ method public int computeHorizontalScrollExtent(android.support.v7.widget.RecyclerView.State);
+ method public int computeHorizontalScrollOffset(android.support.v7.widget.RecyclerView.State);
+ method public int computeHorizontalScrollRange(android.support.v7.widget.RecyclerView.State);
+ method public int computeVerticalScrollExtent(android.support.v7.widget.RecyclerView.State);
+ method public int computeVerticalScrollOffset(android.support.v7.widget.RecyclerView.State);
+ method public int computeVerticalScrollRange(android.support.v7.widget.RecyclerView.State);
+ method public void detachAndScrapAttachedViews(android.support.v7.widget.RecyclerView.Recycler);
+ method public void detachAndScrapView(android.view.View, android.support.v7.widget.RecyclerView.Recycler);
+ method public void detachAndScrapViewAt(int, android.support.v7.widget.RecyclerView.Recycler);
+ method public void detachView(android.view.View);
+ method public void detachViewAt(int);
+ method public void endAnimation(android.view.View);
+ method public android.view.View findContainingItemView(android.view.View);
+ method public android.view.View findViewByPosition(int);
+ method public abstract android.support.v7.widget.RecyclerView.LayoutParams generateDefaultLayoutParams();
+ method public android.support.v7.widget.RecyclerView.LayoutParams generateLayoutParams(android.view.ViewGroup.LayoutParams);
+ method public android.support.v7.widget.RecyclerView.LayoutParams generateLayoutParams(android.content.Context, android.util.AttributeSet);
+ method public int getBaseline();
+ method public int getBottomDecorationHeight(android.view.View);
+ method public android.view.View getChildAt(int);
+ method public int getChildCount();
+ method public static deprecated int getChildMeasureSpec(int, int, int, boolean);
+ method public static int getChildMeasureSpec(int, int, int, int, boolean);
+ method public boolean getClipToPadding();
+ method public int getColumnCountForAccessibility(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
+ method public int getDecoratedBottom(android.view.View);
+ method public void getDecoratedBoundsWithMargins(android.view.View, android.graphics.Rect);
+ method public int getDecoratedLeft(android.view.View);
+ method public int getDecoratedMeasuredHeight(android.view.View);
+ method public int getDecoratedMeasuredWidth(android.view.View);
+ method public int getDecoratedRight(android.view.View);
+ method public int getDecoratedTop(android.view.View);
+ method public android.view.View getFocusedChild();
+ method public int getHeight();
+ method public int getHeightMode();
+ method public int getItemCount();
+ method public int getItemViewType(android.view.View);
+ method public int getLayoutDirection();
+ method public int getLeftDecorationWidth(android.view.View);
+ method public int getMinimumHeight();
+ method public int getMinimumWidth();
+ method public int getPaddingBottom();
+ method public int getPaddingEnd();
+ method public int getPaddingLeft();
+ method public int getPaddingRight();
+ method public int getPaddingStart();
+ method public int getPaddingTop();
+ method public int getPosition(android.view.View);
+ method public static android.support.v7.widget.RecyclerView.LayoutManager.Properties getProperties(android.content.Context, android.util.AttributeSet, int, int);
+ method public int getRightDecorationWidth(android.view.View);
+ method public int getRowCountForAccessibility(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
+ method public int getSelectionModeForAccessibility(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
+ method public int getTopDecorationHeight(android.view.View);
+ method public void getTransformedBoundingBox(android.view.View, boolean, android.graphics.Rect);
+ method public int getWidth();
+ method public int getWidthMode();
+ method public boolean hasFocus();
+ method public void ignoreView(android.view.View);
+ method public boolean isAttachedToWindow();
+ method public boolean isAutoMeasureEnabled();
+ method public boolean isFocused();
+ method public final boolean isItemPrefetchEnabled();
+ method public boolean isLayoutHierarchical(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
+ method public boolean isMeasurementCacheEnabled();
+ method public boolean isSmoothScrolling();
+ method public boolean isViewPartiallyVisible(android.view.View, boolean, boolean);
+ method public void layoutDecorated(android.view.View, int, int, int, int);
+ method public void layoutDecoratedWithMargins(android.view.View, int, int, int, int);
+ method public void measureChild(android.view.View, int, int);
+ method public void measureChildWithMargins(android.view.View, int, int);
+ method public void moveView(int, int);
+ method public void offsetChildrenHorizontal(int);
+ method public void offsetChildrenVertical(int);
+ method public void onAdapterChanged(android.support.v7.widget.RecyclerView.Adapter, android.support.v7.widget.RecyclerView.Adapter);
+ method public boolean onAddFocusables(android.support.v7.widget.RecyclerView, java.util.ArrayList<android.view.View>, int, int);
+ method public void onAttachedToWindow(android.support.v7.widget.RecyclerView);
+ method public deprecated void onDetachedFromWindow(android.support.v7.widget.RecyclerView);
+ method public void onDetachedFromWindow(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.Recycler);
+ method public android.view.View onFocusSearchFailed(android.view.View, int, android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
+ method public void onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
+ method public void onInitializeAccessibilityEvent(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State, android.view.accessibility.AccessibilityEvent);
+ method public void onInitializeAccessibilityNodeInfo(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State, android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+ method public void onInitializeAccessibilityNodeInfoForItem(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State, android.view.View, android.support.v4.view.accessibility.AccessibilityNodeInfoCompat);
+ method public android.view.View onInterceptFocusSearch(android.view.View, int);
+ method public void onItemsAdded(android.support.v7.widget.RecyclerView, int, int);
+ method public void onItemsChanged(android.support.v7.widget.RecyclerView);
+ method public void onItemsMoved(android.support.v7.widget.RecyclerView, int, int, int);
+ method public void onItemsRemoved(android.support.v7.widget.RecyclerView, int, int);
+ method public void onItemsUpdated(android.support.v7.widget.RecyclerView, int, int);
+ method public void onItemsUpdated(android.support.v7.widget.RecyclerView, int, int, java.lang.Object);
+ method public void onLayoutChildren(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
+ method public void onLayoutCompleted(android.support.v7.widget.RecyclerView.State);
+ method public void onMeasure(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State, int, int);
+ method public deprecated boolean onRequestChildFocus(android.support.v7.widget.RecyclerView, android.view.View, android.view.View);
+ method public boolean onRequestChildFocus(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.State, android.view.View, android.view.View);
+ method public void onRestoreInstanceState(android.os.Parcelable);
+ method public android.os.Parcelable onSaveInstanceState();
+ method public void onScrollStateChanged(int);
+ method public boolean performAccessibilityAction(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State, int, android.os.Bundle);
+ method public boolean performAccessibilityActionForItem(android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State, android.view.View, int, android.os.Bundle);
+ method public void postOnAnimation(java.lang.Runnable);
+ method public void removeAllViews();
+ method public void removeAndRecycleAllViews(android.support.v7.widget.RecyclerView.Recycler);
+ method public void removeAndRecycleView(android.view.View, android.support.v7.widget.RecyclerView.Recycler);
+ method public void removeAndRecycleViewAt(int, android.support.v7.widget.RecyclerView.Recycler);
+ method public boolean removeCallbacks(java.lang.Runnable);
+ method public void removeDetachedView(android.view.View);
+ method public void removeView(android.view.View);
+ method public void removeViewAt(int);
+ method public boolean requestChildRectangleOnScreen(android.support.v7.widget.RecyclerView, android.view.View, android.graphics.Rect, boolean);
+ method public boolean requestChildRectangleOnScreen(android.support.v7.widget.RecyclerView, android.view.View, android.graphics.Rect, boolean, boolean);
+ method public void requestLayout();
+ method public void requestSimpleAnimationsInNextLayout();
+ method public int scrollHorizontallyBy(int, android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
+ method public void scrollToPosition(int);
+ method public int scrollVerticallyBy(int, android.support.v7.widget.RecyclerView.Recycler, android.support.v7.widget.RecyclerView.State);
+ method public void setAutoMeasureEnabled(boolean);
+ method public final void setItemPrefetchEnabled(boolean);
+ method public void setMeasuredDimension(android.graphics.Rect, int, int);
+ method public void setMeasuredDimension(int, int);
+ method public void setMeasurementCacheEnabled(boolean);
+ method public void smoothScrollToPosition(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.State, int);
+ method public void startSmoothScroll(android.support.v7.widget.RecyclerView.SmoothScroller);
+ method public void stopIgnoringView(android.view.View);
+ method public boolean supportsPredictiveItemAnimations();
+ }
+
+ public static abstract interface RecyclerView.LayoutManager.LayoutPrefetchRegistry {
+ method public abstract void addPosition(int, int);
+ }
+
+ public static class RecyclerView.LayoutManager.Properties {
+ ctor public RecyclerView.LayoutManager.Properties();
+ field public int orientation;
+ field public boolean reverseLayout;
+ field public int spanCount;
+ field public boolean stackFromEnd;
+ }
+
+ public static class RecyclerView.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+ ctor public RecyclerView.LayoutParams(android.content.Context, android.util.AttributeSet);
+ ctor public RecyclerView.LayoutParams(int, int);
+ ctor public RecyclerView.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ ctor public RecyclerView.LayoutParams(android.view.ViewGroup.LayoutParams);
+ ctor public RecyclerView.LayoutParams(android.support.v7.widget.RecyclerView.LayoutParams);
+ method public int getViewAdapterPosition();
+ method public int getViewLayoutPosition();
+ method public deprecated int getViewPosition();
+ method public boolean isItemChanged();
+ method public boolean isItemRemoved();
+ method public boolean isViewInvalid();
+ method public boolean viewNeedsUpdate();
+ }
+
+ public static abstract interface RecyclerView.OnChildAttachStateChangeListener {
+ method public abstract void onChildViewAttachedToWindow(android.view.View);
+ method public abstract void onChildViewDetachedFromWindow(android.view.View);
+ }
+
+ public static abstract class RecyclerView.OnFlingListener {
+ ctor public RecyclerView.OnFlingListener();
+ method public abstract boolean onFling(int, int);
+ }
+
+ public static abstract interface RecyclerView.OnItemTouchListener {
+ method public abstract boolean onInterceptTouchEvent(android.support.v7.widget.RecyclerView, android.view.MotionEvent);
+ method public abstract void onRequestDisallowInterceptTouchEvent(boolean);
+ method public abstract void onTouchEvent(android.support.v7.widget.RecyclerView, android.view.MotionEvent);
+ }
+
+ public static abstract class RecyclerView.OnScrollListener {
+ ctor public RecyclerView.OnScrollListener();
+ method public void onScrollStateChanged(android.support.v7.widget.RecyclerView, int);
+ method public void onScrolled(android.support.v7.widget.RecyclerView, int, int);
+ }
+
+ public static class RecyclerView.RecycledViewPool {
+ ctor public RecyclerView.RecycledViewPool();
+ method public void clear();
+ method public android.support.v7.widget.RecyclerView.ViewHolder getRecycledView(int);
+ method public int getRecycledViewCount(int);
+ method public void putRecycledView(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public void setMaxRecycledViews(int, int);
+ }
+
+ public final class RecyclerView.Recycler {
+ ctor public RecyclerView.Recycler();
+ method public void bindViewToPosition(android.view.View, int);
+ method public void clear();
+ method public int convertPreLayoutPositionToPostLayout(int);
+ method public java.util.List<android.support.v7.widget.RecyclerView.ViewHolder> getScrapList();
+ method public android.view.View getViewForPosition(int);
+ method public void recycleView(android.view.View);
+ method public void setViewCacheSize(int);
+ }
+
+ public static abstract interface RecyclerView.RecyclerListener {
+ method public abstract void onViewRecycled(android.support.v7.widget.RecyclerView.ViewHolder);
+ }
+
+ public static class RecyclerView.SimpleOnItemTouchListener implements android.support.v7.widget.RecyclerView.OnItemTouchListener {
+ ctor public RecyclerView.SimpleOnItemTouchListener();
+ method public boolean onInterceptTouchEvent(android.support.v7.widget.RecyclerView, android.view.MotionEvent);
+ method public void onRequestDisallowInterceptTouchEvent(boolean);
+ method public void onTouchEvent(android.support.v7.widget.RecyclerView, android.view.MotionEvent);
+ }
+
+ public static abstract class RecyclerView.SmoothScroller {
+ ctor public RecyclerView.SmoothScroller();
+ method public android.view.View findViewByPosition(int);
+ method public int getChildCount();
+ method public int getChildPosition(android.view.View);
+ method public android.support.v7.widget.RecyclerView.LayoutManager getLayoutManager();
+ method public int getTargetPosition();
+ method public deprecated void instantScrollToPosition(int);
+ method public boolean isPendingInitialRun();
+ method public boolean isRunning();
+ method protected void normalize(android.graphics.PointF);
+ method protected void onChildAttachedToWindow(android.view.View);
+ method protected abstract void onSeekTargetStep(int, int, android.support.v7.widget.RecyclerView.State, android.support.v7.widget.RecyclerView.SmoothScroller.Action);
+ method protected abstract void onStart();
+ method protected abstract void onStop();
+ method protected abstract void onTargetFound(android.view.View, android.support.v7.widget.RecyclerView.State, android.support.v7.widget.RecyclerView.SmoothScroller.Action);
+ method public void setTargetPosition(int);
+ method protected final void stop();
+ }
+
+ public static class RecyclerView.SmoothScroller.Action {
+ ctor public RecyclerView.SmoothScroller.Action(int, int);
+ ctor public RecyclerView.SmoothScroller.Action(int, int, int);
+ ctor public RecyclerView.SmoothScroller.Action(int, int, int, android.view.animation.Interpolator);
+ method public int getDuration();
+ method public int getDx();
+ method public int getDy();
+ method public android.view.animation.Interpolator getInterpolator();
+ method public void jumpTo(int);
+ method public void setDuration(int);
+ method public void setDx(int);
+ method public void setDy(int);
+ method public void setInterpolator(android.view.animation.Interpolator);
+ method public void update(int, int, int, android.view.animation.Interpolator);
+ field public static final int UNDEFINED_DURATION = -2147483648; // 0x80000000
+ }
+
+ public static abstract interface RecyclerView.SmoothScroller.ScrollVectorProvider {
+ method public abstract android.graphics.PointF computeScrollVectorForPosition(int);
+ }
+
+ public static class RecyclerView.State {
+ ctor public RecyclerView.State();
+ method public boolean didStructureChange();
+ method public <T> T get(int);
+ method public int getItemCount();
+ method public int getTargetScrollPosition();
+ method public boolean hasTargetScrollPosition();
+ method public boolean isMeasuring();
+ method public boolean isPreLayout();
+ method public void put(int, java.lang.Object);
+ method public void remove(int);
+ method public boolean willRunPredictiveAnimations();
+ method public boolean willRunSimpleAnimations();
+ }
+
+ public static abstract class RecyclerView.ViewCacheExtension {
+ ctor public RecyclerView.ViewCacheExtension();
+ method public abstract android.view.View getViewForPositionAndType(android.support.v7.widget.RecyclerView.Recycler, int, int);
+ }
+
+ public static abstract class RecyclerView.ViewHolder {
+ ctor public RecyclerView.ViewHolder(android.view.View);
+ method public final int getAdapterPosition();
+ method public final long getItemId();
+ method public final int getItemViewType();
+ method public final int getLayoutPosition();
+ method public final int getOldPosition();
+ method public final deprecated int getPosition();
+ method public final boolean isRecyclable();
+ method public final void setIsRecyclable(boolean);
+ field public final android.view.View itemView;
+ }
+
+ public class RecyclerViewAccessibilityDelegate extends android.support.v4.view.AccessibilityDelegateCompat {
+ ctor public RecyclerViewAccessibilityDelegate(android.support.v7.widget.RecyclerView);
+ method public android.support.v4.view.AccessibilityDelegateCompat getItemDelegate();
+ }
+
+ public static class RecyclerViewAccessibilityDelegate.ItemDelegate extends android.support.v4.view.AccessibilityDelegateCompat {
+ ctor public RecyclerViewAccessibilityDelegate.ItemDelegate(android.support.v7.widget.RecyclerViewAccessibilityDelegate);
+ }
+
+ public class SearchView extends android.support.v7.widget.LinearLayoutCompat implements android.support.v7.view.CollapsibleActionView {
+ ctor public SearchView(android.content.Context);
+ ctor public SearchView(android.content.Context, android.util.AttributeSet);
+ ctor public SearchView(android.content.Context, android.util.AttributeSet, int);
+ method public int getImeOptions();
+ method public int getInputType();
+ method public int getMaxWidth();
+ method public java.lang.CharSequence getQuery();
+ method public java.lang.CharSequence getQueryHint();
+ method public android.support.v4.widget.CursorAdapter getSuggestionsAdapter();
+ method public boolean isIconfiedByDefault();
+ method public boolean isIconified();
+ method public boolean isQueryRefinementEnabled();
+ method public boolean isSubmitButtonEnabled();
+ method public void onActionViewCollapsed();
+ method public void onActionViewExpanded();
+ method public void setIconified(boolean);
+ method public void setIconifiedByDefault(boolean);
+ method public void setImeOptions(int);
+ method public void setInputType(int);
+ method public void setMaxWidth(int);
+ method public void setOnCloseListener(android.support.v7.widget.SearchView.OnCloseListener);
+ method public void setOnQueryTextFocusChangeListener(android.view.View.OnFocusChangeListener);
+ method public void setOnQueryTextListener(android.support.v7.widget.SearchView.OnQueryTextListener);
+ method public void setOnSearchClickListener(android.view.View.OnClickListener);
+ method public void setOnSuggestionListener(android.support.v7.widget.SearchView.OnSuggestionListener);
+ method public void setQuery(java.lang.CharSequence, boolean);
+ method public void setQueryHint(java.lang.CharSequence);
+ method public void setQueryRefinementEnabled(boolean);
+ method public void setSearchableInfo(android.app.SearchableInfo);
+ method public void setSubmitButtonEnabled(boolean);
+ method public void setSuggestionsAdapter(android.support.v4.widget.CursorAdapter);
+ }
+
+ public static abstract interface SearchView.OnCloseListener {
+ method public abstract boolean onClose();
+ }
+
+ public static abstract interface SearchView.OnQueryTextListener {
+ method public abstract boolean onQueryTextChange(java.lang.String);
+ method public abstract boolean onQueryTextSubmit(java.lang.String);
+ }
+
+ public static abstract interface SearchView.OnSuggestionListener {
+ method public abstract boolean onSuggestionClick(int);
+ method public abstract boolean onSuggestionSelect(int);
+ }
+
+ public class ShareActionProvider extends android.support.v4.view.ActionProvider {
+ ctor public ShareActionProvider(android.content.Context);
+ method public android.view.View onCreateActionView();
+ method public void setOnShareTargetSelectedListener(android.support.v7.widget.ShareActionProvider.OnShareTargetSelectedListener);
+ method public void setShareHistoryFileName(java.lang.String);
+ method public void setShareIntent(android.content.Intent);
+ field public static final java.lang.String DEFAULT_SHARE_HISTORY_FILE_NAME = "share_history.xml";
+ }
+
+ public static abstract interface ShareActionProvider.OnShareTargetSelectedListener {
+ method public abstract boolean onShareTargetSelected(android.support.v7.widget.ShareActionProvider, android.content.Intent);
+ }
+
+ public abstract class SimpleItemAnimator extends android.support.v7.widget.RecyclerView.ItemAnimator {
+ ctor public SimpleItemAnimator();
+ method public abstract boolean animateAdd(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public boolean animateAppearance(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+ method public boolean animateChange(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+ method public abstract boolean animateChange(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ViewHolder, int, int, int, int);
+ method public boolean animateDisappearance(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+ method public abstract boolean animateMove(android.support.v7.widget.RecyclerView.ViewHolder, int, int, int, int);
+ method public boolean animatePersistence(android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo, android.support.v7.widget.RecyclerView.ItemAnimator.ItemHolderInfo);
+ method public abstract boolean animateRemove(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public final void dispatchAddFinished(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public final void dispatchAddStarting(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public final void dispatchChangeFinished(android.support.v7.widget.RecyclerView.ViewHolder, boolean);
+ method public final void dispatchChangeStarting(android.support.v7.widget.RecyclerView.ViewHolder, boolean);
+ method public final void dispatchMoveFinished(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public final void dispatchMoveStarting(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public final void dispatchRemoveFinished(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public final void dispatchRemoveStarting(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public boolean getSupportsChangeAnimations();
+ method public void onAddFinished(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public void onAddStarting(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public void onChangeFinished(android.support.v7.widget.RecyclerView.ViewHolder, boolean);
+ method public void onChangeStarting(android.support.v7.widget.RecyclerView.ViewHolder, boolean);
+ method public void onMoveFinished(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public void onMoveStarting(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public void onRemoveFinished(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public void onRemoveStarting(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public void setSupportsChangeAnimations(boolean);
+ }
+
+ public abstract class SnapHelper extends android.support.v7.widget.RecyclerView.OnFlingListener {
+ ctor public SnapHelper();
+ method public void attachToRecyclerView(android.support.v7.widget.RecyclerView) throws java.lang.IllegalStateException;
+ method public abstract int[] calculateDistanceToFinalSnap(android.support.v7.widget.RecyclerView.LayoutManager, android.view.View);
+ method public int[] calculateScrollDistance(int, int);
+ method protected android.support.v7.widget.LinearSmoothScroller createSnapScroller(android.support.v7.widget.RecyclerView.LayoutManager);
+ method public abstract android.view.View findSnapView(android.support.v7.widget.RecyclerView.LayoutManager);
+ method public abstract int findTargetSnapPosition(android.support.v7.widget.RecyclerView.LayoutManager, int, int);
+ method public boolean onFling(int, int);
+ }
+
+ public class StaggeredGridLayoutManager extends android.support.v7.widget.RecyclerView.LayoutManager implements android.support.v7.widget.RecyclerView.SmoothScroller.ScrollVectorProvider {
+ ctor public StaggeredGridLayoutManager(android.content.Context, android.util.AttributeSet, int, int);
+ ctor public StaggeredGridLayoutManager(int, int);
+ method public android.graphics.PointF computeScrollVectorForPosition(int);
+ method public int[] findFirstCompletelyVisibleItemPositions(int[]);
+ method public int[] findFirstVisibleItemPositions(int[]);
+ method public int[] findLastCompletelyVisibleItemPositions(int[]);
+ method public int[] findLastVisibleItemPositions(int[]);
+ method public android.support.v7.widget.RecyclerView.LayoutParams generateDefaultLayoutParams();
+ method public int getGapStrategy();
+ method public int getOrientation();
+ method public boolean getReverseLayout();
+ method public int getSpanCount();
+ method public void invalidateSpanAssignments();
+ method public void scrollToPositionWithOffset(int, int);
+ method public void setGapStrategy(int);
+ method public void setOrientation(int);
+ method public void setReverseLayout(boolean);
+ method public void setSpanCount(int);
+ field public static final deprecated int GAP_HANDLING_LAZY = 1; // 0x1
+ field public static final int GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS = 2; // 0x2
+ field public static final int GAP_HANDLING_NONE = 0; // 0x0
+ field public static final int HORIZONTAL = 0; // 0x0
+ field public static final int VERTICAL = 1; // 0x1
+ }
+
+ public static class StaggeredGridLayoutManager.LayoutParams extends android.support.v7.widget.RecyclerView.LayoutParams {
+ ctor public StaggeredGridLayoutManager.LayoutParams(android.content.Context, android.util.AttributeSet);
+ ctor public StaggeredGridLayoutManager.LayoutParams(int, int);
+ ctor public StaggeredGridLayoutManager.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ ctor public StaggeredGridLayoutManager.LayoutParams(android.view.ViewGroup.LayoutParams);
+ ctor public StaggeredGridLayoutManager.LayoutParams(android.support.v7.widget.RecyclerView.LayoutParams);
+ method public final int getSpanIndex();
+ method public boolean isFullSpan();
+ method public void setFullSpan(boolean);
+ field public static final int INVALID_SPAN_ID = -1; // 0xffffffff
+ }
+
+ public class SwitchCompat extends android.widget.CompoundButton {
+ ctor public SwitchCompat(android.content.Context);
+ ctor public SwitchCompat(android.content.Context, android.util.AttributeSet);
+ ctor public SwitchCompat(android.content.Context, android.util.AttributeSet, int);
+ method public boolean getShowText();
+ method public boolean getSplitTrack();
+ method public int getSwitchMinWidth();
+ method public int getSwitchPadding();
+ method public java.lang.CharSequence getTextOff();
+ method public java.lang.CharSequence getTextOn();
+ method public android.graphics.drawable.Drawable getThumbDrawable();
+ method public int getThumbTextPadding();
+ method public android.content.res.ColorStateList getThumbTintList();
+ method public android.graphics.PorterDuff.Mode getThumbTintMode();
+ method public android.graphics.drawable.Drawable getTrackDrawable();
+ method public android.content.res.ColorStateList getTrackTintList();
+ method public android.graphics.PorterDuff.Mode getTrackTintMode();
+ method public void onMeasure(int, int);
+ method public void setShowText(boolean);
+ method public void setSplitTrack(boolean);
+ method public void setSwitchMinWidth(int);
+ method public void setSwitchPadding(int);
+ method public void setSwitchTextAppearance(android.content.Context, int);
+ method public void setSwitchTypeface(android.graphics.Typeface, int);
+ method public void setSwitchTypeface(android.graphics.Typeface);
+ method public void setTextOff(java.lang.CharSequence);
+ method public void setTextOn(java.lang.CharSequence);
+ method public void setThumbDrawable(android.graphics.drawable.Drawable);
+ method public void setThumbResource(int);
+ method public void setThumbTextPadding(int);
+ method public void setThumbTintList(android.content.res.ColorStateList);
+ method public void setThumbTintMode(android.graphics.PorterDuff.Mode);
+ method public void setTrackDrawable(android.graphics.drawable.Drawable);
+ method public void setTrackResource(int);
+ method public void setTrackTintList(android.content.res.ColorStateList);
+ method public void setTrackTintMode(android.graphics.PorterDuff.Mode);
+ }
+
+ public abstract interface ThemedSpinnerAdapter implements android.widget.SpinnerAdapter {
+ method public abstract android.content.res.Resources.Theme getDropDownViewTheme();
+ method public abstract void setDropDownViewTheme(android.content.res.Resources.Theme);
+ }
+
+ public static final class ThemedSpinnerAdapter.Helper {
+ ctor public ThemedSpinnerAdapter.Helper(android.content.Context);
+ method public android.view.LayoutInflater getDropDownViewInflater();
+ method public android.content.res.Resources.Theme getDropDownViewTheme();
+ method public void setDropDownViewTheme(android.content.res.Resources.Theme);
+ }
+
+ public class Toolbar extends android.view.ViewGroup {
+ ctor public Toolbar(android.content.Context);
+ ctor public Toolbar(android.content.Context, android.util.AttributeSet);
+ ctor public Toolbar(android.content.Context, android.util.AttributeSet, int);
+ method public void collapseActionView();
+ method public void dismissPopupMenus();
+ method public int getContentInsetEnd();
+ method public int getContentInsetEndWithActions();
+ method public int getContentInsetLeft();
+ method public int getContentInsetRight();
+ method public int getContentInsetStart();
+ method public int getContentInsetStartWithNavigation();
+ method public int getCurrentContentInsetEnd();
+ method public int getCurrentContentInsetLeft();
+ method public int getCurrentContentInsetRight();
+ method public int getCurrentContentInsetStart();
+ method public android.graphics.drawable.Drawable getLogo();
+ method public java.lang.CharSequence getLogoDescription();
+ method public android.view.Menu getMenu();
+ method public java.lang.CharSequence getNavigationContentDescription();
+ method public android.graphics.drawable.Drawable getNavigationIcon();
+ method public android.graphics.drawable.Drawable getOverflowIcon();
+ method public int getPopupTheme();
+ method public java.lang.CharSequence getSubtitle();
+ method public java.lang.CharSequence getTitle();
+ method public int getTitleMarginBottom();
+ method public int getTitleMarginEnd();
+ method public int getTitleMarginStart();
+ method public int getTitleMarginTop();
+ method public boolean hasExpandedActionView();
+ method public boolean hideOverflowMenu();
+ method public void inflateMenu(int);
+ method public boolean isOverflowMenuShowing();
+ method protected void onLayout(boolean, int, int, int, int);
+ method public void setContentInsetEndWithActions(int);
+ method public void setContentInsetStartWithNavigation(int);
+ method public void setContentInsetsAbsolute(int, int);
+ method public void setContentInsetsRelative(int, int);
+ method public void setLogo(int);
+ method public void setLogo(android.graphics.drawable.Drawable);
+ method public void setLogoDescription(int);
+ method public void setLogoDescription(java.lang.CharSequence);
+ method public void setNavigationContentDescription(int);
+ method public void setNavigationContentDescription(java.lang.CharSequence);
+ method public void setNavigationIcon(int);
+ method public void setNavigationIcon(android.graphics.drawable.Drawable);
+ method public void setNavigationOnClickListener(android.view.View.OnClickListener);
+ method public void setOnMenuItemClickListener(android.support.v7.widget.Toolbar.OnMenuItemClickListener);
+ method public void setOverflowIcon(android.graphics.drawable.Drawable);
+ method public void setPopupTheme(int);
+ method public void setSubtitle(int);
+ method public void setSubtitle(java.lang.CharSequence);
+ method public void setSubtitleTextAppearance(android.content.Context, int);
+ method public void setSubtitleTextColor(int);
+ method public void setTitle(int);
+ method public void setTitle(java.lang.CharSequence);
+ method public void setTitleMargin(int, int, int, int);
+ method public void setTitleMarginBottom(int);
+ method public void setTitleMarginEnd(int);
+ method public void setTitleMarginStart(int);
+ method public void setTitleMarginTop(int);
+ method public void setTitleTextAppearance(android.content.Context, int);
+ method public void setTitleTextColor(int);
+ method public boolean showOverflowMenu();
+ }
+
+ public static class Toolbar.LayoutParams extends android.support.v7.app.ActionBar.LayoutParams {
+ ctor public Toolbar.LayoutParams(android.content.Context, android.util.AttributeSet);
+ ctor public Toolbar.LayoutParams(int, int);
+ ctor public Toolbar.LayoutParams(int, int, int);
+ ctor public Toolbar.LayoutParams(int);
+ ctor public Toolbar.LayoutParams(android.support.v7.widget.Toolbar.LayoutParams);
+ ctor public Toolbar.LayoutParams(android.support.v7.app.ActionBar.LayoutParams);
+ ctor public Toolbar.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ ctor public Toolbar.LayoutParams(android.view.ViewGroup.LayoutParams);
+ }
+
+ public static abstract interface Toolbar.OnMenuItemClickListener {
+ method public abstract boolean onMenuItemClick(android.view.MenuItem);
+ }
+
+ public static class Toolbar.SavedState extends android.support.v4.view.AbsSavedState {
+ ctor public Toolbar.SavedState(android.os.Parcel);
+ ctor public Toolbar.SavedState(android.os.Parcel, java.lang.ClassLoader);
+ ctor public Toolbar.SavedState(android.os.Parcelable);
+ field public static final android.os.Parcelable.Creator<android.support.v7.widget.Toolbar.SavedState> CREATOR;
+ }
+
+}
+
+package android.support.v7.widget.helper {
+
+ public class ItemTouchHelper extends android.support.v7.widget.RecyclerView.ItemDecoration implements android.support.v7.widget.RecyclerView.OnChildAttachStateChangeListener {
+ ctor public ItemTouchHelper(android.support.v7.widget.helper.ItemTouchHelper.Callback);
+ method public void attachToRecyclerView(android.support.v7.widget.RecyclerView);
+ method public void onChildViewAttachedToWindow(android.view.View);
+ method public void onChildViewDetachedFromWindow(android.view.View);
+ method public void startDrag(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public void startSwipe(android.support.v7.widget.RecyclerView.ViewHolder);
+ field public static final int ACTION_STATE_DRAG = 2; // 0x2
+ field public static final int ACTION_STATE_IDLE = 0; // 0x0
+ field public static final int ACTION_STATE_SWIPE = 1; // 0x1
+ field public static final int ANIMATION_TYPE_DRAG = 8; // 0x8
+ field public static final int ANIMATION_TYPE_SWIPE_CANCEL = 4; // 0x4
+ field public static final int ANIMATION_TYPE_SWIPE_SUCCESS = 2; // 0x2
+ field public static final int DOWN = 2; // 0x2
+ field public static final int END = 32; // 0x20
+ field public static final int LEFT = 4; // 0x4
+ field public static final int RIGHT = 8; // 0x8
+ field public static final int START = 16; // 0x10
+ field public static final int UP = 1; // 0x1
+ }
+
+ public static abstract class ItemTouchHelper.Callback {
+ ctor public ItemTouchHelper.Callback();
+ method public boolean canDropOver(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ViewHolder);
+ method public android.support.v7.widget.RecyclerView.ViewHolder chooseDropTarget(android.support.v7.widget.RecyclerView.ViewHolder, java.util.List<android.support.v7.widget.RecyclerView.ViewHolder>, int, int);
+ method public void clearView(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder);
+ method public int convertToAbsoluteDirection(int, int);
+ method public static int convertToRelativeDirection(int, int);
+ method public long getAnimationDuration(android.support.v7.widget.RecyclerView, int, float, float);
+ method public int getBoundingBoxMargin();
+ method public static android.support.v7.widget.helper.ItemTouchUIUtil getDefaultUIUtil();
+ method public float getMoveThreshold(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public abstract int getMovementFlags(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder);
+ method public float getSwipeEscapeVelocity(float);
+ method public float getSwipeThreshold(android.support.v7.widget.RecyclerView.ViewHolder);
+ method public float getSwipeVelocityThreshold(float);
+ method public int interpolateOutOfBoundsScroll(android.support.v7.widget.RecyclerView, int, int, int, long);
+ method public boolean isItemViewSwipeEnabled();
+ method public boolean isLongPressDragEnabled();
+ method public static int makeFlag(int, int);
+ method public static int makeMovementFlags(int, int);
+ method public void onChildDraw(android.graphics.Canvas, android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder, float, float, int, boolean);
+ method public void onChildDrawOver(android.graphics.Canvas, android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder, float, float, int, boolean);
+ method public abstract boolean onMove(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder, android.support.v7.widget.RecyclerView.ViewHolder);
+ method public void onMoved(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder, int, android.support.v7.widget.RecyclerView.ViewHolder, int, int, int);
+ method public void onSelectedChanged(android.support.v7.widget.RecyclerView.ViewHolder, int);
+ method public abstract void onSwiped(android.support.v7.widget.RecyclerView.ViewHolder, int);
+ field public static final int DEFAULT_DRAG_ANIMATION_DURATION = 200; // 0xc8
+ field public static final int DEFAULT_SWIPE_ANIMATION_DURATION = 250; // 0xfa
+ }
+
+ public static abstract class ItemTouchHelper.SimpleCallback extends android.support.v7.widget.helper.ItemTouchHelper.Callback {
+ ctor public ItemTouchHelper.SimpleCallback(int, int);
+ method public int getDragDirs(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder);
+ method public int getMovementFlags(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder);
+ method public int getSwipeDirs(android.support.v7.widget.RecyclerView, android.support.v7.widget.RecyclerView.ViewHolder);
+ method public void setDefaultDragDirs(int);
+ method public void setDefaultSwipeDirs(int);
+ }
+
+ public static abstract interface ItemTouchHelper.ViewDropHandler {
+ method public abstract void prepareForDrop(android.view.View, android.view.View, int, int);
+ }
+
+ public abstract interface ItemTouchUIUtil {
+ method public abstract void clearView(android.view.View);
+ method public abstract void onDraw(android.graphics.Canvas, android.support.v7.widget.RecyclerView, android.view.View, float, float, int, boolean);
+ method public abstract void onDrawOver(android.graphics.Canvas, android.support.v7.widget.RecyclerView, android.view.View, float, float, int, boolean);
+ method public abstract void onSelected(android.view.View);
+ }
+
+}
+
+package android.support.v7.widget.util {
+
+ public abstract class SortedListAdapterCallback<T2> extends android.support.v7.util.SortedList.Callback {
+ ctor public SortedListAdapterCallback(android.support.v7.widget.RecyclerView.Adapter);
+ method public void onChanged(int, int);
+ method public void onInserted(int, int);
+ method public void onMoved(int, int);
+ method public void onRemoved(int, int);
+ }
+
+}
+
+package android.support.wearable.view {
+
+ public class BoxInsetLayout extends android.view.ViewGroup {
+ ctor public BoxInsetLayout(android.content.Context);
+ ctor public BoxInsetLayout(android.content.Context, android.util.AttributeSet);
+ ctor public BoxInsetLayout(android.content.Context, android.util.AttributeSet, int);
+ method protected void onLayout(boolean, int, int, int, int);
+ }
+
+ public static class BoxInsetLayout.LayoutParams extends android.widget.FrameLayout.LayoutParams {
+ ctor public BoxInsetLayout.LayoutParams(android.content.Context, android.util.AttributeSet);
+ ctor public BoxInsetLayout.LayoutParams(int, int);
+ ctor public BoxInsetLayout.LayoutParams(int, int, int);
+ ctor public BoxInsetLayout.LayoutParams(int, int, int, int);
+ ctor public BoxInsetLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
+ ctor public BoxInsetLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+ ctor public BoxInsetLayout.LayoutParams(android.widget.FrameLayout.LayoutParams);
+ ctor public BoxInsetLayout.LayoutParams(android.support.wearable.view.BoxInsetLayout.LayoutParams);
+ field public static final int BOX_ALL = 15; // 0xf
+ field public static final int BOX_BOTTOM = 8; // 0x8
+ field public static final int BOX_LEFT = 1; // 0x1
+ field public static final int BOX_NONE = 0; // 0x0
+ field public static final int BOX_RIGHT = 4; // 0x4
+ field public static final int BOX_TOP = 2; // 0x2
+ field public int boxedEdges;
+ }
+
+}
+
diff --git a/api/26.0.0.txt b/api/26.0.0.txt
index 3d77c5b..205400c 100644
--- a/api/26.0.0.txt
+++ b/api/26.0.0.txt
@@ -1,3 +1,75 @@
+package android.support.animation {
+
+ public abstract class DynamicAnimation<T extends android.support.animation.DynamicAnimation<T>> {
+ method public T addEndListener(android.support.animation.DynamicAnimation.OnAnimationEndListener);
+ method public T addUpdateListener(android.support.animation.DynamicAnimation.OnAnimationUpdateListener);
+ method public void cancel();
+ method public boolean isRunning();
+ method public void removeEndListener(android.support.animation.DynamicAnimation.OnAnimationEndListener);
+ method public void removeUpdateListener(android.support.animation.DynamicAnimation.OnAnimationUpdateListener);
+ method public T setMaxValue(float);
+ method public T setMinValue(float);
+ method public T setStartValue(float);
+ method public T setStartVelocity(float);
+ method public void start();
+ field public static final android.support.animation.DynamicAnimation.ViewProperty ALPHA;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty ROTATION;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty ROTATION_X;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty ROTATION_Y;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty SCALE_X;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty SCALE_Y;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty SCROLL_X;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty SCROLL_Y;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty TRANSLATION_X;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty TRANSLATION_Y;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty TRANSLATION_Z;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty X;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty Y;
+ field public static final android.support.animation.DynamicAnimation.ViewProperty Z;
+ }
+
+ public static abstract interface DynamicAnimation.OnAnimationEndListener {
+ method public abstract void onAnimationEnd(android.support.animation.DynamicAnimation, boolean, float, float);
+ }
+
+ public static abstract interface DynamicAnimation.OnAnimationUpdateListener {
+ method public abstract void onAnimationUpdate(android.support.animation.DynamicAnimation, float, float);
+ }
+
+ public static abstract class DynamicAnimation.ViewProperty {
+ }
+
+ public final class SpringAnimation extends android.support.animation.DynamicAnimation {
+ ctor public SpringAnimation(android.view.View, android.support.animation.DynamicAnimation.ViewProperty);
+ ctor public SpringAnimation(android.view.View, android.support.animation.DynamicAnimation.ViewProperty, float);
+ method public void animateToFinalPosition(float);
+ method public boolean canSkipToEnd();
+ method public android.support.animation.SpringForce getSpring();
+ method public android.support.animation.SpringAnimation setSpring(android.support.animation.SpringForce);
+ method public void skipToEnd();
+ }
+
+ public final class SpringForce {
+ ctor public SpringForce();
+ ctor public SpringForce(float);
+ method public float getDampingRatio();
+ method public float getFinalPosition();
+ method public float getStiffness();
+ method public android.support.animation.SpringForce setDampingRatio(float);
+ method public android.support.animation.SpringForce setFinalPosition(float);
+ method public android.support.animation.SpringForce setStiffness(float);
+ field public static final float DAMPING_RATIO_HIGH_BOUNCY = 0.2f;
+ field public static final float DAMPING_RATIO_LOW_BOUNCY = 0.75f;
+ field public static final float DAMPING_RATIO_MEDIUM_BOUNCY = 0.5f;
+ field public static final float DAMPING_RATIO_NO_BOUNCY = 1.0f;
+ field public static final float STIFFNESS_HIGH = 10000.0f;
+ field public static final float STIFFNESS_LOW = 200.0f;
+ field public static final float STIFFNESS_MEDIUM = 1500.0f;
+ field public static final float STIFFNESS_VERY_LOW = 50.0f;
+ }
+
+}
+
package android.support.app.recommendation {
public final class ContentRecommendation {
@@ -869,16 +941,34 @@
package android.support.graphics.drawable {
- public class AnimatedVectorDrawableCompat extends android.support.graphics.drawable.VectorDrawableCommon {
+ public abstract interface Animatable2Compat {
+ method public abstract void clearAnimationCallbacks();
+ method public abstract void registerAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+ method public abstract boolean unregisterAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+ }
+
+ public static abstract class Animatable2Compat.AnimationCallback {
+ ctor public Animatable2Compat.AnimationCallback();
+ method public void onAnimationEnd(android.graphics.drawable.Drawable);
+ method public void onAnimationStart(android.graphics.drawable.Drawable);
+ }
+
+ public class AnimatedVectorDrawableCompat extends android.support.graphics.drawable.VectorDrawableCommon implements android.support.graphics.drawable.Animatable2Compat {
+ method public void clearAnimationCallbacks();
+ method public static void clearAnimationCallbacks(android.graphics.drawable.Drawable);
method public static android.support.graphics.drawable.AnimatedVectorDrawableCompat create(android.content.Context, int);
method public static android.support.graphics.drawable.AnimatedVectorDrawableCompat createFromXmlInner(android.content.Context, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public void draw(android.graphics.Canvas);
method public int getOpacity();
method public boolean isRunning();
+ method public void registerAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+ method public static void registerAnimationCallback(android.graphics.drawable.Drawable, android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
method public void setAlpha(int);
method public void setColorFilter(android.graphics.ColorFilter);
method public void start();
method public void stop();
+ method public boolean unregisterAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+ method public static boolean unregisterAnimationCallback(android.graphics.drawable.Drawable, android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
}
abstract class VectorDrawableCommon extends android.graphics.drawable.Drawable {
@@ -1102,7 +1192,6 @@
method public android.net.Uri getAppLinkIntentUri();
method public android.net.Uri getAppLinkPosterArtUri();
method public java.lang.String getAppLinkText();
- method public java.lang.String getChannelLogo();
method public java.lang.String getDescription();
method public java.lang.String getDisplayName();
method public java.lang.String getDisplayNumber();
@@ -1135,7 +1224,6 @@
method public android.support.media.tv.Channel.Builder setAppLinkIntentUri(android.net.Uri);
method public android.support.media.tv.Channel.Builder setAppLinkPosterArtUri(android.net.Uri);
method public android.support.media.tv.Channel.Builder setAppLinkText(java.lang.String);
- method public android.support.media.tv.Channel.Builder setChannelLogo(java.lang.String);
method public android.support.media.tv.Channel.Builder setDescription(java.lang.String);
method public android.support.media.tv.Channel.Builder setDisplayName(java.lang.String);
method public android.support.media.tv.Channel.Builder setDisplayNumber(java.lang.String);
@@ -1148,7 +1236,6 @@
method public android.support.media.tv.Channel.Builder setInternalProviderFlag4(long);
method public android.support.media.tv.Channel.Builder setNetworkAffiliation(java.lang.String);
method public android.support.media.tv.Channel.Builder setOriginalNetworkId(int);
- method public android.support.media.tv.Channel.Builder setPackageName(java.lang.String);
method public android.support.media.tv.Channel.Builder setSearchable(boolean);
method public android.support.media.tv.Channel.Builder setServiceId(int);
method public android.support.media.tv.Channel.Builder setServiceType(java.lang.String);
@@ -1589,12 +1676,25 @@
package android.support.transition {
+ public class ArcMotion extends android.support.transition.PathMotion {
+ ctor public ArcMotion();
+ method public float getMaximumAngle();
+ method public float getMinimumHorizontalAngle();
+ method public float getMinimumVerticalAngle();
+ method public android.graphics.Path getPath(float, float, float, float);
+ method public void setMaximumAngle(float);
+ method public void setMinimumHorizontalAngle(float);
+ method public void setMinimumVerticalAngle(float);
+ }
+
public class AutoTransition extends android.support.transition.TransitionSet {
ctor public AutoTransition();
+ ctor public AutoTransition(android.content.Context, android.util.AttributeSet);
}
public class ChangeBounds extends android.support.transition.Transition {
ctor public ChangeBounds();
+ ctor public ChangeBounds(android.content.Context, android.util.AttributeSet);
method public void captureEndValues(android.support.transition.TransitionValues);
method public void captureStartValues(android.support.transition.TransitionValues);
method public void setResizeClip(boolean);
@@ -1603,10 +1703,24 @@
public class Fade extends android.support.transition.Visibility {
ctor public Fade(int);
ctor public Fade();
+ ctor public Fade(android.content.Context, android.util.AttributeSet);
field public static final int IN = 1; // 0x1
field public static final int OUT = 2; // 0x2
}
+ public abstract class PathMotion {
+ ctor public PathMotion();
+ method public abstract android.graphics.Path getPath(float, float, float, float);
+ }
+
+ public class PatternPathMotion extends android.support.transition.PathMotion {
+ ctor public PatternPathMotion();
+ ctor public PatternPathMotion(android.graphics.Path);
+ method public android.graphics.Path getPath(float, float, float, float);
+ method public android.graphics.Path getPatternPath();
+ method public void setPatternPath(android.graphics.Path);
+ }
+
public class Scene {
ctor public Scene(android.view.ViewGroup);
ctor public Scene(android.view.ViewGroup, android.view.View);
@@ -1620,6 +1734,7 @@
public abstract class Transition {
ctor public Transition();
+ ctor public Transition(android.content.Context, android.util.AttributeSet);
method public android.support.transition.Transition addListener(android.support.transition.Transition.TransitionListener);
method public android.support.transition.Transition addTarget(android.view.View);
method public android.support.transition.Transition addTarget(int);
@@ -1639,6 +1754,7 @@
method public long getDuration();
method public android.animation.TimeInterpolator getInterpolator();
method public java.lang.String getName();
+ method public android.support.transition.PathMotion getPathMotion();
method public long getStartDelay();
method public java.util.List<java.lang.Integer> getTargetIds();
method public java.util.List<java.lang.String> getTargetNames();
@@ -1654,6 +1770,7 @@
method public android.support.transition.Transition setDuration(long);
method public android.support.transition.Transition setInterpolator(android.animation.TimeInterpolator);
method public void setMatchOrder(int...);
+ method public void setPathMotion(android.support.transition.PathMotion);
method public android.support.transition.Transition setStartDelay(long);
field public static final int MATCH_ID = 3; // 0x3
field public static final int MATCH_INSTANCE = 1; // 0x1
@@ -1669,6 +1786,12 @@
method public abstract void onTransitionStart(android.support.transition.Transition);
}
+ public class TransitionInflater {
+ method public static android.support.transition.TransitionInflater from(android.content.Context);
+ method public android.support.transition.Transition inflateTransition(int);
+ method public android.support.transition.TransitionManager inflateTransitionManager(int, android.view.ViewGroup);
+ }
+
public class TransitionManager {
ctor public TransitionManager();
method public static void beginDelayedTransition(android.view.ViewGroup);
@@ -1682,6 +1805,7 @@
public class TransitionSet extends android.support.transition.Transition {
ctor public TransitionSet();
+ ctor public TransitionSet(android.content.Context, android.util.AttributeSet);
method public android.support.transition.TransitionSet addTransition(android.support.transition.Transition);
method public void captureEndValues(android.support.transition.TransitionValues);
method public void captureStartValues(android.support.transition.TransitionValues);
@@ -1702,11 +1826,18 @@
public abstract class Visibility extends android.support.transition.Transition {
ctor public Visibility();
+ ctor public Visibility(android.content.Context, android.util.AttributeSet);
method public void captureEndValues(android.support.transition.TransitionValues);
method public void captureStartValues(android.support.transition.TransitionValues);
+ method public int getMode();
method public boolean isVisible(android.support.transition.TransitionValues);
method public android.animation.Animator onAppear(android.view.ViewGroup, android.support.transition.TransitionValues, int, android.support.transition.TransitionValues, int);
+ method public android.animation.Animator onAppear(android.view.ViewGroup, android.view.View, android.support.transition.TransitionValues, android.support.transition.TransitionValues);
method public android.animation.Animator onDisappear(android.view.ViewGroup, android.support.transition.TransitionValues, int, android.support.transition.TransitionValues, int);
+ method public android.animation.Animator onDisappear(android.view.ViewGroup, android.view.View, android.support.transition.TransitionValues, android.support.transition.TransitionValues);
+ method public void setMode(int);
+ field public static final int MODE_IN = 1; // 0x1
+ field public static final int MODE_OUT = 2; // 0x2
}
}
@@ -2892,10 +3023,7 @@
public class BoundsRule {
ctor public BoundsRule();
ctor public BoundsRule(android.support.v17.leanback.graphics.BoundsRule);
- method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule absoluteValue(int);
method public void calculateBounds(android.graphics.Rect, android.graphics.Rect);
- method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParent(float);
- method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParentWithOffset(float, int);
field public android.support.v17.leanback.graphics.BoundsRule.ValueRule bottom;
field public android.support.v17.leanback.graphics.BoundsRule.ValueRule left;
field public android.support.v17.leanback.graphics.BoundsRule.ValueRule right;
@@ -2903,8 +3031,11 @@
}
public static final class BoundsRule.ValueRule {
+ method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule absoluteValue(int);
method public int getAbsoluteValue();
method public float getFraction();
+ method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParent(float);
+ method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParentWithOffset(float, int);
method public void setAbsoluteValue(int);
method public void setFraction(float);
}
@@ -4010,111 +4141,79 @@
public abstract class Parallax<PropertyT extends android.util.Property> {
ctor public Parallax();
- method public void addEffect(android.support.v17.leanback.widget.ParallaxEffect);
- method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue...);
- method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue...);
- method public abstract PropertyT addProperty(java.lang.String);
+ method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.PropertyMarkerValue...);
+ method public final PropertyT addProperty(java.lang.String);
method public abstract PropertyT createProperty(java.lang.String, int);
method public java.util.List<android.support.v17.leanback.widget.ParallaxEffect> getEffects();
+ method public abstract float getMaxValue();
method public final java.util.List<PropertyT> getProperties();
method public void removeAllEffects();
method public void removeEffect(android.support.v17.leanback.widget.ParallaxEffect);
method public void updateValues();
- method public abstract void verifyProperties() throws java.lang.IllegalStateException;
- }
-
- public static abstract class Parallax.FloatParallax<FloatPropertyT extends android.support.v17.leanback.widget.Parallax.FloatProperty> extends android.support.v17.leanback.widget.Parallax {
- ctor public Parallax.FloatParallax();
- method public final FloatPropertyT addProperty(java.lang.String);
- method public abstract float getMaxValue();
- method public final float getPropertyValue(int);
- method public final void setPropertyValue(int, float);
- method public final void verifyProperties() throws java.lang.IllegalStateException;
}
public static class Parallax.FloatProperty extends android.util.Property {
ctor public Parallax.FloatProperty(java.lang.String, int);
- method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue at(float, float);
- method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue atAbsolute(float);
- method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue atFraction(float);
- method public final java.lang.Float get(android.support.v17.leanback.widget.Parallax.FloatParallax);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue at(float, float);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atAbsolute(float);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atFraction(float);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMax();
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMin();
+ method public final java.lang.Float get(android.support.v17.leanback.widget.Parallax);
method public final int getIndex();
- method public final void set(android.support.v17.leanback.widget.Parallax.FloatParallax, java.lang.Float);
+ method public final float getValue(android.support.v17.leanback.widget.Parallax);
+ method public final void set(android.support.v17.leanback.widget.Parallax, java.lang.Float);
+ method public final void setValue(android.support.v17.leanback.widget.Parallax, float);
field public static final float UNKNOWN_AFTER = 3.4028235E38f;
field public static final float UNKNOWN_BEFORE = -3.4028235E38f;
}
- public static class Parallax.FloatPropertyMarkerValue extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue {
- ctor public Parallax.FloatPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.FloatProperty, float);
- ctor public Parallax.FloatPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.FloatProperty, float, float);
- method public final float getMarkerValue(android.support.v17.leanback.widget.Parallax.FloatParallax);
- }
-
- public static abstract class Parallax.IntParallax<IntPropertyT extends android.support.v17.leanback.widget.Parallax.IntProperty> extends android.support.v17.leanback.widget.Parallax {
- ctor public Parallax.IntParallax();
- method public final IntPropertyT addProperty(java.lang.String);
- method public abstract int getMaxValue();
- method public final int getPropertyValue(int);
- method public final void setPropertyValue(int, int);
- method public final void verifyProperties() throws java.lang.IllegalStateException;
- }
-
public static class Parallax.IntProperty extends android.util.Property {
ctor public Parallax.IntProperty(java.lang.String, int);
- method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue at(int, float);
- method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue atAbsolute(int);
- method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue atFraction(float);
- method public final java.lang.Integer get(android.support.v17.leanback.widget.Parallax.IntParallax);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue at(int, float);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atAbsolute(int);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atFraction(float);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMax();
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMin();
+ method public final java.lang.Integer get(android.support.v17.leanback.widget.Parallax);
method public final int getIndex();
- method public final void set(android.support.v17.leanback.widget.Parallax.IntParallax, java.lang.Integer);
+ method public final int getValue(android.support.v17.leanback.widget.Parallax);
+ method public final void set(android.support.v17.leanback.widget.Parallax, java.lang.Integer);
+ method public final void setValue(android.support.v17.leanback.widget.Parallax, int);
field public static final int UNKNOWN_AFTER = 2147483647; // 0x7fffffff
field public static final int UNKNOWN_BEFORE = -2147483648; // 0x80000000
}
- public static class Parallax.IntPropertyMarkerValue extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue {
- ctor public Parallax.IntPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.IntProperty, int);
- ctor public Parallax.IntPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.IntProperty, int, float);
- method public final int getMarkerValue(android.support.v17.leanback.widget.Parallax.IntParallax);
- }
-
public static class Parallax.PropertyMarkerValue<PropertyT> {
ctor public Parallax.PropertyMarkerValue(PropertyT);
method public PropertyT getProperty();
}
- public abstract class ParallaxEffect<ParallaxEffectT extends android.support.v17.leanback.widget.ParallaxEffect, PropertyMarkerValueT extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue> {
- ctor public ParallaxEffect();
+ public abstract class ParallaxEffect {
method public final void addTarget(android.support.v17.leanback.widget.ParallaxTarget);
- method protected abstract float calculateFraction(android.support.v17.leanback.widget.Parallax);
- method public final java.util.List<PropertyMarkerValueT> getPropertyRanges();
+ method public final java.util.List<android.support.v17.leanback.widget.Parallax.PropertyMarkerValue> getPropertyRanges();
method public final java.util.List<android.support.v17.leanback.widget.ParallaxTarget> getTargets();
method public final void performMapping(android.support.v17.leanback.widget.Parallax);
method public final void removeTarget(android.support.v17.leanback.widget.ParallaxTarget);
- method public final void setPropertyRanges(PropertyMarkerValueT...);
+ method public final void setPropertyRanges(android.support.v17.leanback.widget.Parallax.PropertyMarkerValue...);
method public final android.support.v17.leanback.widget.ParallaxEffect target(android.support.v17.leanback.widget.ParallaxTarget);
method public final android.support.v17.leanback.widget.ParallaxEffect target(java.lang.Object, android.animation.PropertyValuesHolder);
- }
-
- public static final class ParallaxEffect.FloatEffect extends android.support.v17.leanback.widget.ParallaxEffect {
- ctor public ParallaxEffect.FloatEffect();
- method protected float calculateFraction(android.support.v17.leanback.widget.Parallax);
- }
-
- public static final class ParallaxEffect.IntEffect extends android.support.v17.leanback.widget.ParallaxEffect {
- ctor public ParallaxEffect.IntEffect();
- method protected float calculateFraction(android.support.v17.leanback.widget.Parallax);
+ method public final <T, V extends java.lang.Number> android.support.v17.leanback.widget.ParallaxEffect target(T, android.util.Property<T, V>);
}
public abstract class ParallaxTarget {
ctor public ParallaxTarget();
- method public abstract float getFraction();
- method public abstract void update(float);
+ method public void directUpdate(java.lang.Number);
+ method public boolean isDirectMapping();
+ method public void update(float);
+ }
+
+ public static final class ParallaxTarget.DirectPropertyTarget<T, V extends java.lang.Number> extends android.support.v17.leanback.widget.ParallaxTarget {
+ ctor public ParallaxTarget.DirectPropertyTarget(java.lang.Object, android.util.Property<T, V>);
}
public static final class ParallaxTarget.PropertyValuesHolderTarget extends android.support.v17.leanback.widget.ParallaxTarget {
ctor public ParallaxTarget.PropertyValuesHolderTarget(java.lang.Object, android.animation.PropertyValuesHolder);
- method public float getFraction();
- method public void update(float);
}
public class PlaybackControlsRow extends android.support.v17.leanback.widget.Row {
@@ -4306,10 +4405,10 @@
method public void unselect();
}
- public class RecyclerViewParallax extends android.support.v17.leanback.widget.Parallax.IntParallax {
+ public class RecyclerViewParallax extends android.support.v17.leanback.widget.Parallax {
ctor public RecyclerViewParallax();
method public android.support.v17.leanback.widget.RecyclerViewParallax.ChildPositionProperty createProperty(java.lang.String, int);
- method public int getMaxValue();
+ method public float getMaxValue();
method public android.support.v7.widget.RecyclerView getRecyclerView();
method public void setRecyclerView(android.support.v7.widget.RecyclerView);
}
@@ -6034,6 +6133,13 @@
}
public class ShortcutInfoCompat {
+ method public android.content.ComponentName getActivity();
+ method public java.lang.CharSequence getDisabledMessage();
+ method public java.lang.String getId();
+ method public android.content.Intent getIntent();
+ method public android.content.Intent[] getIntents();
+ method public java.lang.CharSequence getLongLabel();
+ method public java.lang.CharSequence getShortLabel();
}
public static class ShortcutInfoCompat.Builder {
@@ -6050,7 +6156,6 @@
}
public class ShortcutManagerCompat {
- ctor public ShortcutManagerCompat();
method public static android.content.Intent createShortcutResultIntent(android.content.Context, android.support.v4.content.pm.ShortcutInfoCompat);
method public static boolean isRequestPinShortcutSupported(android.content.Context);
method public static boolean requestPinShortcut(android.content.Context, android.support.v4.content.pm.ShortcutInfoCompat, android.content.IntentSender);
@@ -7391,14 +7496,19 @@
method public static deprecated boolean expandActionView(android.view.MenuItem);
method public static android.support.v4.view.ActionProvider getActionProvider(android.view.MenuItem);
method public static deprecated android.view.View getActionView(android.view.MenuItem);
+ method public int getAlphabeticModifiers(android.view.MenuItem);
method public static java.lang.CharSequence getContentDescription(android.view.MenuItem);
+ method public int getNumericModifiers(android.view.MenuItem);
method public static java.lang.CharSequence getTooltipText(android.view.MenuItem);
method public static deprecated boolean isActionViewExpanded(android.view.MenuItem);
method public static android.view.MenuItem setActionProvider(android.view.MenuItem, android.support.v4.view.ActionProvider);
method public static deprecated android.view.MenuItem setActionView(android.view.MenuItem, android.view.View);
method public static deprecated android.view.MenuItem setActionView(android.view.MenuItem, int);
+ method public static void setAlphabeticShortcut(android.view.MenuItem, char, int);
method public static void setContentDescription(android.view.MenuItem, java.lang.CharSequence);
+ method public static void setNumericShortcut(android.view.MenuItem, char, int);
method public static deprecated android.view.MenuItem setOnActionExpandListener(android.view.MenuItem, android.support.v4.view.MenuItemCompat.OnActionExpandListener);
+ method public static void setShortcut(android.view.MenuItem, char, char, int, int);
method public static deprecated void setShowAsAction(android.view.MenuItem, int);
method public static void setTooltipText(android.view.MenuItem, java.lang.CharSequence);
field public static final deprecated int SHOW_AS_ACTION_ALWAYS = 2; // 0x2
@@ -9023,6 +9133,7 @@
method public android.support.v7.graphics.drawable.DrawerArrowDrawable getDrawerArrowDrawable();
method public android.view.View.OnClickListener getToolbarNavigationClickListener();
method public boolean isDrawerIndicatorEnabled();
+ method public boolean isDrawerSlideAnimationEnabled();
method public void onConfigurationChanged(android.content.res.Configuration);
method public void onDrawerClosed(android.view.View);
method public void onDrawerOpened(android.view.View);
@@ -9031,6 +9142,7 @@
method public boolean onOptionsItemSelected(android.view.MenuItem);
method public void setDrawerArrowDrawable(android.support.v7.graphics.drawable.DrawerArrowDrawable);
method public void setDrawerIndicatorEnabled(boolean);
+ method public void setDrawerSlideAnimationEnabled(boolean);
method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable);
method public void setHomeAsUpIndicator(int);
method public void setToolbarNavigationClickListener(android.view.View.OnClickListener);
@@ -10689,7 +10801,8 @@
method public int findLastVisibleItemPosition();
method public android.support.v7.widget.RecyclerView.LayoutParams generateDefaultLayoutParams();
method protected int getExtraLayoutSpace(android.support.v7.widget.RecyclerView.State);
- method public int getInitialItemPrefetchCount();
+ method public deprecated int getInitialItemPrefetchCount();
+ method public int getInitialPrefetchItemCount();
method public int getOrientation();
method public boolean getRecycleChildrenOnDetach();
method public boolean getReverseLayout();
diff --git a/api/current.txt b/api/current.txt
index 83d059c..2990bd1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1192,7 +1192,6 @@
method public android.net.Uri getAppLinkIntentUri();
method public android.net.Uri getAppLinkPosterArtUri();
method public java.lang.String getAppLinkText();
- method public java.lang.String getChannelLogo();
method public java.lang.String getDescription();
method public java.lang.String getDisplayName();
method public java.lang.String getDisplayNumber();
@@ -1225,7 +1224,6 @@
method public android.support.media.tv.Channel.Builder setAppLinkIntentUri(android.net.Uri);
method public android.support.media.tv.Channel.Builder setAppLinkPosterArtUri(android.net.Uri);
method public android.support.media.tv.Channel.Builder setAppLinkText(java.lang.String);
- method public android.support.media.tv.Channel.Builder setChannelLogo(java.lang.String);
method public android.support.media.tv.Channel.Builder setDescription(java.lang.String);
method public android.support.media.tv.Channel.Builder setDisplayName(java.lang.String);
method public android.support.media.tv.Channel.Builder setDisplayNumber(java.lang.String);
@@ -1238,7 +1236,6 @@
method public android.support.media.tv.Channel.Builder setInternalProviderFlag4(long);
method public android.support.media.tv.Channel.Builder setNetworkAffiliation(java.lang.String);
method public android.support.media.tv.Channel.Builder setOriginalNetworkId(int);
- method public android.support.media.tv.Channel.Builder setPackageName(java.lang.String);
method public android.support.media.tv.Channel.Builder setSearchable(boolean);
method public android.support.media.tv.Channel.Builder setServiceId(int);
method public android.support.media.tv.Channel.Builder setServiceType(java.lang.String);
@@ -1677,6 +1674,125 @@
}
+package android.support.text.emoji {
+
+ public class EmojiCompat {
+ method public static android.support.text.emoji.EmojiCompat get();
+ method public static boolean handleDeleteSurroundingText(android.view.inputmethod.InputConnection, android.text.Editable, int, int, boolean);
+ method public static boolean handleOnKeyDown(android.text.Editable, int, android.view.KeyEvent);
+ method public boolean hasEmojiGlyph(java.lang.CharSequence);
+ method public boolean hasEmojiGlyph(java.lang.CharSequence, int);
+ method public static android.support.text.emoji.EmojiCompat init(android.support.text.emoji.EmojiCompat.Config);
+ method public boolean isInitialized();
+ method public java.lang.CharSequence process(java.lang.CharSequence);
+ method public java.lang.CharSequence process(java.lang.CharSequence, int, int);
+ method public void registerInitCallback(android.support.text.emoji.EmojiCompat.InitCallback);
+ method public void unregisterInitCallback(android.support.text.emoji.EmojiCompat.InitCallback);
+ field public static final java.lang.String EDITOR_INFO_METAVERSION_KEY = "android.support.text.emoji.emojiCompat_metadataVersion";
+ field public static final java.lang.String EDITOR_INFO_REPLACE_ALL_KEY = "android.support.text.emoji.emojiCompat_replaceAll";
+ }
+
+ public static abstract class EmojiCompat.Config {
+ ctor protected EmojiCompat.Config(android.support.text.emoji.EmojiCompat.MetadataLoader);
+ method public android.support.text.emoji.EmojiCompat.Config registerInitCallback(android.support.text.emoji.EmojiCompat.InitCallback);
+ method public android.support.text.emoji.EmojiCompat.Config setMaxEmojiPerText(int);
+ method public android.support.text.emoji.EmojiCompat.Config setReplaceAll(boolean);
+ method public android.support.text.emoji.EmojiCompat.Config unregisterInitCallback(android.support.text.emoji.EmojiCompat.InitCallback);
+ }
+
+ public static abstract class EmojiCompat.InitCallback {
+ ctor public EmojiCompat.InitCallback();
+ method public void onFailed(java.lang.Throwable);
+ method public void onInitialized();
+ }
+
+ public static abstract class EmojiCompat.LoaderCallback {
+ ctor public EmojiCompat.LoaderCallback();
+ method public abstract void onFailed(java.lang.Throwable);
+ method public abstract void onLoaded(android.support.text.emoji.MetadataRepo);
+ }
+
+ public static abstract interface EmojiCompat.MetadataLoader {
+ method public abstract void load(android.support.text.emoji.EmojiCompat.LoaderCallback);
+ }
+
+ public abstract class EmojiSpan extends android.text.style.ReplacementSpan {
+ method public int getSize(android.graphics.Paint, java.lang.CharSequence, int, int, android.graphics.Paint.FontMetricsInt);
+ }
+
+ public final class MetadataRepo {
+ method public static android.support.text.emoji.MetadataRepo create(android.graphics.Typeface, java.io.InputStream) throws java.io.IOException;
+ method public static android.support.text.emoji.MetadataRepo create(android.graphics.Typeface, java.nio.ByteBuffer) throws java.io.IOException;
+ method public static android.support.text.emoji.MetadataRepo create(android.content.res.AssetManager, java.lang.String) throws java.io.IOException;
+ }
+
+}
+
+package android.support.text.emoji.bundled {
+
+ public class BundledEmojiCompatConfig extends android.support.text.emoji.EmojiCompat.Config {
+ ctor public BundledEmojiCompatConfig(android.content.Context);
+ }
+
+}
+
+package android.support.text.emoji.widget {
+
+ public class EmojiAppCompatButton extends android.support.v7.widget.AppCompatButton {
+ ctor public EmojiAppCompatButton(android.content.Context);
+ ctor public EmojiAppCompatButton(android.content.Context, android.util.AttributeSet);
+ ctor public EmojiAppCompatButton(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public class EmojiAppCompatEditText extends android.support.v7.widget.AppCompatEditText {
+ ctor public EmojiAppCompatEditText(android.content.Context);
+ ctor public EmojiAppCompatEditText(android.content.Context, android.util.AttributeSet);
+ ctor public EmojiAppCompatEditText(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public class EmojiAppCompatTextView extends android.support.v7.widget.AppCompatTextView {
+ ctor public EmojiAppCompatTextView(android.content.Context);
+ ctor public EmojiAppCompatTextView(android.content.Context, android.util.AttributeSet);
+ ctor public EmojiAppCompatTextView(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ public class EmojiButton extends android.widget.Button {
+ ctor public EmojiButton(android.content.Context);
+ ctor public EmojiButton(android.content.Context, android.util.AttributeSet);
+ ctor public EmojiButton(android.content.Context, android.util.AttributeSet, int);
+ ctor public EmojiButton(android.content.Context, android.util.AttributeSet, int, int);
+ }
+
+ public class EmojiEditText extends android.widget.EditText {
+ ctor public EmojiEditText(android.content.Context);
+ ctor public EmojiEditText(android.content.Context, android.util.AttributeSet);
+ ctor public EmojiEditText(android.content.Context, android.util.AttributeSet, int);
+ ctor public EmojiEditText(android.content.Context, android.util.AttributeSet, int, int);
+ }
+
+ public final class EmojiEditTextHelper {
+ ctor public EmojiEditTextHelper(android.widget.EditText);
+ method public android.text.method.KeyListener getKeyListener(android.text.method.KeyListener);
+ method public android.view.inputmethod.InputConnection onCreateInputConnection(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo);
+ }
+
+ public class EmojiTextView extends android.widget.TextView {
+ ctor public EmojiTextView(android.content.Context);
+ ctor public EmojiTextView(android.content.Context, android.util.AttributeSet);
+ ctor public EmojiTextView(android.content.Context, android.util.AttributeSet, int);
+ ctor public EmojiTextView(android.content.Context, android.util.AttributeSet, int, int);
+ }
+
+ public final class EmojiTextViewHelper {
+ ctor public EmojiTextViewHelper(android.widget.TextView);
+ method public android.text.InputFilter[] getFilters(android.text.InputFilter[]);
+ method public android.text.method.TransformationMethod getTransformationMethod(android.text.method.TransformationMethod);
+ method public void setAllCaps(boolean);
+ method public void updateTransformationMethod();
+ }
+
+}
+
package android.support.transition {
public class ArcMotion extends android.support.transition.PathMotion {
@@ -3026,10 +3142,7 @@
public class BoundsRule {
ctor public BoundsRule();
ctor public BoundsRule(android.support.v17.leanback.graphics.BoundsRule);
- method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule absoluteValue(int);
method public void calculateBounds(android.graphics.Rect, android.graphics.Rect);
- method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParent(float);
- method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParentWithOffset(float, int);
field public android.support.v17.leanback.graphics.BoundsRule.ValueRule bottom;
field public android.support.v17.leanback.graphics.BoundsRule.ValueRule left;
field public android.support.v17.leanback.graphics.BoundsRule.ValueRule right;
@@ -3037,8 +3150,11 @@
}
public static final class BoundsRule.ValueRule {
+ method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule absoluteValue(int);
method public int getAbsoluteValue();
method public float getFraction();
+ method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParent(float);
+ method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParentWithOffset(float, int);
method public void setAbsoluteValue(int);
method public void setFraction(float);
}
@@ -4144,111 +4260,79 @@
public abstract class Parallax<PropertyT extends android.util.Property> {
ctor public Parallax();
- method public void addEffect(android.support.v17.leanback.widget.ParallaxEffect);
- method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue...);
- method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue...);
- method public abstract PropertyT addProperty(java.lang.String);
+ method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.PropertyMarkerValue...);
+ method public final PropertyT addProperty(java.lang.String);
method public abstract PropertyT createProperty(java.lang.String, int);
method public java.util.List<android.support.v17.leanback.widget.ParallaxEffect> getEffects();
+ method public abstract float getMaxValue();
method public final java.util.List<PropertyT> getProperties();
method public void removeAllEffects();
method public void removeEffect(android.support.v17.leanback.widget.ParallaxEffect);
method public void updateValues();
- method public abstract void verifyProperties() throws java.lang.IllegalStateException;
- }
-
- public static abstract class Parallax.FloatParallax<FloatPropertyT extends android.support.v17.leanback.widget.Parallax.FloatProperty> extends android.support.v17.leanback.widget.Parallax {
- ctor public Parallax.FloatParallax();
- method public final FloatPropertyT addProperty(java.lang.String);
- method public abstract float getMaxValue();
- method public final float getPropertyValue(int);
- method public final void setPropertyValue(int, float);
- method public final void verifyProperties() throws java.lang.IllegalStateException;
}
public static class Parallax.FloatProperty extends android.util.Property {
ctor public Parallax.FloatProperty(java.lang.String, int);
- method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue at(float, float);
- method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue atAbsolute(float);
- method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue atFraction(float);
- method public final java.lang.Float get(android.support.v17.leanback.widget.Parallax.FloatParallax);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue at(float, float);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atAbsolute(float);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atFraction(float);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMax();
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMin();
+ method public final java.lang.Float get(android.support.v17.leanback.widget.Parallax);
method public final int getIndex();
- method public final void set(android.support.v17.leanback.widget.Parallax.FloatParallax, java.lang.Float);
+ method public final float getValue(android.support.v17.leanback.widget.Parallax);
+ method public final void set(android.support.v17.leanback.widget.Parallax, java.lang.Float);
+ method public final void setValue(android.support.v17.leanback.widget.Parallax, float);
field public static final float UNKNOWN_AFTER = 3.4028235E38f;
field public static final float UNKNOWN_BEFORE = -3.4028235E38f;
}
- public static class Parallax.FloatPropertyMarkerValue extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue {
- ctor public Parallax.FloatPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.FloatProperty, float);
- ctor public Parallax.FloatPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.FloatProperty, float, float);
- method public final float getMarkerValue(android.support.v17.leanback.widget.Parallax.FloatParallax);
- }
-
- public static abstract class Parallax.IntParallax<IntPropertyT extends android.support.v17.leanback.widget.Parallax.IntProperty> extends android.support.v17.leanback.widget.Parallax {
- ctor public Parallax.IntParallax();
- method public final IntPropertyT addProperty(java.lang.String);
- method public abstract int getMaxValue();
- method public final int getPropertyValue(int);
- method public final void setPropertyValue(int, int);
- method public final void verifyProperties() throws java.lang.IllegalStateException;
- }
-
public static class Parallax.IntProperty extends android.util.Property {
ctor public Parallax.IntProperty(java.lang.String, int);
- method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue at(int, float);
- method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue atAbsolute(int);
- method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue atFraction(float);
- method public final java.lang.Integer get(android.support.v17.leanback.widget.Parallax.IntParallax);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue at(int, float);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atAbsolute(int);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atFraction(float);
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMax();
+ method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMin();
+ method public final java.lang.Integer get(android.support.v17.leanback.widget.Parallax);
method public final int getIndex();
- method public final void set(android.support.v17.leanback.widget.Parallax.IntParallax, java.lang.Integer);
+ method public final int getValue(android.support.v17.leanback.widget.Parallax);
+ method public final void set(android.support.v17.leanback.widget.Parallax, java.lang.Integer);
+ method public final void setValue(android.support.v17.leanback.widget.Parallax, int);
field public static final int UNKNOWN_AFTER = 2147483647; // 0x7fffffff
field public static final int UNKNOWN_BEFORE = -2147483648; // 0x80000000
}
- public static class Parallax.IntPropertyMarkerValue extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue {
- ctor public Parallax.IntPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.IntProperty, int);
- ctor public Parallax.IntPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.IntProperty, int, float);
- method public final int getMarkerValue(android.support.v17.leanback.widget.Parallax.IntParallax);
- }
-
public static class Parallax.PropertyMarkerValue<PropertyT> {
ctor public Parallax.PropertyMarkerValue(PropertyT);
method public PropertyT getProperty();
}
- public abstract class ParallaxEffect<ParallaxEffectT extends android.support.v17.leanback.widget.ParallaxEffect, PropertyMarkerValueT extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue> {
- ctor public ParallaxEffect();
+ public abstract class ParallaxEffect {
method public final void addTarget(android.support.v17.leanback.widget.ParallaxTarget);
- method protected abstract float calculateFraction(android.support.v17.leanback.widget.Parallax);
- method public final java.util.List<PropertyMarkerValueT> getPropertyRanges();
+ method public final java.util.List<android.support.v17.leanback.widget.Parallax.PropertyMarkerValue> getPropertyRanges();
method public final java.util.List<android.support.v17.leanback.widget.ParallaxTarget> getTargets();
method public final void performMapping(android.support.v17.leanback.widget.Parallax);
method public final void removeTarget(android.support.v17.leanback.widget.ParallaxTarget);
- method public final void setPropertyRanges(PropertyMarkerValueT...);
+ method public final void setPropertyRanges(android.support.v17.leanback.widget.Parallax.PropertyMarkerValue...);
method public final android.support.v17.leanback.widget.ParallaxEffect target(android.support.v17.leanback.widget.ParallaxTarget);
method public final android.support.v17.leanback.widget.ParallaxEffect target(java.lang.Object, android.animation.PropertyValuesHolder);
- }
-
- public static final class ParallaxEffect.FloatEffect extends android.support.v17.leanback.widget.ParallaxEffect {
- ctor public ParallaxEffect.FloatEffect();
- method protected float calculateFraction(android.support.v17.leanback.widget.Parallax);
- }
-
- public static final class ParallaxEffect.IntEffect extends android.support.v17.leanback.widget.ParallaxEffect {
- ctor public ParallaxEffect.IntEffect();
- method protected float calculateFraction(android.support.v17.leanback.widget.Parallax);
+ method public final <T, V extends java.lang.Number> android.support.v17.leanback.widget.ParallaxEffect target(T, android.util.Property<T, V>);
}
public abstract class ParallaxTarget {
ctor public ParallaxTarget();
- method public abstract float getFraction();
- method public abstract void update(float);
+ method public void directUpdate(java.lang.Number);
+ method public boolean isDirectMapping();
+ method public void update(float);
+ }
+
+ public static final class ParallaxTarget.DirectPropertyTarget<T, V extends java.lang.Number> extends android.support.v17.leanback.widget.ParallaxTarget {
+ ctor public ParallaxTarget.DirectPropertyTarget(java.lang.Object, android.util.Property<T, V>);
}
public static final class ParallaxTarget.PropertyValuesHolderTarget extends android.support.v17.leanback.widget.ParallaxTarget {
ctor public ParallaxTarget.PropertyValuesHolderTarget(java.lang.Object, android.animation.PropertyValuesHolder);
- method public float getFraction();
- method public void update(float);
}
public class PlaybackControlsRow extends android.support.v17.leanback.widget.Row {
@@ -4440,10 +4524,10 @@
method public void unselect();
}
- public class RecyclerViewParallax extends android.support.v17.leanback.widget.Parallax.IntParallax {
+ public class RecyclerViewParallax extends android.support.v17.leanback.widget.Parallax {
ctor public RecyclerViewParallax();
method public android.support.v17.leanback.widget.RecyclerViewParallax.ChildPositionProperty createProperty(java.lang.String, int);
- method public int getMaxValue();
+ method public float getMaxValue();
method public android.support.v7.widget.RecyclerView getRecyclerView();
method public void setRecyclerView(android.support.v7.widget.RecyclerView);
}
@@ -6168,6 +6252,13 @@
}
public class ShortcutInfoCompat {
+ method public android.content.ComponentName getActivity();
+ method public java.lang.CharSequence getDisabledMessage();
+ method public java.lang.String getId();
+ method public android.content.Intent getIntent();
+ method public android.content.Intent[] getIntents();
+ method public java.lang.CharSequence getLongLabel();
+ method public java.lang.CharSequence getShortLabel();
}
public static class ShortcutInfoCompat.Builder {
@@ -6184,7 +6275,6 @@
}
public class ShortcutManagerCompat {
- ctor public ShortcutManagerCompat();
method public static android.content.Intent createShortcutResultIntent(android.content.Context, android.support.v4.content.pm.ShortcutInfoCompat);
method public static boolean isRequestPinShortcutSupported(android.content.Context);
method public static boolean requestPinShortcut(android.content.Context, android.support.v4.content.pm.ShortcutInfoCompat, android.content.IntentSender);
@@ -6678,7 +6768,7 @@
ctor public MediaButtonReceiver();
method public static android.app.PendingIntent buildMediaButtonPendingIntent(android.content.Context, long);
method public static android.app.PendingIntent buildMediaButtonPendingIntent(android.content.Context, android.content.ComponentName, long);
- method public static android.view.KeyEvent handleIntent(android.support.v4.media.session.MediaSessionCompat, android.content.Intent);
+ method public static deprecated android.view.KeyEvent handleIntent(android.support.v4.media.session.MediaSessionCompat, android.content.Intent);
method public void onReceive(android.content.Context, android.content.Intent);
}
@@ -6704,6 +6794,7 @@
method public android.app.PendingIntent getSessionActivity();
method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
method public android.support.v4.media.session.MediaControllerCompat.TransportControls getTransportControls();
+ method public boolean isCaptioningEnabled();
method public boolean isShuffleModeEnabled();
method public void registerCallback(android.support.v4.media.session.MediaControllerCompat.Callback);
method public void registerCallback(android.support.v4.media.session.MediaControllerCompat.Callback, android.os.Handler);
@@ -6719,6 +6810,7 @@
ctor public MediaControllerCompat.Callback();
method public void binderDied();
method public void onAudioInfoChanged(android.support.v4.media.session.MediaControllerCompat.PlaybackInfo);
+ method public void onCaptioningEnabledChanged(boolean);
method public void onExtrasChanged(android.os.Bundle);
method public void onMetadataChanged(android.support.v4.media.MediaMetadataCompat);
method public void onPlaybackStateChanged(android.support.v4.media.session.PlaybackStateCompat);
@@ -6755,6 +6847,7 @@
method public abstract void seekTo(long);
method public abstract void sendCustomAction(android.support.v4.media.session.PlaybackStateCompat.CustomAction, android.os.Bundle);
method public abstract void sendCustomAction(java.lang.String, android.os.Bundle);
+ method public abstract void setCaptioningEnabled(boolean);
method public abstract void setRating(android.support.v4.media.RatingCompat);
method public abstract void setRepeatMode(int);
method public abstract void setShuffleModeEnabled(boolean);
@@ -6781,6 +6874,7 @@
method public void setActive(boolean);
method public void setCallback(android.support.v4.media.session.MediaSessionCompat.Callback);
method public void setCallback(android.support.v4.media.session.MediaSessionCompat.Callback, android.os.Handler);
+ method public void setCaptioningEnabled(boolean);
method public void setExtras(android.os.Bundle);
method public void setFlags(int);
method public void setMediaButtonReceiver(android.app.PendingIntent);
@@ -6794,6 +6888,8 @@
method public void setRepeatMode(int);
method public void setSessionActivity(android.app.PendingIntent);
method public void setShuffleModeEnabled(boolean);
+ field public static final java.lang.String ACTION_FLAG_AS_INAPPROPRIATE = "android.support.v4.media.session.action.FLAG_AS_INAPPROPRIATE";
+ field public static final java.lang.String ACTION_SKIP_AD = "android.support.v4.media.session.action.SKIP_AD";
field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4
field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
@@ -6820,6 +6916,7 @@
method public void onRemoveQueueItemAt(int);
method public void onRewind();
method public void onSeekTo(long);
+ method public void onSetCaptioningEnabled(boolean);
method public void onSetRating(android.support.v4.media.RatingCompat);
method public void onSetRepeatMode(int);
method public void onSetShuffleModeEnabled(boolean);
@@ -6898,6 +6995,7 @@
field public static final long ACTION_PREPARE_FROM_URI = 131072L; // 0x20000L
field public static final long ACTION_REWIND = 8L; // 0x8L
field public static final long ACTION_SEEK_TO = 256L; // 0x100L
+ field public static final long ACTION_SET_CAPTIONING_ENABLED = 1048576L; // 0x100000L
field public static final long ACTION_SET_RATING = 128L; // 0x80L
field public static final long ACTION_SET_REPEAT_MODE = 262144L; // 0x40000L
field public static final long ACTION_SET_SHUFFLE_MODE_ENABLED = 524288L; // 0x80000L
@@ -7525,14 +7623,19 @@
method public static deprecated boolean expandActionView(android.view.MenuItem);
method public static android.support.v4.view.ActionProvider getActionProvider(android.view.MenuItem);
method public static deprecated android.view.View getActionView(android.view.MenuItem);
+ method public int getAlphabeticModifiers(android.view.MenuItem);
method public static java.lang.CharSequence getContentDescription(android.view.MenuItem);
+ method public int getNumericModifiers(android.view.MenuItem);
method public static java.lang.CharSequence getTooltipText(android.view.MenuItem);
method public static deprecated boolean isActionViewExpanded(android.view.MenuItem);
method public static android.view.MenuItem setActionProvider(android.view.MenuItem, android.support.v4.view.ActionProvider);
method public static deprecated android.view.MenuItem setActionView(android.view.MenuItem, android.view.View);
method public static deprecated android.view.MenuItem setActionView(android.view.MenuItem, int);
+ method public static void setAlphabeticShortcut(android.view.MenuItem, char, int);
method public static void setContentDescription(android.view.MenuItem, java.lang.CharSequence);
+ method public static void setNumericShortcut(android.view.MenuItem, char, int);
method public static deprecated android.view.MenuItem setOnActionExpandListener(android.view.MenuItem, android.support.v4.view.MenuItemCompat.OnActionExpandListener);
+ method public static void setShortcut(android.view.MenuItem, char, char, int, int);
method public static deprecated void setShowAsAction(android.view.MenuItem, int);
method public static void setTooltipText(android.view.MenuItem, java.lang.CharSequence);
field public static final deprecated int SHOW_AS_ACTION_ALWAYS = 2; // 0x2
@@ -11801,6 +11904,10 @@
field public static final android.os.Parcelable.Creator<android.support.v7.widget.Toolbar.SavedState> CREATOR;
}
+ public class TooltipCompat {
+ method public static void setTooltipText(android.view.View, java.lang.CharSequence);
+ }
+
}
package android.support.v7.widget.helper {
@@ -11917,6 +12024,12 @@
field public int boxedEdges;
}
+ public class CurvedOffsettingHelper extends android.support.wearable.view.WearableRecyclerView.OffsettingHelper {
+ ctor public CurvedOffsettingHelper();
+ method public void adjustAnchorOffsetXY(android.view.View, float[]);
+ method public void updateChild(android.view.View, android.support.wearable.view.WearableRecyclerView);
+ }
+
public class SwipeDismissFrameLayout extends android.widget.FrameLayout {
ctor public SwipeDismissFrameLayout(android.content.Context);
ctor public SwipeDismissFrameLayout(android.content.Context, android.util.AttributeSet);
@@ -11934,5 +12047,27 @@
method public void onSwipeStarted();
}
+ public class WearableRecyclerView extends android.support.v7.widget.RecyclerView {
+ ctor public WearableRecyclerView(android.content.Context);
+ ctor public WearableRecyclerView(android.content.Context, android.util.AttributeSet);
+ ctor public WearableRecyclerView(android.content.Context, android.util.AttributeSet, int);
+ ctor public WearableRecyclerView(android.content.Context, android.util.AttributeSet, int, int);
+ method public float getBezelWidthFraction();
+ method public boolean getEdgeItemsCenteringEnabled();
+ method public android.support.wearable.view.WearableRecyclerView.OffsettingHelper getOffsettingHelper();
+ method public float getScrollDegreesPerScreen();
+ method public boolean isCircularScrollingGestureEnabled();
+ method public void setBezelWidthFraction(float);
+ method public void setCircularScrollingGestureEnabled(boolean);
+ method public void setEdgeItemsCenteringEnabled(boolean);
+ method public void setOffsettingHelper(android.support.wearable.view.WearableRecyclerView.OffsettingHelper);
+ method public void setScrollDegreesPerScreen(float);
+ }
+
+ public static abstract class WearableRecyclerView.OffsettingHelper {
+ ctor public WearableRecyclerView.OffsettingHelper();
+ method public abstract void updateChild(android.view.View, android.support.wearable.view.WearableRecyclerView);
+ }
+
}
diff --git a/build.gradle b/build.gradle
index b3fcda7..98de82b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -17,14 +17,10 @@
buildscript {
ext.supportRootFolder = project.projectDir
apply from: 'buildSrc/init.gradle'
+ init.loadDefaultVersions()
+ init.setSdkInLocalPropertiesFile()
init.addMavenRepositories(repositories)
- dependencies {
- classpath libs.gradle
- }
}
-init.loadDefaultVersions()
-
-init.setSdkInLocalPropertiesFile()
init.addMavenRepositories(repositories)
@@ -34,4 +30,8 @@
init.setupRelease()
-init.enableDoclavaAndJDiff(this)
\ No newline at end of file
+init.enableDoclavaAndJDiff(this)
+
+///// FLATFOOT START
+
+///// FLATFOOT END
\ No newline at end of file
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index ae9582a..1041b12 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -10,4 +10,6 @@
}
dependencies {
compile libs.gradle
+ compile libs.error_prone
+ compile libs.jarjar_gradle
}
diff --git a/buildSrc/dependencies.gradle b/buildSrc/dependencies.gradle
index 284fe01..aa7f93e 100644
--- a/buildSrc/dependencies.gradle
+++ b/buildSrc/dependencies.gradle
@@ -31,5 +31,9 @@
// Other dependencies
libs.xml_parser_apis = 'xerces:xmlParserAPIs:2.6.2'
libs.xerces_impl = 'xerces:xercesImpl:2.6.2'
+libs.error_prone = 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.9'
+
+// jarjar plugin
+libs.jarjar_gradle = 'org.anarres.jarjar:jarjar-gradle:1.0.0'
rootProject.ext['libs'] = libs
diff --git a/buildSrc/diff_and_docs.gradle b/buildSrc/diff_and_docs.gradle
index c6dda4f..9ad419d 100644
--- a/buildSrc/diff_and_docs.gradle
+++ b/buildSrc/diff_and_docs.gradle
@@ -59,7 +59,7 @@
options {
addStringOption "templatedir",
- "${supportRootFolder}/../../build/tools/droiddoc/templates-sdk"
+ "${supportRootFolder}/../../external/doclava/res/assets/templates-sdk"
addStringOption "federate Android", "http://developer.android.com"
addStringOption "stubpackages", "android.support.*"
addStringOption "samplesdir", "${supportRootFolder}/samples"
@@ -102,7 +102,7 @@
options {
addStringOption "templatedir",
- "${supportRootFolder}/../../build/tools/droiddoc/templates-sdk"
+ "${supportRootFolder}/../../external/doclava/res/assets/templates-sdk"
addStringOption "federate Android", "http://developer.android.com"
addStringOption "stubpackages", "android.support.*"
}
@@ -346,16 +346,18 @@
subprojects { subProject ->
subProject.afterEvaluate { p ->
- if (p.hasProperty('android') && p.android.hasProperty('libraryVariants')) {
- p.android.libraryVariants.all { v ->
- if (v.name == 'release') {
- registerForDocsTask(rootProject.generateDocs, p, v)
- registerForDocsTask(rootProject.generateApi, p, v)
- registerForDocsTask(rootProject.generateDiffs, p, v)
+ if (!p.hasProperty("noDocs") || !p.noDocs) {
+ if (p.hasProperty('android') && p.android.hasProperty('libraryVariants')) {
+ p.android.libraryVariants.all { v ->
+ if (v.name == 'release') {
+ registerForDocsTask(rootProject.generateDocs, p, v)
+ registerForDocsTask(rootProject.generateApi, p, v)
+ registerForDocsTask(rootProject.generateDiffs, p, v)
+ }
}
+ } else if (p.hasProperty("compileJava")) {
+ registerJavaProjectForDocsTask(rootProject.generateDocs, p, p.compileJava)
}
- } else if (p.hasProperty("compileJava")) {
- registerJavaProjectForDocsTask(rootProject.generateDocs, p, p.compileJava)
}
}
}
diff --git a/buildSrc/init.gradle b/buildSrc/init.gradle
index 988da6d..25281df 100644
--- a/buildSrc/init.gradle
+++ b/buildSrc/init.gradle
@@ -85,11 +85,13 @@
System.setProperty('android.home', "${init.prebuiltsRoot}/fullsdk-${platform}")
File props = file("local.properties")
props.write "sdk.dir=${fullSdkPath}"
+ ext.usingFullSdk = true
} else {
gradle.ext.currentSdk = 'current'
project.ext.androidJar = files("${init.prebuiltsRoot}/sdk/current/android.jar")
File props = file("local.properties")
props.write "android.dir=../../"
+ ext.usingFullSdk = false
}
}
@@ -325,7 +327,8 @@
if (junitReport.enabled) {
def zipTask = project.tasks.create(name : "zipResultsOf${task.name.capitalize()}", type : Zip) {
destinationDir(testResultsDistDir)
- archiveName("${project.name}.zip")
+ // first one is always :, drop it.
+ archiveName("${project.getPath().split(":").join("_").substring(1)}.zip")
}
if (project.rootProject.ext.runningInBuildServer) {
task.ignoreFailures = true
diff --git a/buildSrc/release.gradle b/buildSrc/release.gradle
index 7749f8d..83871b8 100644
--- a/buildSrc/release.gradle
+++ b/buildSrc/release.gradle
@@ -27,27 +27,42 @@
// to the local repo.
task(mainUpload)
+rootProject.ext.repoWithHistoryOut = new File(buildDir, 'support_repo_with_history')
+
// repository creation task
task createRepository(type: Zip, dependsOn: mainUpload) {
- from project.ext.supportRepoOut
+ from rootProject.ext.supportRepoOut
+ from "${init.prebuiltsRoot}/maven_repo/android"
+ // if there are duplicates, pick the first one.
+ duplicatesStrategy "EXCLUDE"
destinationDir project.ext.distDir
into 'm2repository'
baseName = String.format("sdk-repo-linux-m2repository-%s", project.ext.buildNumber)
}
+
+task createTopOfTreeRepository(type : Zip) {
+ description "Creates a maven repository that includes just the libraries compiled in this" +
+ " project, without any history from prebuilts."
+ from rootProject.ext.supportRepoOut
+ destinationDir rootProject.ext.distDir
+ into 'm2repository'
+ baseName = String.format("top-of-tree-m2repository-%s", project.ext.buildNumber)
+ dependsOn mainUpload
+}
+
createArchive.dependsOn createRepository
-
-// prepare repository with older versions
-task unzipRepo(type: Copy) {
- from "${init.prebuiltsRoot}/maven_repo/android"
- into project.ext.supportRepoOut
-}
-
-unzipRepo.doFirst {
- project.ext.supportRepoOut.deleteDir()
- project.ext.supportRepoOut.mkdirs()
-}
+createRepository.dependsOn createTopOfTreeRepository
// anchor for prepare repo. This is post unzip + sourceProp.
+task nukeRepoOut() {
+ description "This task clears the repo folder to ensure that we run a fresh build every" +
+ " time we create arhives. Otherwise, snapshots will accumulate in the builds folder."
+ doFirst {
+ rootProject.ext.supportRepoOut.deleteDir()
+ rootProject.ext.supportRepoOut.mkdirs()
+ }
+}
+
task(prepareRepo)
task(createXml).doLast({
@@ -94,7 +109,7 @@
Files.write(sourceProp, new File(project.ext.supportRepoOut, 'source.properties'), Charsets.UTF_8)
})
-createSourceProp.dependsOn unzipRepo
+createSourceProp.dependsOn nukeRepoOut
prepareRepo.dependsOn createSourceProp
/**
@@ -107,4 +122,4 @@
HashFunction hashFunction = Hashing.sha1()
HashCode hashCode = hashFunction.hashString(inputFile.getAbsolutePath(), Charset.forName("UTF-8"))
return hashCode.toString()
-}
\ No newline at end of file
+}
diff --git a/buildSrc/src/main/groovy/android/support/SupportLibraryPlugin.groovy b/buildSrc/src/main/groovy/android/support/SupportLibraryPlugin.groovy
index f1f6a04..6cdf079 100644
--- a/buildSrc/src/main/groovy/android/support/SupportLibraryPlugin.groovy
+++ b/buildSrc/src/main/groovy/android/support/SupportLibraryPlugin.groovy
@@ -21,6 +21,8 @@
import com.android.build.gradle.api.LibraryVariant
import com.android.builder.core.BuilderConstants
import com.google.common.collect.ImmutableMap
+import net.ltgt.gradle.errorprone.ErrorProneBasePlugin
+import net.ltgt.gradle.errorprone.ErrorProneToolChain
import org.gradle.api.Action
import org.gradle.api.JavaVersion
import org.gradle.api.Plugin
@@ -43,6 +45,8 @@
project.getExtensions().create("supportLibrary", SupportLibraryExtension);
project.apply(ImmutableMap.of("plugin", "com.android.library"));
+ project.apply(ImmutableMap.of("plugin", ErrorProneBasePlugin.class));
+
LibraryExtension library =
project.getExtensions().findByType(LibraryExtension.class);
@@ -88,8 +92,10 @@
error 'NewApi'
}
- // Library projects don't run lint by default, so set up dependency.
- project.tasks.release.dependsOn project.tasks.lint
+ if (project.rootProject.ext.usingFullSdk) {
+ // Library projects don't run lint by default, so set up dependency.
+ project.tasks.release.dependsOn project.tasks.lint
+ }
// Java 8 is only fully supported on API 24+ and not all Java 8 features are binary
// compatible with API < 24, so use Java 7 for both source AND target.
@@ -151,5 +157,29 @@
}
});
}
+
+ final ErrorProneToolChain toolChain = ErrorProneToolChain.create(project);
+ library.getBuildTypes().create("errorProne")
+ library.getLibraryVariants().all(new Action<LibraryVariant>() {
+ @Override
+ void execute(LibraryVariant libraryVariant) {
+ if (libraryVariant.getBuildType().getName().equals("errorProne")) {
+ libraryVariant.getJavaCompile().setToolChain(toolChain);
+
+ // TODO(aurimas): remove this once all these warnings are fixed.
+ libraryVariant.getJavaCompile().options.compilerArgs += [
+ '-Xep:EqualsHashCode:OFF',
+ '-Xep:MissingCasesInEnumSwitch:WARN',
+ '-Xep:TypeParameterUnusedInFormals:WARN',
+ '-Xep:MissingOverride:WARN',
+ '-Xep:ArrayToString:WARN',
+ '-Xep:MislabeledAndroidString:WARN',
+ '-Xep:SelfEquals:WARN',
+ '-Xep:RectIntersectReturnValueIgnored:WARN',
+ '-Xep:FallThrough:WARN'
+ ]
+ }
+ }
+ })
}
}
diff --git a/compat/api21/android/support/v4/app/ActivityOptionsCompat21.java b/compat/api21/android/support/v4/app/ActivityOptionsCompat21.java
index 8f2b2e8..0b04ba8 100644
--- a/compat/api21/android/support/v4/app/ActivityOptionsCompat21.java
+++ b/compat/api21/android/support/v4/app/ActivityOptionsCompat21.java
@@ -55,9 +55,10 @@
sharedElementName));
}
+ @SuppressWarnings("unchecked")
public static ActivityOptionsCompat21 makeSceneTransitionAnimation(Activity activity,
View[] sharedElements, String[] sharedElementNames) {
- Pair[] pairs = null;
+ Pair<View, String>[] pairs = null;
if (sharedElements != null) {
pairs = new Pair[sharedElements.length];
for (int i = 0; i < pairs.length; i++) {
diff --git a/compat/api21/android/support/v4/widget/PopupWindowCompatApi21.java b/compat/api21/android/support/v4/widget/PopupWindowCompatApi21.java
deleted file mode 100644
index f231722..0000000
--- a/compat/api21/android/support/v4/widget/PopupWindowCompatApi21.java
+++ /dev/null
@@ -1,62 +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 android.support.v4.widget;
-
-import android.support.annotation.RequiresApi;
-import android.util.Log;
-import android.widget.PopupWindow;
-
-import java.lang.reflect.Field;
-
-@RequiresApi(21)
-class PopupWindowCompatApi21 {
-
- private static final String TAG = "PopupWindowCompatApi21";
-
- private static Field sOverlapAnchorField;
-
- static {
- try {
- sOverlapAnchorField = PopupWindow.class.getDeclaredField("mOverlapAnchor");
- sOverlapAnchorField.setAccessible(true);
- } catch (NoSuchFieldException e) {
- Log.i(TAG, "Could not fetch mOverlapAnchor field from PopupWindow", e);
- }
- }
-
- static void setOverlapAnchor(PopupWindow popupWindow, boolean overlapAnchor) {
- if (sOverlapAnchorField != null) {
- try {
- sOverlapAnchorField.set(popupWindow, overlapAnchor);
- } catch (IllegalAccessException e) {
- Log.i(TAG, "Could not set overlap anchor field in PopupWindow", e);
- }
- }
- }
-
- static boolean getOverlapAnchor(PopupWindow popupWindow) {
- if (sOverlapAnchorField != null) {
- try {
- return (Boolean) sOverlapAnchorField.get(popupWindow);
- } catch (IllegalAccessException e) {
- Log.i(TAG, "Could not get overlap anchor field in PopupWindow", e);
- }
- }
- return false;
- }
-
-}
diff --git a/compat/api23/android/support/v4/app/ActivityOptionsCompat23.java b/compat/api23/android/support/v4/app/ActivityOptionsCompat23.java
index 08863a5..a5daaa7 100644
--- a/compat/api23/android/support/v4/app/ActivityOptionsCompat23.java
+++ b/compat/api23/android/support/v4/app/ActivityOptionsCompat23.java
@@ -56,9 +56,10 @@
sharedElementName));
}
+ @SuppressWarnings("unchecked")
public static ActivityOptionsCompat23 makeSceneTransitionAnimation(Activity activity,
View[] sharedElements, String[] sharedElementNames) {
- Pair[] pairs = null;
+ Pair<View, String>[] pairs = null;
if (sharedElements != null) {
pairs = new Pair[sharedElements.length];
for (int i = 0; i < pairs.length; i++) {
diff --git a/compat/api23/android/support/v4/widget/PopupWindowCompatApi23.java b/compat/api23/android/support/v4/widget/PopupWindowCompatApi23.java
deleted file mode 100644
index 9d30f61..0000000
--- a/compat/api23/android/support/v4/widget/PopupWindowCompatApi23.java
+++ /dev/null
@@ -1,41 +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 android.support.v4.widget;
-
-import android.support.annotation.RequiresApi;
-import android.widget.PopupWindow;
-
-@RequiresApi(23)
-class PopupWindowCompatApi23 {
-
- static void setOverlapAnchor(PopupWindow popupWindow, boolean overlapAnchor) {
- popupWindow.setOverlapAnchor(overlapAnchor);
- }
-
- static boolean getOverlapAnchor(PopupWindow popupWindow) {
- return popupWindow.getOverlapAnchor();
- }
-
- static void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
- popupWindow.setWindowLayoutType(layoutType);
- }
-
- static int getWindowLayoutType(PopupWindow popupWindow) {
- return popupWindow.getWindowLayoutType();
- }
-
-}
diff --git a/compat/api24/android/support/v4/app/ActivityOptionsCompat24.java b/compat/api24/android/support/v4/app/ActivityOptionsCompat24.java
index 8e0d520..608c017 100644
--- a/compat/api24/android/support/v4/app/ActivityOptionsCompat24.java
+++ b/compat/api24/android/support/v4/app/ActivityOptionsCompat24.java
@@ -56,9 +56,10 @@
sharedElementName));
}
+ @SuppressWarnings("unchecked")
public static ActivityOptionsCompat24 makeSceneTransitionAnimation(Activity activity,
View[] sharedElements, String[] sharedElementNames) {
- Pair[] pairs = null;
+ Pair<View, String>[] pairs = null;
if (sharedElements != null) {
pairs = new Pair[sharedElements.length];
for (int i = 0; i < pairs.length; i++) {
diff --git a/compat/ics/android/support/v4/graphics/PaintCompatApi14.java b/compat/ics/android/support/v4/graphics/PaintCompatApi14.java
index b459623..86e87d8 100644
--- a/compat/ics/android/support/v4/graphics/PaintCompatApi14.java
+++ b/compat/ics/android/support/v4/graphics/PaintCompatApi14.java
@@ -88,7 +88,7 @@
private static Pair<Rect, Rect> obtainEmptyRects() {
Pair<Rect, Rect> rects = sRectThreadLocal.get();
if (rects == null) {
- rects = new Pair(new Rect(), new Rect());
+ rects = new Pair<>(new Rect(), new Rect());
sRectThreadLocal.set(rects);
} else {
rects.first.setEmpty();
diff --git a/compat/ics/android/support/v4/view/ViewCompatICS.java b/compat/ics/android/support/v4/view/ViewCompatICS.java
deleted file mode 100644
index 1c4c2e4..0000000
--- a/compat/ics/android/support/v4/view/ViewCompatICS.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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.v4.view;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.support.annotation.RequiresApi;
-import android.support.v4.view.accessibility.AccessibilityManagerCompat;
-import android.text.TextUtils;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.accessibility.AccessibilityManager;
-import android.widget.Toast;
-
-@RequiresApi(14)
-class ViewCompatICS {
-
- public static void setTooltipText(View view, CharSequence tooltipText) {
- if (TextUtils.isEmpty(tooltipText)) {
- view.setOnLongClickListener(null);
- view.setLongClickable(false);
- view.setOnHoverListener(null);
- } else {
- new TooltipHandler(view, tooltipText);
- }
- }
-
- private static class TooltipHandler implements View.OnLongClickListener, View.OnHoverListener {
- private final View mAnchor;
- private final CharSequence mTooltipText;
- private final Runnable mShowRunnable = new Runnable() {
- @Override
- public void run() {
- show(Toast.LENGTH_LONG);
- }
- };
- private Toast mTooltip;
-
- TooltipHandler(View anchor, CharSequence tooltipText) {
- mAnchor = anchor;
- mTooltipText = tooltipText;
-
- mAnchor.setOnLongClickListener(this);
- mAnchor.setOnHoverListener(this);
- }
-
- @Override
- public boolean onLongClick(View v) {
- show(Toast.LENGTH_SHORT);
- return true;
- }
-
- @Override
- public boolean onHover(View v, MotionEvent event) {
- AccessibilityManager manager = (AccessibilityManager)
- mAnchor.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
- if (manager.isEnabled()
- && AccessibilityManagerCompat.isTouchExplorationEnabled(manager)) {
- return false;
- }
- final int action = event.getAction();
- if (action == MotionEvent.ACTION_HOVER_MOVE) {
- hide();
- mAnchor.getHandler().postDelayed(
- mShowRunnable, ViewConfiguration.getLongPressTimeout());
- } else if (action == MotionEvent.ACTION_HOVER_EXIT) {
- hide();
- }
- return false;
- }
-
- private void show(int duration) {
- final Context context = mAnchor.getContext();
- final Resources resources = context.getResources();
- final int screenWidth = resources.getDisplayMetrics().widthPixels;
- final int screenHeight = resources.getDisplayMetrics().heightPixels;
-
- final Rect displayFrame = new Rect();
- mAnchor.getWindowVisibleDisplayFrame(displayFrame);
- if (displayFrame.left < 0 && displayFrame.top < 0) {
- // No meaningful display frame, the anchor view is probably in a subpanel
- // (such as a popup window). Use the screen frame as a reasonable approximation.
- final int statusBarHeight;
- int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
- if (resourceId > 0) {
- statusBarHeight = resources.getDimensionPixelSize(resourceId);
- } else {
- statusBarHeight = 0;
- }
- displayFrame.set(0, statusBarHeight, screenWidth, screenHeight);
- }
-
- final int[] anchorPos = new int[2];
- mAnchor.getLocationOnScreen(anchorPos);
- int referenceX = anchorPos[0] + mAnchor.getWidth() / 2;
- if (ViewCompat.getLayoutDirection(mAnchor) == ViewCompat.LAYOUT_DIRECTION_LTR) {
- referenceX = screenWidth - referenceX; // mirror
- }
- final int anchorTop = anchorPos[1];
- hide();
- mTooltip = Toast.makeText(context, mTooltipText, duration);
- if (anchorTop < displayFrame.height() * 0.8) {
- // Show along the bottom of the anchor view.
- mTooltip.setGravity(Gravity.TOP | GravityCompat.END, referenceX,
- anchorTop + mAnchor.getHeight() - displayFrame.top);
- } else {
- // Show along the top of the anchor view.
- mTooltip.setGravity(Gravity.BOTTOM | GravityCompat.END, referenceX,
- displayFrame.bottom - anchorTop);
- }
- mTooltip.show();
- }
-
- private void hide() {
- if (mTooltip != null) {
- mTooltip.cancel();
- mTooltip = null;
- }
- mAnchor.getHandler().removeCallbacks(mShowRunnable);
- }
- }
-}
diff --git a/compat/java/android/support/v4/app/NotificationManagerCompat.java b/compat/java/android/support/v4/app/NotificationManagerCompat.java
index 0cdd765..8b7841e 100644
--- a/compat/java/android/support/v4/app/NotificationManagerCompat.java
+++ b/compat/java/android/support/v4/app/NotificationManagerCompat.java
@@ -16,7 +16,6 @@
package android.support.v4.app;
-import android.support.annotation.RequiresApi;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
@@ -35,6 +34,7 @@
import android.os.Message;
import android.os.RemoteException;
import android.provider.Settings;
+import android.support.annotation.RequiresApi;
import android.support.v4.os.BuildCompat;
import android.util.Log;
@@ -611,7 +611,7 @@
final ComponentName componentName;
final IBinder iBinder;
- public ServiceConnectedEvent(ComponentName componentName,
+ ServiceConnectedEvent(ComponentName componentName,
final IBinder iBinder) {
this.componentName = componentName;
this.iBinder = iBinder;
@@ -619,7 +619,7 @@
}
private interface Task {
- public void send(INotificationSideChannel service) throws RemoteException;
+ void send(INotificationSideChannel service) throws RemoteException;
}
private static class NotifyTask implements Task {
@@ -628,7 +628,7 @@
final String tag;
final Notification notif;
- public NotifyTask(String packageName, int id, String tag, Notification notif) {
+ NotifyTask(String packageName, int id, String tag, Notification notif) {
this.packageName = packageName;
this.id = id;
this.tag = tag;
@@ -640,6 +640,7 @@
service.notify(packageName, id, tag, notif);
}
+ @Override
public String toString() {
StringBuilder sb = new StringBuilder("NotifyTask[");
sb.append("packageName:").append(packageName);
@@ -656,14 +657,14 @@
final String tag;
final boolean all;
- public CancelTask(String packageName) {
+ CancelTask(String packageName) {
this.packageName = packageName;
this.id = 0;
this.tag = null;
this.all = true;
}
- public CancelTask(String packageName, int id, String tag) {
+ CancelTask(String packageName, int id, String tag) {
this.packageName = packageName;
this.id = id;
this.tag = tag;
@@ -679,6 +680,7 @@
}
}
+ @Override
public String toString() {
StringBuilder sb = new StringBuilder("CancelTask[");
sb.append("packageName:").append(packageName);
diff --git a/compat/java/android/support/v4/app/SharedElementCallback.java b/compat/java/android/support/v4/app/SharedElementCallback.java
index 5c64762..c218d86 100644
--- a/compat/java/android/support/v4/app/SharedElementCallback.java
+++ b/compat/java/android/support/v4/app/SharedElementCallback.java
@@ -190,9 +190,9 @@
int bitmapHeight = Math.round(screenBounds.height());
Bitmap bitmap = null;
if (bitmapWidth > 0 && bitmapHeight > 0) {
- float scale = Math.min(1f, ((float)MAX_IMAGE_SIZE) / (bitmapWidth * bitmapHeight));
- bitmapWidth *= scale;
- bitmapHeight *= scale;
+ float scale = Math.min(1f, ((float) MAX_IMAGE_SIZE) / (bitmapWidth * bitmapHeight));
+ bitmapWidth = (int) (bitmapWidth * scale);
+ bitmapHeight = (int) (bitmapHeight * scale);
if (mTempMatrix == null) {
mTempMatrix = new Matrix();
}
diff --git a/compat/java/android/support/v4/content/ModernAsyncTask.java b/compat/java/android/support/v4/content/ModernAsyncTask.java
index 306d334..db07ee5 100644
--- a/compat/java/android/support/v4/content/ModernAsyncTask.java
+++ b/compat/java/android/support/v4/content/ModernAsyncTask.java
@@ -47,7 +47,7 @@
*
* <p>Note that for now this is not publicly available because it is not a
* complete implementation, only sufficient for the needs of
- * {@link AsyncTaskLoader}.
+ * {@link android.content.AsyncTaskLoader}.
*/
abstract class ModernAsyncTask<Params, Progress, Result> {
private static final String LOG_TAG = "AsyncTask";
@@ -436,6 +436,8 @@
throw new IllegalStateException("Cannot execute task:"
+ " the task has already been executed "
+ "(a task can be executed only once)");
+ default:
+ throw new IllegalStateException("We should never reach this state");
}
}
diff --git a/compat/java/android/support/v4/content/pm/ShortcutInfoCompat.java b/compat/java/android/support/v4/content/pm/ShortcutInfoCompat.java
index b6ac319..bbb2568 100644
--- a/compat/java/android/support/v4/content/pm/ShortcutInfoCompat.java
+++ b/compat/java/android/support/v4/content/pm/ShortcutInfoCompat.java
@@ -15,7 +15,6 @@
*/
package android.support.v4.content.pm;
-import android.support.annotation.RequiresApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -24,8 +23,12 @@
import android.graphics.drawable.Icon;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.RequiresApi;
import android.text.TextUtils;
+import java.util.Arrays;
+
/**
* Helper for accessing features in {@link android.content.pm.ShortcutInfo}
* introduced after API level 25 in a backwards compatible fashion.
@@ -83,6 +86,84 @@
}
/**
+ * Returns the ID of a shortcut.
+ *
+ * <p>Shortcut IDs are unique within each publisher app and must be stable across
+ * devices so that shortcuts will still be valid when restored on a different device.
+ * See {@link android.content.pm.ShortcutManager} for details.
+ */
+ @NonNull
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Return the target activity.
+ *
+ * <p>This has nothing to do with the activity that this shortcut will launch.
+ * Launcher apps should show the launcher icon for the returned activity alongside
+ * this shortcut.
+ *
+ * @see Builder#setActivity(ComponentName)
+ */
+ @Nullable
+ public ComponentName getActivity() {
+ return mActivity;
+ }
+
+ /**
+ * Return the short description of a shortcut.
+ *
+ * @see Builder#setShortLabel(CharSequence)
+ */
+ @NonNull
+ public CharSequence getShortLabel() {
+ return mLabel;
+ }
+
+ /**
+ * Return the long description of a shortcut.
+ *
+ * @see Builder#setLongLabel(CharSequence)
+ */
+ @Nullable
+ public CharSequence getLongLabel() {
+ return mLongLabel;
+ }
+
+ /**
+ * Return the message that should be shown when the user attempts to start a shortcut
+ * that is disabled.
+ *
+ * @see Builder#setDisabledMessage(CharSequence)
+ */
+ @Nullable
+ public CharSequence getDisabledMessage() {
+ return mDisabledMessage;
+ }
+
+ /**
+ * Returns the intent that is executed when the user selects this shortcut.
+ * If setIntents() was used, then return the last intent in the array.
+ *
+ * @see Builder#setIntent(Intent)
+ */
+ @NonNull
+ public Intent getIntent() {
+ return mIntents[mIntents.length - 1];
+ }
+
+ /**
+ * Return the intent set with {@link Builder#setIntents(Intent[])}.
+ *
+ * @see Builder#setIntents(Intent[])
+ */
+ @NonNull
+ public Intent[] getIntents() {
+ return Arrays.copyOf(mIntents, mIntents.length);
+ }
+
+ /**
* Builder class for {@link ShortcutInfoCompat} objects.
*/
public static class Builder {
@@ -194,7 +275,7 @@
}
/**
- * Sets an icon of a shortcut.
+ * Creates a {@link ShortcutInfoCompat} instance.
*/
@NonNull
public ShortcutInfoCompat build() {
diff --git a/compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java b/compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java
index 732a14f..b421a1c 100644
--- a/compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java
+++ b/compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java
@@ -43,6 +43,10 @@
@VisibleForTesting static final String INSTALL_SHORTCUT_PERMISSION =
"com.android.launcher.permission.INSTALL_SHORTCUT";
+ private ShortcutManagerCompat() {
+ /* Hide constructor */
+ }
+
/**
* @return {@code true} if the launcher supports {@link #requestPinShortcut},
* {@code false} otherwise
diff --git a/compat/java/android/support/v4/internal/view/SupportMenu.java b/compat/java/android/support/v4/internal/view/SupportMenu.java
index 55b8a95..c072151 100644
--- a/compat/java/android/support/v4/internal/view/SupportMenu.java
+++ b/compat/java/android/support/v4/internal/view/SupportMenu.java
@@ -19,6 +19,7 @@
import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
import android.support.annotation.RestrictTo;
+import android.view.KeyEvent;
/**
* Interface for managing the items in a menu.
@@ -53,6 +54,13 @@
int CATEGORY_SHIFT = 16;
/**
+ * A mask of all supported modifiers for MenuItem's keyboard shortcuts
+ */
+ int SUPPORTED_MODIFIERS_MASK = KeyEvent.META_META_ON | KeyEvent.META_CTRL_ON
+ | KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON | KeyEvent.META_SYM_ON
+ | KeyEvent.META_FUNCTION_ON;
+
+ /**
* Flag which stops the Menu being closed when a sub menu is opened
*/
int FLAG_KEEP_OPEN_ON_SUBMENU_OPENED = 4;
diff --git a/compat/java/android/support/v4/internal/view/SupportMenuItem.java b/compat/java/android/support/v4/internal/view/SupportMenuItem.java
index 504b579..109cdb0 100644
--- a/compat/java/android/support/v4/internal/view/SupportMenuItem.java
+++ b/compat/java/android/support/v4/internal/view/SupportMenuItem.java
@@ -249,4 +249,94 @@
*/
@Override
CharSequence getTooltipText();
+
+ /**
+ * Change both the numeric and alphabetic shortcut associated with this
+ * item. Note that the shortcut will be triggered when the key that
+ * generates the given character is pressed along with the corresponding
+ * modifier key. Also note that case is not significant and that alphabetic
+ * shortcut characters will be handled in lower case.
+ * <p>
+ * See {@link Menu} for the menu types that support shortcuts.
+ *
+ * @param numericChar The numeric shortcut key. This is the shortcut when
+ * using a numeric (e.g., 12-key) keyboard.
+ * @param numericModifiers The numeric modifier associated with the shortcut. It should
+ * be a combination of {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_CTRL_ON},
+ * {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_SHIFT_ON},
+ * {@link KeyEvent#META_SYM_ON}, {@link KeyEvent#META_FUNCTION_ON}.
+ * @param alphaChar The alphabetic shortcut key. This is the shortcut when
+ * using a keyboard with alphabetic keys.
+ * @param alphaModifiers The alphabetic modifier associated with the shortcut. It should
+ * be a combination of {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_CTRL_ON},
+ * {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_SHIFT_ON},
+ * {@link KeyEvent#META_SYM_ON}, {@link KeyEvent#META_FUNCTION_ON}.
+ * @return This Item so additional setters can be called.
+ */
+ @Override
+ MenuItem setShortcut(char numericChar, char alphaChar, int numericModifiers,
+ int alphaModifiers);
+
+ /**
+ * Change the numeric shortcut and modifiers associated with this item.
+ * <p>
+ * See {@link Menu} for the menu types that support shortcuts.
+ *
+ * @param numericChar The numeric shortcut key. This is the shortcut when
+ * using a 12-key (numeric) keyboard.
+ * @param numericModifiers The modifier associated with the shortcut. It should
+ * be a combination of {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_CTRL_ON},
+ * {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_SHIFT_ON},
+ * {@link KeyEvent#META_SYM_ON}, {@link KeyEvent#META_FUNCTION_ON}.
+ * @return This Item so additional setters can be called.
+ */
+ @Override
+ MenuItem setNumericShortcut(char numericChar, int numericModifiers);
+
+ /**
+ * Return the modifiers for this menu item's numeric (12-key) shortcut.
+ * The modifier is a combination of {@link KeyEvent#META_META_ON},
+ * {@link KeyEvent#META_CTRL_ON}, {@link KeyEvent#META_ALT_ON},
+ * {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_SYM_ON},
+ * {@link KeyEvent#META_FUNCTION_ON}.
+ * For example, {@link KeyEvent#META_FUNCTION_ON}|{@link KeyEvent#META_CTRL_ON}
+ *
+ * @return Modifier associated with the numeric shortcut.
+ */
+ @Override
+ int getNumericModifiers();
+
+ /**
+ * Change the alphabetic shortcut associated with this item. The shortcut
+ * will be triggered when the key that generates the given character is
+ * pressed along with the modifier keys. Case is not significant and shortcut
+ * characters will be displayed in lower case. Note that menu items with
+ * the characters '\b' or '\n' as shortcuts will get triggered by the
+ * Delete key or Carriage Return key, respectively.
+ * <p>
+ * See {@link Menu} for the menu types that support shortcuts.
+ *
+ * @param alphaChar The alphabetic shortcut key. This is the shortcut when
+ * using a keyboard with alphabetic keys.
+ * @param alphaModifiers The modifier associated with the shortcut. It should
+ * be a combination of {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_CTRL_ON},
+ * {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_SHIFT_ON},
+ * {@link KeyEvent#META_SYM_ON}, {@link KeyEvent#META_FUNCTION_ON}.
+ * @return This Item so additional setters can be called.
+ */
+ @Override
+ MenuItem setAlphabeticShortcut(char alphaChar, int alphaModifiers);
+
+ /**
+ * Return the modifier for this menu item's alphabetic shortcut.
+ * The modifier is a combination of {@link KeyEvent#META_META_ON},
+ * {@link KeyEvent#META_CTRL_ON}, {@link KeyEvent#META_ALT_ON},
+ * {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_SYM_ON},
+ * {@link KeyEvent#META_FUNCTION_ON}.
+ * For example, {@link KeyEvent#META_FUNCTION_ON}|{@link KeyEvent#META_CTRL_ON}
+ *
+ * @return Modifier associated with the keyboard shortcut.
+ */
+ @Override
+ int getAlphabeticModifiers();
}
\ No newline at end of file
diff --git a/compat/java/android/support/v4/util/MapCollections.java b/compat/java/android/support/v4/util/MapCollections.java
index 441f338..1a0ab6b 100644
--- a/compat/java/android/support/v4/util/MapCollections.java
+++ b/compat/java/android/support/v4/util/MapCollections.java
@@ -20,6 +20,7 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.Set;
/**
@@ -49,6 +50,7 @@
@Override
public T next() {
+ if (!hasNext()) throw new NoSuchElementException();
Object res = colGetEntry(mIndex, mOffset);
mIndex++;
mCanRemove = true;
@@ -84,6 +86,7 @@
@Override
public Map.Entry<K, V> next() {
+ if (!hasNext()) throw new NoSuchElementException();
mIndex++;
mEntryValid = true;
return this;
diff --git a/compat/java/android/support/v4/view/LayoutInflaterCompat.java b/compat/java/android/support/v4/view/LayoutInflaterCompat.java
index 1444b58..50f494b 100644
--- a/compat/java/android/support/v4/view/LayoutInflaterCompat.java
+++ b/compat/java/android/support/v4/view/LayoutInflaterCompat.java
@@ -56,6 +56,7 @@
return mDelegateFactory.onCreateView(parent, name, context, attributeSet);
}
+ @Override
public String toString() {
return getClass().getName() + "{" + mDelegateFactory + "}";
}
diff --git a/compat/java/android/support/v4/view/MenuItemCompat.java b/compat/java/android/support/v4/view/MenuItemCompat.java
index d21be25..0c5ba63 100644
--- a/compat/java/android/support/v4/view/MenuItemCompat.java
+++ b/compat/java/android/support/v4/view/MenuItemCompat.java
@@ -20,6 +20,8 @@
import android.support.v4.internal.view.SupportMenuItem;
import android.support.v4.os.BuildCompat;
import android.util.Log;
+import android.view.KeyEvent;
+import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -90,6 +92,12 @@
CharSequence getContentDescription(MenuItem item);
void setTooltipText(MenuItem item, CharSequence tooltipText);
CharSequence getTooltipText(MenuItem item);
+ void setShortcut(MenuItem item, char numericChar, char alphaChar, int numericModifiers,
+ int alphaModifiers);
+ void setAlphabeticShortcut(MenuItem item, char alphaChar, int alphaModifiers);
+ int getAlphabeticModifiers(MenuItem item);
+ void setNumericShortcut(MenuItem item, char numericChar, int numericModifiers);
+ int getNumericModifiers(MenuItem item);
}
/**
@@ -142,6 +150,29 @@
public CharSequence getTooltipText(MenuItem item) {
return null;
}
+
+ @Override
+ public void setShortcut(MenuItem item, char numericChar, char alphaChar,
+ int numericModifiers, int alphaModifiers) {
+ }
+
+ @Override
+ public void setAlphabeticShortcut(MenuItem item, char alphaChar, int alphaModifiers) {
+ }
+
+ @Override
+ public int getAlphabeticModifiers(MenuItem item) {
+ return 0;
+ }
+
+ @Override
+ public void setNumericShortcut(MenuItem item, char numericChar, int numericModifiers) {
+ }
+
+ @Override
+ public int getNumericModifiers(MenuItem item) {
+ return 0;
+ }
}
@RequiresApi(26)
@@ -165,6 +196,32 @@
public CharSequence getTooltipText(MenuItem item) {
return item.getTooltipText();
}
+
+ @Override
+ public void setShortcut(MenuItem item, char numericChar, char alphaChar,
+ int numericModifiers, int alphaModifiers) {
+ item.setShortcut(numericChar, alphaChar, numericModifiers, alphaModifiers);
+ }
+
+ @Override
+ public void setAlphabeticShortcut(MenuItem item, char alphaChar, int alphaModifiers) {
+ item.setAlphabeticShortcut(alphaChar, alphaModifiers);
+ }
+
+ @Override
+ public int getAlphabeticModifiers(MenuItem item) {
+ return item.getAlphabeticModifiers();
+ }
+
+ @Override
+ public void setNumericShortcut(MenuItem item, char numericChar, int numericModifiers) {
+ item.setNumericShortcut(numericChar, numericModifiers);
+ }
+
+ @Override
+ public int getNumericModifiers(MenuItem item) {
+ return item.getNumericModifiers();
+ }
}
/**
@@ -426,5 +483,116 @@
return IMPL.getTooltipText(item);
}
+ /**
+ * Change both the numeric and alphabetic shortcut associated with this
+ * item. Note that the shortcut will be triggered when the key that
+ * generates the given character is pressed along with the corresponding
+ * modifier key. Also note that case is not significant and that alphabetic
+ * shortcut characters will be handled in lower case.
+ * <p>
+ * See {@link Menu} for the menu types that support shortcuts.
+ *
+ * @param numericChar The numeric shortcut key. This is the shortcut when
+ * using a numeric (e.g., 12-key) keyboard.
+ * @param numericModifiers The numeric modifier associated with the shortcut. It should
+ * be a combination of {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_CTRL_ON},
+ * {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_SHIFT_ON},
+ * {@link KeyEvent#META_SYM_ON}, {@link KeyEvent#META_FUNCTION_ON}.
+ * @param alphaChar The alphabetic shortcut key. This is the shortcut when
+ * using a keyboard with alphabetic keys.
+ * @param alphaModifiers The alphabetic modifier associated with the shortcut. It should
+ * be a combination of {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_CTRL_ON},
+ * {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_SHIFT_ON},
+ * {@link KeyEvent#META_SYM_ON}, {@link KeyEvent#META_FUNCTION_ON}.
+ */
+ public static void setShortcut(MenuItem item, char numericChar, char alphaChar,
+ int numericModifiers, int alphaModifiers) {
+ if (item instanceof SupportMenuItem) {
+ ((SupportMenuItem) item).setShortcut(numericChar, alphaChar, numericModifiers,
+ alphaModifiers);
+ } else {
+ IMPL.setShortcut(item, numericChar, alphaChar, numericModifiers, alphaModifiers);
+ }
+ }
+
+ /**
+ * Change the numeric shortcut and modifiers associated with this item.
+ * <p>
+ * See {@link Menu} for the menu types that support shortcuts.
+ *
+ * @param numericChar The numeric shortcut key. This is the shortcut when
+ * using a 12-key (numeric) keyboard.
+ * @param numericModifiers The modifier associated with the shortcut. It should
+ * be a combination of {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_CTRL_ON},
+ * {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_SHIFT_ON},
+ * {@link KeyEvent#META_SYM_ON}, {@link KeyEvent#META_FUNCTION_ON}.
+ */
+ public static void setNumericShortcut(MenuItem item, char numericChar, int numericModifiers) {
+ if (item instanceof SupportMenuItem) {
+ ((SupportMenuItem) item).setNumericShortcut(numericChar, numericModifiers);
+ } else {
+ IMPL.setNumericShortcut(item, numericChar, numericModifiers);
+ }
+ }
+
+ /**
+ * Return the modifiers for this menu item's numeric (12-key) shortcut.
+ * The modifier is a combination of {@link KeyEvent#META_META_ON},
+ * {@link KeyEvent#META_CTRL_ON}, {@link KeyEvent#META_ALT_ON},
+ * {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_SYM_ON},
+ * {@link KeyEvent#META_FUNCTION_ON}.
+ * For example, {@link KeyEvent#META_FUNCTION_ON}|{@link KeyEvent#META_CTRL_ON}
+ *
+ * @return Modifier associated with the numeric shortcut.
+ */
+ public int getNumericModifiers(MenuItem item) {
+ if (item instanceof SupportMenuItem) {
+ return ((SupportMenuItem) item).getNumericModifiers();
+ }
+ return IMPL.getNumericModifiers(item);
+ }
+
+ /**
+ * Change the alphabetic shortcut associated with this item. The shortcut
+ * will be triggered when the key that generates the given character is
+ * pressed along with the modifier keys. Case is not significant and shortcut
+ * characters will be displayed in lower case. Note that menu items with
+ * the characters '\b' or '\n' as shortcuts will get triggered by the
+ * Delete key or Carriage Return key, respectively.
+ * <p>
+ * See {@link Menu} for the menu types that support shortcuts.
+ *
+ * @param alphaChar The alphabetic shortcut key. This is the shortcut when
+ * using a keyboard with alphabetic keys.
+ * @param alphaModifiers The modifier associated with the shortcut. It should
+ * be a combination of {@link KeyEvent#META_META_ON}, {@link KeyEvent#META_CTRL_ON},
+ * {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_SHIFT_ON},
+ * {@link KeyEvent#META_SYM_ON}, {@link KeyEvent#META_FUNCTION_ON}.
+ */
+ public static void setAlphabeticShortcut(MenuItem item, char alphaChar, int alphaModifiers) {
+ if (item instanceof SupportMenuItem) {
+ ((SupportMenuItem) item).setAlphabeticShortcut(alphaChar, alphaModifiers);
+ } else {
+ IMPL.setAlphabeticShortcut(item, alphaChar, alphaModifiers);
+ }
+ }
+
+ /**
+ * Return the modifier for this menu item's alphabetic shortcut.
+ * The modifier is a combination of {@link KeyEvent#META_META_ON},
+ * {@link KeyEvent#META_CTRL_ON}, {@link KeyEvent#META_ALT_ON},
+ * {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_SYM_ON},
+ * {@link KeyEvent#META_FUNCTION_ON}.
+ * For example, {@link KeyEvent#META_FUNCTION_ON}|{@link KeyEvent#META_CTRL_ON}
+ *
+ * @return Modifier associated with the keyboard shortcut.
+ */
+ public int getAlphabeticModifiers(MenuItem item) {
+ if (item instanceof SupportMenuItem) {
+ return ((SupportMenuItem) item).getAlphabeticModifiers();
+ }
+ return IMPL.getAlphabeticModifiers(item);
+ }
+
private MenuItemCompat() {}
}
diff --git a/compat/java/android/support/v4/view/ViewCompat.java b/compat/java/android/support/v4/view/ViewCompat.java
index 91311be..54c2730 100644
--- a/compat/java/android/support/v4/view/ViewCompat.java
+++ b/compat/java/android/support/v4/view/ViewCompat.java
@@ -922,7 +922,6 @@
}
public void setTooltipText(View view, CharSequence tooltipText) {
- ViewCompatICS.setTooltipText(view, tooltipText);
}
}
@@ -3321,12 +3320,9 @@
/**
* Sets the tooltip for the view.
- * <p>
- * Compatibility:
- * <ul>
- * <li>API < 26: Sets or clears (when tooltip is null) the view's OnLongClickListener and
- * OnHoverListener. Creates a Toast on long click or mouse hover.
- * </ul>
+ *
+ * <p>Prior to API 26 this does nothing. Use TooltipCompat class from v7 appcompat library
+ * for a compatible tooltip implementation.</p>
*
* @param tooltipText the tooltip text
*/
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java b/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
index 632eae9..6bd1031 100644
--- a/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
+++ b/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
@@ -1439,6 +1439,7 @@
return new AccessibilityNodeInfo.AccessibilityAction(actionId, label);
}
+ @SuppressWarnings("unchecked")
@Override
public List<Object> getActionList(AccessibilityNodeInfo info) {
Object result = info.getActionList();
diff --git a/compat/java/android/support/v4/widget/PopupWindowCompat.java b/compat/java/android/support/v4/widget/PopupWindowCompat.java
index 698e718..5018e04 100644
--- a/compat/java/android/support/v4/widget/PopupWindowCompat.java
+++ b/compat/java/android/support/v4/widget/PopupWindowCompat.java
@@ -16,43 +16,29 @@
package android.support.v4.widget;
-import android.support.annotation.RequiresApi;
import android.os.Build;
+import android.support.annotation.RequiresApi;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.ViewCompat;
+import android.util.Log;
import android.view.Gravity;
import android.view.View;
-import android.view.WindowManager;
import android.widget.PopupWindow;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
- * Helper for accessing features in PopupWindow introduced after API level 4
- * in a backwards compatible fashion.
+ * Helper for accessing features in PopupWindow in a backwards compatible fashion.
*/
public final class PopupWindowCompat {
- /**
- * Interface for the full API.
- */
- interface PopupWindowImpl {
- void showAsDropDown(PopupWindow popup, View anchor, int xoff, int yoff, int gravity);
- void setOverlapAnchor(PopupWindow popupWindow, boolean overlapAnchor);
- boolean getOverlapAnchor(PopupWindow popupWindow);
- void setWindowLayoutType(PopupWindow popupWindow, int layoutType);
- int getWindowLayoutType(PopupWindow popupWindow);
- }
- /**
- * Interface implementation that doesn't use anything above v4 APIs.
- */
- static class BasePopupWindowImpl implements PopupWindowImpl {
+ static class PopupWindowCompatBaseImpl {
private static Method sSetWindowLayoutTypeMethod;
private static boolean sSetWindowLayoutTypeMethodAttempted;
private static Method sGetWindowLayoutTypeMethod;
private static boolean sGetWindowLayoutTypeMethodAttempted;
- @Override
public void showAsDropDown(PopupWindow popup, View anchor, int xoff, int yoff,
int gravity) {
final int hgrav = GravityCompat.getAbsoluteGravity(gravity,
@@ -65,17 +51,14 @@
popup.showAsDropDown(anchor, xoff, yoff);
}
- @Override
public void setOverlapAnchor(PopupWindow popupWindow, boolean overlapAnchor) {
// noop
}
- @Override
public boolean getOverlapAnchor(PopupWindow popupWindow) {
return false;
}
- @Override
public void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
if (!sSetWindowLayoutTypeMethodAttempted) {
try {
@@ -97,7 +80,6 @@
}
}
- @Override
public int getWindowLayoutType(PopupWindow popupWindow) {
if (!sGetWindowLayoutTypeMethodAttempted) {
try {
@@ -125,63 +107,89 @@
* Interface implementation for devices with at least KitKat APIs.
*/
@RequiresApi(19)
- static class KitKatPopupWindowImpl extends BasePopupWindowImpl {
+ static class PopupWindowCompatApi19Impl extends PopupWindowCompatBaseImpl {
@Override
public void showAsDropDown(PopupWindow popup, View anchor, int xoff, int yoff,
int gravity) {
- PopupWindowCompatKitKat.showAsDropDown(popup, anchor, xoff, yoff, gravity);
+ popup.showAsDropDown(anchor, xoff, yoff, gravity);
}
}
@RequiresApi(21)
- static class Api21PopupWindowImpl extends KitKatPopupWindowImpl {
+ static class PopupWindowCompatApi21Impl extends PopupWindowCompatApi19Impl {
+ private static final String TAG = "PopupWindowCompatApi21";
+
+ private static Field sOverlapAnchorField;
+
+ static {
+ try {
+ sOverlapAnchorField = PopupWindow.class.getDeclaredField("mOverlapAnchor");
+ sOverlapAnchorField.setAccessible(true);
+ } catch (NoSuchFieldException e) {
+ Log.i(TAG, "Could not fetch mOverlapAnchor field from PopupWindow", e);
+ }
+ }
+
@Override
public void setOverlapAnchor(PopupWindow popupWindow, boolean overlapAnchor) {
- PopupWindowCompatApi21.setOverlapAnchor(popupWindow, overlapAnchor);
+ if (sOverlapAnchorField != null) {
+ try {
+ sOverlapAnchorField.set(popupWindow, overlapAnchor);
+ } catch (IllegalAccessException e) {
+ Log.i(TAG, "Could not set overlap anchor field in PopupWindow", e);
+ }
+ }
}
@Override
public boolean getOverlapAnchor(PopupWindow popupWindow) {
- return PopupWindowCompatApi21.getOverlapAnchor(popupWindow);
+ if (sOverlapAnchorField != null) {
+ try {
+ return (Boolean) sOverlapAnchorField.get(popupWindow);
+ } catch (IllegalAccessException e) {
+ Log.i(TAG, "Could not get overlap anchor field in PopupWindow", e);
+ }
+ }
+ return false;
}
}
@RequiresApi(23)
- static class Api23PopupWindowImpl extends Api21PopupWindowImpl {
+ static class PopupWindowCompatApi23Impl extends PopupWindowCompatApi21Impl {
@Override
public void setOverlapAnchor(PopupWindow popupWindow, boolean overlapAnchor) {
- PopupWindowCompatApi23.setOverlapAnchor(popupWindow, overlapAnchor);
+ popupWindow.setOverlapAnchor(overlapAnchor);
}
@Override
public boolean getOverlapAnchor(PopupWindow popupWindow) {
- return PopupWindowCompatApi23.getOverlapAnchor(popupWindow);
+ return popupWindow.getOverlapAnchor();
}
@Override
public void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
- PopupWindowCompatApi23.setWindowLayoutType(popupWindow, layoutType);
+ popupWindow.setWindowLayoutType(layoutType);
}
@Override
public int getWindowLayoutType(PopupWindow popupWindow) {
- return PopupWindowCompatApi23.getWindowLayoutType(popupWindow);
+ return popupWindow.getWindowLayoutType();
}
}
/**
* Select the correct implementation to use for the current platform.
*/
- static final PopupWindowImpl IMPL;
+ static final PopupWindowCompatBaseImpl IMPL;
static {
if (Build.VERSION.SDK_INT >= 23) {
- IMPL = new Api23PopupWindowImpl();
+ IMPL = new PopupWindowCompatApi23Impl();
} else if (Build.VERSION.SDK_INT >= 21) {
- IMPL = new Api21PopupWindowImpl();
+ IMPL = new PopupWindowCompatApi21Impl();
} else if (Build.VERSION.SDK_INT >= 19) {
- IMPL = new KitKatPopupWindowImpl();
+ IMPL = new PopupWindowCompatApi19Impl();
} else {
- IMPL = new BasePopupWindowImpl();
+ IMPL = new PopupWindowCompatBaseImpl();
}
}
@@ -232,12 +240,12 @@
/**
* Set the layout type for this window. This value will be passed through to
- * {@link WindowManager.LayoutParams#type} therefore the value should match any value
- * {@link WindowManager.LayoutParams#type} accepts.
+ * {@link android.view.WindowManager.LayoutParams#type} therefore the value should match any
+ * value {@link android.view.WindowManager.LayoutParams#type} accepts.
*
* @param layoutType Layout type for this window.
*
- * @see WindowManager.LayoutParams#type
+ * @see android.view.WindowManager.LayoutParams#type
*/
public static void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
IMPL.setWindowLayoutType(popupWindow, layoutType);
diff --git a/compat/jellybean/android/support/v4/app/NotificationCompatJellybean.java b/compat/jellybean/android/support/v4/app/NotificationCompatJellybean.java
index feee689..d302175 100644
--- a/compat/jellybean/android/support/v4/app/NotificationCompatJellybean.java
+++ b/compat/jellybean/android/support/v4/app/NotificationCompatJellybean.java
@@ -16,6 +16,7 @@
package android.support.v4.app;
+import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
@@ -347,13 +348,14 @@
}
}
+ @SuppressLint("NewApi") // Intentionally looking up Notification.Action using reflection.
private static boolean ensureActionReflectionReadyLocked() {
if (sActionsAccessFailed) {
return false;
}
try {
if (sActionsField == null) {
- sActionClass = Class.forName("android.app.Notification$Action");
+ sActionClass = Class.forName(Notification.Action.class.getName());
sActionIconField = sActionClass.getDeclaredField("icon");
sActionTitleField = sActionClass.getDeclaredField("title");
sActionIntentField = sActionClass.getDeclaredField("actionIntent");
diff --git a/compat/kitkat/android/support/v4/widget/PopupWindowCompatKitKat.java b/compat/kitkat/android/support/v4/widget/PopupWindowCompatKitKat.java
deleted file mode 100644
index 887301f..0000000
--- a/compat/kitkat/android/support/v4/widget/PopupWindowCompatKitKat.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.widget;
-
-import android.support.annotation.RequiresApi;
-import android.view.View;
-import android.widget.PopupWindow;
-
-/**
- * Implementation of PopupWindow compatibility that can call KitKat APIs.
- */
-
-@RequiresApi(19)
-class PopupWindowCompatKitKat {
- public static void showAsDropDown(PopupWindow popup, View anchor, int xoff, int yoff,
- int gravity) {
- popup.showAsDropDown(anchor, xoff, yoff, gravity);
- }
-}
diff --git a/compat/tests/java/android/support/v4/testutils/TestUtils.java b/compat/tests/java/android/support/v4/testutils/TestUtils.java
index e44448d..70be082 100644
--- a/compat/tests/java/android/support/v4/testutils/TestUtils.java
+++ b/compat/tests/java/android/support/v4/testutils/TestUtils.java
@@ -17,9 +17,6 @@
package android.support.v4.testutils;
-import java.lang.IllegalArgumentException;
-import java.lang.RuntimeException;
-
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
diff --git a/compat/tests/java/android/support/v4/util/ArrayMapCompatTest.java b/compat/tests/java/android/support/v4/util/ArrayMapCompatTest.java
new file mode 100644
index 0000000..c00d264
--- /dev/null
+++ b/compat/tests/java/android/support/v4/util/ArrayMapCompatTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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.v4.util;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ArrayMapCompatTest {
+
+ @Test
+ public void testCanNotIteratePastEnd_entrySetIterator() {
+ Map<String, String> map = new ArrayMap<>();
+ map.put("key 1", "value 1");
+ map.put("key 2", "value 2");
+ Set<Map.Entry<String, String>> expectedEntriesToIterate = new HashSet<>(Arrays.asList(
+ entryOf("key 1", "value 1"),
+ entryOf("key 2", "value 2")
+ ));
+ Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
+
+ // Assert iteration over the expected two entries in any order
+ assertTrue(iterator.hasNext());
+ Map.Entry<String, String> firstEntry = copyOf(iterator.next());
+ assertTrue(expectedEntriesToIterate.remove(firstEntry));
+
+ assertTrue(iterator.hasNext());
+ Map.Entry<String, String> secondEntry = copyOf(iterator.next());
+ assertTrue(expectedEntriesToIterate.remove(secondEntry));
+
+ assertFalse(iterator.hasNext());
+
+ try {
+ iterator.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+ }
+
+ private static <K, V> Map.Entry<K, V> entryOf(K key, V value) {
+ return new AbstractMap.SimpleEntry<>(key, value);
+ }
+
+ private static <K, V> Map.Entry<K, V> copyOf(Map.Entry<K, V> entry) {
+ return entryOf(entry.getKey(), entry.getValue());
+ }
+
+ @Test
+ public void testCanNotIteratePastEnd_keySetIterator() {
+ Map<String, String> map = new ArrayMap<>();
+ map.put("key 1", "value 1");
+ map.put("key 2", "value 2");
+ Set<String> expectedKeysToIterate = new HashSet<>(Arrays.asList("key 1", "key 2"));
+ Iterator<String> iterator = map.keySet().iterator();
+
+ // Assert iteration over the expected two keys in any order
+ assertTrue(iterator.hasNext());
+ String firstKey = iterator.next();
+ assertTrue(expectedKeysToIterate.remove(firstKey));
+
+ assertTrue(iterator.hasNext());
+ String secondKey = iterator.next();
+ assertTrue(expectedKeysToIterate.remove(secondKey));
+
+ assertFalse(iterator.hasNext());
+
+ try {
+ iterator.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+ }
+
+ @Test
+ public void testCanNotIteratePastEnd_valuesIterator() {
+ Map<String, String> map = new ArrayMap<>();
+ map.put("key 1", "value 1");
+ map.put("key 2", "value 2");
+ Set<String> expectedValuesToIterate = new HashSet<>(Arrays.asList("value 1", "value 2"));
+ Iterator<String> iterator = map.values().iterator();
+
+ // Assert iteration over the expected two values in any order
+ assertTrue(iterator.hasNext());
+ String firstValue = iterator.next();
+ assertTrue(expectedValuesToIterate.remove(firstValue));
+
+ assertTrue(iterator.hasNext());
+ String secondValue = iterator.next();
+ assertTrue(expectedValuesToIterate.remove(secondValue));
+
+ assertFalse(iterator.hasNext());
+
+ try {
+ iterator.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+ }
+}
diff --git a/compat/tests/java/android/support/v4/util/ArraySetCompatTest.java b/compat/tests/java/android/support/v4/util/ArraySetCompatTest.java
new file mode 100644
index 0000000..10a0b1b
--- /dev/null
+++ b/compat/tests/java/android/support/v4/util/ArraySetCompatTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.v4.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ArraySetCompatTest {
+ @Test
+ public void testCanNotIteratePastEnd() {
+ ArraySet<String> set = new ArraySet<>();
+ set.add("value");
+ Iterator<String> iterator = set.iterator();
+
+ assertTrue(iterator.hasNext());
+ assertEquals("value", iterator.next());
+ assertFalse(iterator.hasNext());
+
+ try {
+ iterator.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+ }
+}
diff --git a/core-ui/build.gradle b/core-ui/build.gradle
index c40022d..03de595 100644
--- a/core-ui/build.gradle
+++ b/core-ui/build.gradle
@@ -14,6 +14,7 @@
androidTestCompile libs.mockito_core
androidTestCompile libs.dexmaker
androidTestCompile libs.dexmaker_mockito
+ androidTestCompile project(':support-testutils')
}
android {
diff --git a/core-ui/java/android/support/v4/widget/ExploreByTouchHelper.java b/core-ui/java/android/support/v4/widget/ExploreByTouchHelper.java
index 840effb..7ca0054 100644
--- a/core-ui/java/android/support/v4/widget/ExploreByTouchHelper.java
+++ b/core-ui/java/android/support/v4/widget/ExploreByTouchHelper.java
@@ -48,8 +48,7 @@
* support in custom {@link View}s that represent a collection of View-like
* logical items. It extends {@link AccessibilityNodeProviderCompat} and
* simplifies many aspects of providing information to accessibility services
- * and managing accessibility focus. This class does not currently support
- * hierarchies of logical items.
+ * and managing accessibility focus.
* <p>
* Clients should override abstract methods on this class and attach it to the
* host view using {@link ViewCompat#setAccessibilityDelegate}:
diff --git a/core-ui/tests/java/android/support/v4/testutils/PollingCheck.java b/core-ui/tests/java/android/support/v4/testutils/PollingCheck.java
deleted file mode 100644
index b4271f4..0000000
--- a/core-ui/tests/java/android/support/v4/testutils/PollingCheck.java
+++ /dev/null
@@ -1,94 +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.v4.testutils;
-
-import java.util.concurrent.Callable;
-
-import junit.framework.Assert;
-
-public abstract class PollingCheck {
- private static final long TIME_SLICE = 50;
- private long mTimeout = 3000;
-
- public static interface PollingCheckCondition {
- boolean canProceed();
- }
-
- public PollingCheck() {
- }
-
- public PollingCheck(long timeout) {
- mTimeout = timeout;
- }
-
- protected abstract boolean check();
-
- public void run() {
- if (check()) {
- return;
- }
-
- long timeout = mTimeout;
- while (timeout > 0) {
- try {
- Thread.sleep(TIME_SLICE);
- } catch (InterruptedException e) {
- Assert.fail("unexpected InterruptedException");
- }
-
- if (check()) {
- return;
- }
-
- timeout -= TIME_SLICE;
- }
-
- Assert.fail("unexpected timeout");
- }
-
- public static void check(CharSequence message, long timeout, Callable<Boolean> condition)
- throws Exception {
- while (timeout > 0) {
- if (condition.call()) {
- return;
- }
-
- Thread.sleep(TIME_SLICE);
- timeout -= TIME_SLICE;
- }
-
- Assert.fail(message.toString());
- }
-
- public static void waitFor(final PollingCheckCondition condition) {
- new PollingCheck() {
- @Override
- protected boolean check() {
- return condition.canProceed();
- }
- }.run();
- }
-
- public static void waitFor(long timeout, final PollingCheckCondition condition) {
- new PollingCheck(timeout) {
- @Override
- protected boolean check() {
- return condition.canProceed();
- }
- }.run();
- }
-}
\ No newline at end of file
diff --git a/core-ui/tests/java/android/support/v4/testutils/TestUtilsMatchers.java b/core-ui/tests/java/android/support/v4/testutils/TestUtilsMatchers.java
index c6f07e5..3884e8f 100644
--- a/core-ui/tests/java/android/support/v4/testutils/TestUtilsMatchers.java
+++ b/core-ui/tests/java/android/support/v4/testutils/TestUtilsMatchers.java
@@ -16,14 +16,9 @@
package android.support.v4.testutils;
-import java.lang.String;
-import java.util.List;
-
-import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.test.espresso.matcher.BoundedMatcher;
-import android.support.v4.testutils.TestUtils;
import android.support.v4.view.ViewCompat;
import android.view.View;
import android.view.ViewGroup;
@@ -35,6 +30,8 @@
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
+import java.util.List;
+
public class TestUtilsMatchers {
/**
* Returns a matcher that matches views which have specific background color.
diff --git a/core-ui/tests/java/android/support/v4/view/BaseViewPagerTest.java b/core-ui/tests/java/android/support/v4/view/BaseViewPagerTest.java
index dfa7a22..a83a976 100644
--- a/core-ui/tests/java/android/support/v4/view/BaseViewPagerTest.java
+++ b/core-ui/tests/java/android/support/v4/view/BaseViewPagerTest.java
@@ -97,7 +97,7 @@
protected ArrayList<Pair<String, Q>> mEntries = new ArrayList<>();
public void add(String title, Q content) {
- mEntries.add(new Pair(title, content));
+ mEntries.add(new Pair<>(title, content));
}
@Override
diff --git a/core-ui/tests/java/android/support/v4/widget/SwipeRefreshLayoutTest.java b/core-ui/tests/java/android/support/v4/widget/SwipeRefreshLayoutTest.java
index cdbc2cb..04a2835 100644
--- a/core-ui/tests/java/android/support/v4/widget/SwipeRefreshLayoutTest.java
+++ b/core-ui/tests/java/android/support/v4/widget/SwipeRefreshLayoutTest.java
@@ -37,8 +37,8 @@
import android.support.test.filters.LargeTest;
import android.support.test.filters.MediumTest;
import android.support.test.filters.SmallTest;
+import android.support.testutils.PollingCheck;
import android.support.v4.BaseInstrumentationTestCase;
-import android.support.v4.testutils.PollingCheck;
import android.view.View;
import org.junit.Before;
diff --git a/core-utils/api21/android/support/v4/provider/DocumentsContractApi21.java b/core-utils/api21/android/support/v4/provider/DocumentsContractApi21.java
index cfaea83..90e0038 100644
--- a/core-utils/api21/android/support/v4/provider/DocumentsContractApi21.java
+++ b/core-utils/api21/android/support/v4/provider/DocumentsContractApi21.java
@@ -32,8 +32,12 @@
public static Uri createFile(Context context, Uri self, String mimeType,
String displayName) {
- return DocumentsContract.createDocument(context.getContentResolver(), self, mimeType,
- displayName);
+ try {
+ return DocumentsContract.createDocument(context.getContentResolver(), self, mimeType,
+ displayName);
+ } catch (Exception e) {
+ return null;
+ }
}
public static Uri createDirectory(Context context, Uri self, String displayName) {
@@ -71,7 +75,12 @@
}
public static Uri renameTo(Context context, Uri self, String displayName) {
- return DocumentsContract.renameDocument(context.getContentResolver(), self, displayName);
+ try {
+ return DocumentsContract.renameDocument(context.getContentResolver(), self,
+ displayName);
+ } catch (Exception e) {
+ return null;
+ }
}
private static void closeQuietly(AutoCloseable closeable) {
diff --git a/core-utils/java/android/support/v4/app/AppLaunchChecker.java b/core-utils/java/android/support/v4/app/AppLaunchChecker.java
index 86219d4..f8beb91 100644
--- a/core-utils/java/android/support/v4/app/AppLaunchChecker.java
+++ b/core-utils/java/android/support/v4/app/AppLaunchChecker.java
@@ -19,7 +19,6 @@
import android.app.Activity;
import android.content.Context;
-import android.content.ContextWrapper;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
diff --git a/core-utils/java/android/support/v4/content/AsyncTaskLoader.java b/core-utils/java/android/support/v4/content/AsyncTaskLoader.java
index c31a8cd..faa13ad 100644
--- a/core-utils/java/android/support/v4/content/AsyncTaskLoader.java
+++ b/core-utils/java/android/support/v4/content/AsyncTaskLoader.java
@@ -157,6 +157,9 @@
protected boolean onCancelLoad() {
if (DEBUG) Log.v(TAG, "onCancelLoad: mTask=" + mTask);
if (mTask != null) {
+ if (!mStarted) {
+ mContentChanged = true;
+ }
if (mCancellingTask != null) {
// There was a pending task already waiting for a previous
// one being canceled; just drop it.
diff --git a/core-utils/java/android/support/v4/content/FileProvider.java b/core-utils/java/android/support/v4/content/FileProvider.java
index 9e82d63..c49fc12 100644
--- a/core-utils/java/android/support/v4/content/FileProvider.java
+++ b/core-utils/java/android/support/v4/content/FileProvider.java
@@ -32,6 +32,7 @@
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.OpenableColumns;
+import android.support.annotation.GuardedBy;
import android.text.TextUtils;
import android.webkit.MimeTypeMap;
@@ -339,7 +340,7 @@
private static final File DEVICE_ROOT = new File("/");
- // @GuardedBy("sCache")
+ @GuardedBy("sCache")
private static HashMap<String, PathStrategy> sCache = new HashMap<String, PathStrategy>();
private PathStrategy mStrategy;
diff --git a/core-utils/java/android/support/v4/content/MimeTypeFilter.java b/core-utils/java/android/support/v4/content/MimeTypeFilter.java
index 6d26dcb..8734c4d 100644
--- a/core-utils/java/android/support/v4/content/MimeTypeFilter.java
+++ b/core-utils/java/android/support/v4/content/MimeTypeFilter.java
@@ -27,14 +27,16 @@
* <p>Wildcards are allowed only instead of the entire type or subtype with a tree prefix.
* Eg. image\/*, *\/* is a valid filter and will match image/jpeg, but image/j* is invalid and
* it will not match image/jpeg. Suffixes and parameters are not supported, and they are treated
- * as part of the subtype during matching.
+ * as part of the subtype during matching. Neither type nor subtype can be empty.
*
* <p><em>Note: MIME type matching in the Android framework is case-sensitive, unlike the formal
* RFC definitions. As a result, you should always write these elements with lower case letters,
* or use {@link android.content.Intent#normalizeMimeType} to ensure that they are converted to
* lower case.</em>
*
- * <p>Null MIME type doesn't match anything.
+ * <p>MIME types can be null or ill-formatted. In such case they won't match anything.
+ *
+ * <p>MIME type filters must be correctly formatted, or an exception will be thrown.
*/
public final class MimeTypeFilter {
@@ -42,8 +44,16 @@
}
private static boolean mimeTypeAgainstFilter(
- @NonNull String[] mimeTypeParts, @NonNull String[]filterParts) {
- if (mimeTypeParts.length != 2 || filterParts.length != 2) {
+ @NonNull String[] mimeTypeParts, @NonNull String[] filterParts) {
+ if (filterParts.length != 2) {
+ throw new IllegalArgumentException(
+ "Ill-formatted MIME type filter. Must be type/subtype.");
+ }
+ if (filterParts[0].isEmpty() || filterParts[1].isEmpty()) {
+ throw new IllegalArgumentException(
+ "Ill-formatted MIME type filter. Type or subtype empty.");
+ }
+ if (mimeTypeParts.length != 2) {
return false;
}
if (!"*".equals(filterParts[0])
@@ -59,7 +69,7 @@
}
/**
- * See the class description for the matching behavior details.
+ * Matches one nullable MIME type against one MIME type filter.
* @return True if the {@code mimeType} matches the {@code filter}.
*/
public static boolean matches(@Nullable String mimeType, @NonNull String filter) {
@@ -74,7 +84,7 @@
}
/**
- * See the class description for the matching behavior details.
+ * Matches one nullable MIME type against an array of MIME type filters.
* @return The first matching filter, or null if nothing matches.
*/
public static String matches(
@@ -95,7 +105,7 @@
}
/**
- * See the class description for the matching behavior details.
+ * Matches multiple MIME types against an array of MIME type filters.
* @return The first matching MIME type, or null if nothing matches.
*/
public static String matches(
@@ -116,8 +126,8 @@
}
/**
- * See the class description for the matching behavior details.
- * @return The list of matching MIME types, or empty list if nothing matches.
+ * Matches multiple MIME types against an array of MIME type filters.
+ * @return The list of matching MIME types, or empty array if nothing matches.
*/
public static String[] matchesMany(
@Nullable String[] mimeTypes, @NonNull String filter) {
diff --git a/core-utils/java/android/support/v4/provider/SingleDocumentFile.java b/core-utils/java/android/support/v4/provider/SingleDocumentFile.java
index 606c351..77c4e49 100644
--- a/core-utils/java/android/support/v4/provider/SingleDocumentFile.java
+++ b/core-utils/java/android/support/v4/provider/SingleDocumentFile.java
@@ -19,7 +19,6 @@
import android.content.Context;
import android.net.Uri;
import android.support.annotation.RequiresApi;
-import android.support.v4.provider.DocumentsContractApi19;
@RequiresApi(19)
class SingleDocumentFile extends DocumentFile {
diff --git a/core-utils/kitkat/android/support/v4/provider/DocumentsContractApi19.java b/core-utils/kitkat/android/support/v4/provider/DocumentsContractApi19.java
index 41ba0f0..a429d8d 100644
--- a/core-utils/kitkat/android/support/v4/provider/DocumentsContractApi19.java
+++ b/core-utils/kitkat/android/support/v4/provider/DocumentsContractApi19.java
@@ -137,7 +137,11 @@
}
public static boolean delete(Context context, Uri self) {
- return DocumentsContract.deleteDocument(context.getContentResolver(), self);
+ try {
+ return DocumentsContract.deleteDocument(context.getContentResolver(), self);
+ } catch (Exception e) {
+ return false;
+ }
}
public static boolean exists(Context context, Uri self) {
diff --git a/core-utils/tests/java/android/support/v4/content/MimeTypeFilterTest.java b/core-utils/tests/java/android/support/v4/content/MimeTypeFilterTest.java
index 4fec6dd..21748ff 100644
--- a/core-utils/tests/java/android/support/v4/content/MimeTypeFilterTest.java
+++ b/core-utils/tests/java/android/support/v4/content/MimeTypeFilterTest.java
@@ -25,6 +25,8 @@
import android.support.test.runner.AndroidJUnit4;
import android.test.MoreAsserts;
+import junit.framework.Assert;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -53,14 +55,11 @@
assertFalse(MimeTypeFilter.matches((String) null, "image/"));
assertFalse(MimeTypeFilter.matches((String) null, "image/jpeg"));
- // Invalid MIME types, filters or swapped arguments.
- assertFalse(MimeTypeFilter.matches((String) null, ""));
- assertFalse(MimeTypeFilter.matches("", ""));
- assertFalse(MimeTypeFilter.matches("", "*/"));
+ // Null and invalid MIME types.
+ assertFalse(MimeTypeFilter.matches((String) null, "*/*"));
assertFalse(MimeTypeFilter.matches("", "*/*"));
assertFalse(MimeTypeFilter.matches("image/", "*/*"));
- assertFalse(MimeTypeFilter.matches("image/", "image/"));
- assertFalse(MimeTypeFilter.matches("*/*", "image/jpeg"));
+ assertFalse(MimeTypeFilter.matches("*/", "*/*"));
}
@Test
@@ -83,7 +82,6 @@
"image/jpeg", new String[] {"*/png", "*/jpeg"}));
assertNull(MimeTypeFilter.matches("image/jpeg", new String[] {}));
- assertNull(MimeTypeFilter.matches("image/jpeg", new String[] {}));
assertNull(MimeTypeFilter.matches("image/jpeg", new String[] {"image/png", "video/jpeg"}));
assertNull(MimeTypeFilter.matches("image/jpeg", new String[] {"video/jpeg", "image/png"}));
@@ -92,14 +90,11 @@
assertNull(MimeTypeFilter.matches(null, new String[] {"image/"}));
assertNull(MimeTypeFilter.matches(null, new String[] {"image/jpeg"}));
- // Invalid MIME types, filters or swapped arguments.
- assertNull(MimeTypeFilter.matches(null, new String[] {""}));
- assertNull(MimeTypeFilter.matches("", new String[] {""}));
- assertNull(MimeTypeFilter.matches("", new String[] {"*/"}));
- assertNull(MimeTypeFilter.matches("", new String[] {"*/*"}));
- assertNull(MimeTypeFilter.matches("image/", new String[] {"*/*"}));
- assertNull(MimeTypeFilter.matches("image/", new String[] {"image/"}));
- assertNull(MimeTypeFilter.matches("*/*", new String[] {"image/jpeg"}));
+ // Null and invalid MIME types.
+ assertNull(MimeTypeFilter.matches((String) null, new String[] { "*/*" }));
+ assertNull(MimeTypeFilter.matches("", new String[] { "*/*" }));
+ assertNull(MimeTypeFilter.matches("image/", new String[] { "*/*" }));
+ assertNull(MimeTypeFilter.matches("*/", new String[] { "*/*" }));
}
@Test
@@ -112,10 +107,151 @@
MimeTypeFilter.matchesMany(new String[] {"image/jpeg", "image/png"}, "*/JpEg"));
MoreAsserts.assertEquals(new String[] {},
- MimeTypeFilter.matchesMany(new String[] {"image/jpeg", "image/png"}, "video/ogv"));
- MoreAsserts.assertEquals(new String[] {},
- MimeTypeFilter.matchesMany(new String[] {"image/jpeg", "image/png"}, ""));
+ MimeTypeFilter.matchesMany(new String[] {"*/", "image/"}, "*/*"));
MoreAsserts.assertEquals(new String[] {},
MimeTypeFilter.matchesMany(new String[] {}, "*/*"));
}
+
+ @Test
+ public void illegalFilters() throws Exception {
+ try {
+ MimeTypeFilter.matches("image/jpeg", "");
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matches("image/jpeg", "*");
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matches("image/jpeg", "*/");
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matches("image/jpeg", "/*");
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matches("image/jpeg", "*/*/*");
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matches(new String[] { "image/jpeg" }, "");
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matches(new String[] { "image/jpeg" }, "*");
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matches(new String[] { "image/jpeg" }, "*/");
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matches(new String[] { "image/jpeg" }, "/*");
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matches(new String[] { "image/jpeg" }, "*/*/*");
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matches("image/jpeg", new String[] { "" });
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matches("image/jpeg", new String[] { "*" });
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matches("image/jpeg", new String[] { "*/" });
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matches("image/jpeg", new String[] { "/*" });
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matches("image/jpeg", new String[] { "*/*/*" });
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matchesMany(new String[] { "image/jpeg" }, "");
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matchesMany(new String[] { "image/jpeg" }, "*");
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matchesMany(new String[] { "image/jpeg" }, "*/");
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matchesMany(new String[] { "image/jpeg" }, "/*");
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+
+ try {
+ MimeTypeFilter.matchesMany(new String[] { "image/jpeg" }, "*/*/*");
+ Assert.fail("Illegal filter, should throw.");
+ } catch (IllegalArgumentException e) {
+ // Expected.
+ }
+ }
}
diff --git a/core-utils/tests/java/android/support/v4/provider/GrantActivity.java b/core-utils/tests/java/android/support/v4/provider/GrantActivity.java
index c4dbb27..a354201 100644
--- a/core-utils/tests/java/android/support/v4/provider/GrantActivity.java
+++ b/core-utils/tests/java/android/support/v4/provider/GrantActivity.java
@@ -20,7 +20,6 @@
import android.content.ContentResolver;
import android.content.Intent;
import android.os.Bundle;
-import android.support.v4.provider.DocumentFileTest;
/**
* Stub activity used to request a permission grant for
diff --git a/customtabs/build.gradle b/customtabs/build.gradle
index 740b125..6bc7dd5 100644
--- a/customtabs/build.gradle
+++ b/customtabs/build.gradle
@@ -12,6 +12,8 @@
androidTestCompile (libs.espresso_core) {
exclude module: 'support-annotations'
}
+
+ androidTestCompile project(':support-testutils')
}
android {
diff --git a/customtabs/tests/src/android/support/customtabs/PostMessageServiceConnectionTest.java b/customtabs/tests/src/android/support/customtabs/PostMessageServiceConnectionTest.java
index c0fadae..07d21a8 100644
--- a/customtabs/tests/src/android/support/customtabs/PostMessageServiceConnectionTest.java
+++ b/customtabs/tests/src/android/support/customtabs/PostMessageServiceConnectionTest.java
@@ -26,6 +26,7 @@
import android.support.test.rule.ActivityTestRule;
import android.support.test.rule.ServiceTestRule;
import android.support.test.runner.AndroidJUnit4;
+import android.support.testutils.PollingCheck;
import org.junit.Before;
import org.junit.Rule;
diff --git a/customtabs/tests/src/android/support/customtabs/PostMessageTest.java b/customtabs/tests/src/android/support/customtabs/PostMessageTest.java
index d20a06d..e832b23 100644
--- a/customtabs/tests/src/android/support/customtabs/PostMessageTest.java
+++ b/customtabs/tests/src/android/support/customtabs/PostMessageTest.java
@@ -29,6 +29,7 @@
import android.support.test.rule.ActivityTestRule;
import android.support.test.rule.ServiceTestRule;
import android.support.test.runner.AndroidJUnit4;
+import android.support.testutils.PollingCheck;
import org.junit.Before;
import org.junit.Rule;
diff --git a/design/base/android/support/design/widget/AnimationUtils.java b/design/base/android/support/design/widget/AnimationUtils.java
index 8ef1722..3613afd 100644
--- a/design/base/android/support/design/widget/AnimationUtils.java
+++ b/design/base/android/support/design/widget/AnimationUtils.java
@@ -19,7 +19,6 @@
import android.support.v4.view.animation.FastOutLinearInInterpolator;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.support.v4.view.animation.LinearOutSlowInInterpolator;
-import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
@@ -43,18 +42,4 @@
return startValue + Math.round(fraction * (endValue - startValue));
}
- static class AnimationListenerAdapter implements Animation.AnimationListener {
- @Override
- public void onAnimationStart(Animation animation) {
- }
-
- @Override
- public void onAnimationEnd(Animation animation) {
- }
-
- @Override
- public void onAnimationRepeat(Animation animation) {
- }
- }
-
}
diff --git a/design/src/android/support/design/internal/BottomNavigationItemView.java b/design/src/android/support/design/internal/BottomNavigationItemView.java
index f764ffa..72b80bf 100644
--- a/design/src/android/support/design/internal/BottomNavigationItemView.java
+++ b/design/src/android/support/design/internal/BottomNavigationItemView.java
@@ -31,6 +31,7 @@
import android.support.v4.view.ViewCompat;
import android.support.v7.view.menu.MenuItemImpl;
import android.support.v7.view.menu.MenuView;
+import android.support.v7.widget.TooltipCompat;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -100,7 +101,7 @@
setTitle(itemData.getTitle());
setId(itemData.getItemId());
setContentDescription(itemData.getContentDescription());
- ViewCompat.setTooltipText(this, itemData.getTooltipText());
+ TooltipCompat.setTooltipText(this, itemData.getTooltipText());
}
public void setItemPosition(int position) {
diff --git a/design/src/android/support/design/internal/BottomNavigationMenuView.java b/design/src/android/support/design/internal/BottomNavigationMenuView.java
index 18133be..bf33454 100644
--- a/design/src/android/support/design/internal/BottomNavigationMenuView.java
+++ b/design/src/android/support/design/internal/BottomNavigationMenuView.java
@@ -295,19 +295,25 @@
return;
}
int previousSelectedId = mSelectedItemId;
+
for (int i = 0; i < menuSize; i++) {
- mPresenter.setUpdateSuspended(true);
MenuItem item = mMenu.getItem(i);
if (item.isChecked()) {
mSelectedItemId = item.getItemId();
mSelectedItemPosition = i;
}
- mButtons[i].initialize((MenuItemImpl) item, 0);
- mPresenter.setUpdateSuspended(false);
}
if (previousSelectedId != mSelectedItemId) {
- TransitionManager.beginDelayedTransition(this);
+ // Note: this has to be called before BottomNavigationItemView#initialize().
+ TransitionManager.beginDelayedTransition(this, mSet);
}
+
+ for (int i = 0; i < menuSize; i++) {
+ mPresenter.setUpdateSuspended(true);
+ mButtons[i].initialize((MenuItemImpl) mMenu.getItem(i), 0);
+ mPresenter.setUpdateSuspended(false);
+ }
+
}
private BottomNavigationItemView getNewItem() {
diff --git a/design/src/android/support/design/internal/NavigationMenuItemView.java b/design/src/android/support/design/internal/NavigationMenuItemView.java
index 2a4367c..53ef24a 100644
--- a/design/src/android/support/design/internal/NavigationMenuItemView.java
+++ b/design/src/android/support/design/internal/NavigationMenuItemView.java
@@ -35,6 +35,7 @@
import android.support.v4.widget.TextViewCompat;
import android.support.v7.view.menu.MenuItemImpl;
import android.support.v7.view.menu.MenuView;
+import android.support.v7.widget.TooltipCompat;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.LayoutInflater;
@@ -117,7 +118,7 @@
setIcon(itemData.getIcon());
setActionView(itemData.getActionView());
setContentDescription(itemData.getContentDescription());
- ViewCompat.setTooltipText(this, itemData.getTooltipText());
+ TooltipCompat.setTooltipText(this, itemData.getTooltipText());
adjustAppearance();
}
diff --git a/design/src/android/support/design/widget/BottomSheetBehavior.java b/design/src/android/support/design/widget/BottomSheetBehavior.java
index 6d664b5..e85c38d 100644
--- a/design/src/android/support/design/widget/BottomSheetBehavior.java
+++ b/design/src/android/support/design/widget/BottomSheetBehavior.java
@@ -381,7 +381,8 @@
setStateInternal(STATE_EXPANDED);
return;
}
- if (target != mNestedScrollingChildRef.get() || !mNestedScrolled) {
+ if (mNestedScrollingChildRef == null || target != mNestedScrollingChildRef.get()
+ || !mNestedScrolled) {
return;
}
int top;
diff --git a/design/src/android/support/design/widget/CollapsingTextHelper.java b/design/src/android/support/design/widget/CollapsingTextHelper.java
index 8d88bbb..909a9a8 100644
--- a/design/src/android/support/design/widget/CollapsingTextHelper.java
+++ b/design/src/android/support/design/widget/CollapsingTextHelper.java
@@ -27,7 +27,6 @@
import android.graphics.Typeface;
import android.os.Build;
import android.support.annotation.ColorInt;
-import android.support.design.R;
import android.support.v4.text.TextDirectionHeuristicsCompat;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.ViewCompat;
diff --git a/design/src/android/support/design/widget/DirectedAcyclicGraph.java b/design/src/android/support/design/widget/DirectedAcyclicGraph.java
index 189daf4..85a32cd 100644
--- a/design/src/android/support/design/widget/DirectedAcyclicGraph.java
+++ b/design/src/android/support/design/widget/DirectedAcyclicGraph.java
@@ -97,7 +97,7 @@
* @return a list containing any outgoing edges, or null if there are none.
*/
@Nullable
- List getOutgoingEdges(@NonNull T node) {
+ List<T> getOutgoingEdges(@NonNull T node) {
ArrayList<T> result = null;
for (int i = 0, size = mGraph.size(); i < size; i++) {
ArrayList<T> edges = mGraph.valueAt(i);
diff --git a/design/src/android/support/design/widget/DrawableUtils.java b/design/src/android/support/design/widget/DrawableUtils.java
index 1e2e6cf..df1c04b 100644
--- a/design/src/android/support/design/widget/DrawableUtils.java
+++ b/design/src/android/support/design/widget/DrawableUtils.java
@@ -18,10 +18,8 @@
import android.graphics.drawable.Drawable;
import android.graphics.drawable.DrawableContainer;
-import android.os.Build;
import android.util.Log;
-import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
diff --git a/design/src/android/support/design/widget/TabLayout.java b/design/src/android/support/design/widget/TabLayout.java
index 17b4cd5..9b81465 100755
--- a/design/src/android/support/design/widget/TabLayout.java
+++ b/design/src/android/support/design/widget/TabLayout.java
@@ -51,6 +51,7 @@
import android.support.v4.widget.TextViewCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.content.res.AppCompatResources;
+import android.support.v7.widget.TooltipCompat;
import android.text.Layout;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -1765,7 +1766,7 @@
iconView.requestLayout();
}
}
- ViewCompat.setTooltipText(this, hasText ? null : contentDesc);
+ TooltipCompat.setTooltipText(this, hasText ? null : contentDesc);
}
public Tab getTab() {
diff --git a/design/src/android/support/design/widget/ThemeUtils.java b/design/src/android/support/design/widget/ThemeUtils.java
index ffdc3f4..821dcb6 100644
--- a/design/src/android/support/design/widget/ThemeUtils.java
+++ b/design/src/android/support/design/widget/ThemeUtils.java
@@ -18,7 +18,6 @@
import android.content.Context;
import android.content.res.TypedArray;
-import android.support.design.R;
class ThemeUtils {
@@ -29,9 +28,7 @@
static void checkAppCompatTheme(Context context) {
TypedArray a = context.obtainStyledAttributes(APPCOMPAT_CHECK_ATTRS);
final boolean failed = !a.hasValue(0);
- if (a != null) {
- a.recycle();
- }
+ a.recycle();
if (failed) {
throw new IllegalArgumentException("You need to use a Theme.AppCompat theme "
+ "(or descendant) with the design library.");
diff --git a/design/tests/src/android/support/design/widget/BaseInstrumentationTestCase.java b/design/tests/src/android/support/design/widget/BaseInstrumentationTestCase.java
index 0c09e7b..e06fa0a 100644
--- a/design/tests/src/android/support/design/widget/BaseInstrumentationTestCase.java
+++ b/design/tests/src/android/support/design/widget/BaseInstrumentationTestCase.java
@@ -17,17 +17,18 @@
package android.support.design.widget;
import android.app.Activity;
-import android.support.test.rule.ActivityTestRule;
+import android.support.test.rule.BootlegActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
+
import org.junit.Rule;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public abstract class BaseInstrumentationTestCase<A extends Activity> {
@Rule
- public final ActivityTestRule<A> mActivityTestRule;
+ public final BootlegActivityTestRule<A> mActivityTestRule;
protected BaseInstrumentationTestCase(Class<A> activityClass) {
- mActivityTestRule = new ActivityTestRule<A>(activityClass);
+ mActivityTestRule = new BootlegActivityTestRule<>(activityClass);
}
}
diff --git a/design/tests/src/android/support/design/widget/BottomSheetDialogTest.java b/design/tests/src/android/support/design/widget/BottomSheetDialogTest.java
index 940eb5a..c434f9f 100644
--- a/design/tests/src/android/support/design/widget/BottomSheetDialogTest.java
+++ b/design/tests/src/android/support/design/widget/BottomSheetDialogTest.java
@@ -23,11 +23,10 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.content.Context;
diff --git a/design/tests/src/android/support/design/widget/TabLayoutWithViewPagerTest.java b/design/tests/src/android/support/design/widget/TabLayoutWithViewPagerTest.java
index c01b785..09bf43c 100755
--- a/design/tests/src/android/support/design/widget/TabLayoutWithViewPagerTest.java
+++ b/design/tests/src/android/support/design/widget/TabLayoutWithViewPagerTest.java
@@ -72,7 +72,7 @@
protected ArrayList<Pair<String, Q>> mEntries = new ArrayList<>();
public void add(String title, Q content) {
- mEntries.add(new Pair(title, content));
+ mEntries.add(new Pair<>(title, content));
}
@Override
diff --git a/design/tests/src/android/support/design/widget/TextInputLayoutActivity.java b/design/tests/src/android/support/design/widget/TextInputLayoutActivity.java
index 1ae3a29..613ae6e 100644
--- a/design/tests/src/android/support/design/widget/TextInputLayoutActivity.java
+++ b/design/tests/src/android/support/design/widget/TextInputLayoutActivity.java
@@ -16,7 +16,6 @@
package android.support.design.widget;
import android.support.design.test.R;
-import android.support.v7.widget.Toolbar;
public class TextInputLayoutActivity extends BaseTestActivity {
@Override
diff --git a/design/tests/src/android/support/test/rule/BootlegActivityTestRule.java b/design/tests/src/android/support/test/rule/BootlegActivityTestRule.java
new file mode 100644
index 0000000..b12edfa
--- /dev/null
+++ b/design/tests/src/android/support/test/rule/BootlegActivityTestRule.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 android.support.test.rule;
+
+import android.app.Activity;
+import android.support.annotation.NonNull;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.intercepting.SingleActivityFactory;
+
+/**
+ * An extension of existing {@link ActivityTestRule} that contains a fix for finishActivity()
+ * method (cr/138555678).
+ *
+ * Remove this once we move to Android Test Runner 0.7.
+ */
+public class BootlegActivityTestRule<T extends Activity> extends ActivityTestRule {
+ public BootlegActivityTestRule(Class activityClass) {
+ super(activityClass);
+ }
+
+ public BootlegActivityTestRule(Class<T> activityClass, boolean initialTouchMode) {
+ super(activityClass, initialTouchMode);
+ }
+
+ public BootlegActivityTestRule(Class<T> activityClass, boolean initialTouchMode,
+ boolean launchActivity) {
+ super(activityClass, initialTouchMode, launchActivity);
+ }
+
+ public BootlegActivityTestRule(
+ SingleActivityFactory activityFactory,
+ boolean initialTouchMode, boolean launchActivity) {
+ super(activityFactory, initialTouchMode, launchActivity);
+ }
+
+ public BootlegActivityTestRule(Class<T> activityClass,
+ @NonNull String targetPackage, int launchFlags,
+ boolean initialTouchMode, boolean launchActivity) {
+ super(activityClass, targetPackage, launchFlags, initialTouchMode, launchActivity);
+ }
+
+ @Override
+ public void finishActivity() {
+ super.finishActivity();
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
+
+ @Override
+ public T getActivity() {
+ return (T) super.getActivity();
+ }
+}
diff --git a/dynamic-animation/Android.mk b/dynamic-animation/Android.mk
index b8ba139..1b33094 100644
--- a/dynamic-animation/Android.mk
+++ b/dynamic-animation/Android.mk
@@ -20,7 +20,6 @@
LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
LOCAL_SRC_FILES := $(call all-java-files-under,src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_MANIFEST_FILE := AndroidManifest-make.xml
LOCAL_SHARED_ANDROID_LIBRARIES := \
android-support-compat \
android-support-annotations
diff --git a/dynamic-animation/src/android/support/animation/AnimationHandler.java b/dynamic-animation/src/android/support/animation/AnimationHandler.java
index 948b93e..fac9cd2 100644
--- a/dynamic-animation/src/android/support/animation/AnimationHandler.java
+++ b/dynamic-animation/src/android/support/animation/AnimationHandler.java
@@ -175,17 +175,6 @@
}
}
- private int getCallbackSize() {
- int count = 0;
- int size = mAnimationCallbacks.size();
- for (int i = size - 1; i >= 0; i--) {
- if (mAnimationCallbacks.get(i) != null) {
- count++;
- }
- }
- return count;
- }
-
/**
* Default provider of timing pulse that uses Choreographer for frame callbacks.
*/
diff --git a/dynamic-animation/src/android/support/animation/DynamicAnimation.java b/dynamic-animation/src/android/support/animation/DynamicAnimation.java
index ee90df2..7285943 100644
--- a/dynamic-animation/src/android/support/animation/DynamicAnimation.java
+++ b/dynamic-animation/src/android/support/animation/DynamicAnimation.java
@@ -527,9 +527,7 @@
if (mLastFrameTime == 0) {
// First frame.
mLastFrameTime = frameTime;
- if (mStartValueIsSet) {
- setPropertyValue(mValue);
- }
+ setPropertyValue(mValue);
return false;
}
long deltaT = frameTime - mLastFrameTime;
@@ -555,39 +553,7 @@
* @param deltaT time elapsed in millisecond since last frame
* @return whether the animation has finished
*/
- boolean updateValueAndVelocity(long deltaT) {
- if (deltaT < 0) {
- throw new UnsupportedOperationException("Cannot play animation backwards");
- }
- if (deltaT == 0) {
- return false;
- }
-
- // Break down the deltaT into 4ms intervals.
- long increment = Math.min(4, deltaT);
-
- int totalT = (int) deltaT;
- int i = 0;
- float velocity = mVelocity;
- float value = mValue;
- for (i = 0; i <= totalT; i += increment) {
- float acceleration = getAcceleration(value, velocity);
- float newVelocity = acceleration * increment / 1000 + velocity;
- value += (velocity + newVelocity) / 2 * increment / 1000;
- velocity = newVelocity;
- if (i == totalT) {
- break;
- } else if (i + increment > deltaT) {
- increment = totalT - i;
- }
- }
-
- mVelocity = (float) velocity;
- mValue = (float) value;
-
- // TODO: need to update values to end value if true, otherwise there'll be precision loss.
- return isAtEquilibrium(mValue, mVelocity);
- }
+ abstract boolean updateValueAndVelocity(long deltaT);
/**
* Internal method to reset the animation states when animation is finished/canceled.
diff --git a/dynamic-animation/tests/src/android/support/dynamicanimation/tests/SpringTests.java b/dynamic-animation/tests/src/android/support/dynamicanimation/tests/SpringTests.java
index 801ed39..ebceeea 100644
--- a/dynamic-animation/tests/src/android/support/dynamicanimation/tests/SpringTests.java
+++ b/dynamic-animation/tests/src/android/support/dynamicanimation/tests/SpringTests.java
@@ -16,6 +16,8 @@
package android.support.dynamicanimation.tests;
+import static junit.framework.Assert.fail;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -36,11 +38,13 @@
import android.support.test.filters.MediumTest;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
+import android.util.AndroidRuntimeException;
import android.view.View;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
@MediumTest
@@ -50,6 +54,9 @@
public View mView1;
public View mView2;
+ @Rule
+ public ExpectedException mExpectedException = ExpectedException.none();
+
public SpringTests() {
mActivityTestRule = new ActivityTestRule<>(AnimationActivity.class);
}
@@ -273,6 +280,26 @@
}
/**
+ * Test negative stiffness and expect exception.
+ */
+ @Test
+ public void testInvalidStiffness() {
+ SpringForce spring = new SpringForce();
+ mExpectedException.expect(IllegalArgumentException.class);
+ spring.setStiffness(-5f);
+ }
+
+ /**
+ * Test negative dampingRatio and expect exception.
+ */
+ @Test
+ public void testInvalidDampingRatio() {
+ SpringForce spring = new SpringForce();
+ mExpectedException.expect(IllegalArgumentException.class);
+ spring.setDampingRatio(-5f);
+ }
+
+ /**
* Remove an update listener and an end listener, and check that there are no interaction after
* removal.
*/
@@ -427,6 +454,177 @@
assertEquals(0, mView1.getScrollX());
}
+ /**
+ * Makes sure all the properties getter works.
+ */
+ @Test
+ public void testAllProperties() {
+ final DynamicAnimation.ViewProperty[] properties = {
+ DynamicAnimation.ALPHA, DynamicAnimation.TRANSLATION_X,
+ DynamicAnimation.TRANSLATION_Y, DynamicAnimation.TRANSLATION_Z,
+ DynamicAnimation.SCALE_X, DynamicAnimation.SCALE_Y, DynamicAnimation.ROTATION,
+ DynamicAnimation.ROTATION_X, DynamicAnimation.ROTATION_Y,
+ DynamicAnimation.X, DynamicAnimation.Y, DynamicAnimation.Z,
+ DynamicAnimation.SCROLL_X, DynamicAnimation.SCROLL_Y,
+ };
+
+ mView1.setAlpha(0f);
+ mView1.setTranslationX(0f);
+ mView1.setTranslationY(0f);
+ mView1.setTranslationZ(0f);
+
+ mView1.setScaleX(0f);
+ mView1.setScaleY(0f);
+
+ mView1.setRotation(0f);
+ mView1.setRotationX(0f);
+ mView1.setRotationY(0f);
+
+ mView1.setX(0f);
+ mView1.setY(0f);
+ mView1.setZ(0f);
+
+ mView1.setScrollX(0);
+ mView1.setScrollY(0);
+
+ View mockView = mock(View.class);
+
+ final SpringAnimation[] anims = new SpringAnimation[properties.length];
+ final DynamicAnimation.OnAnimationUpdateListener[] mockListeners =
+ new DynamicAnimation.OnAnimationUpdateListener[properties.length];
+ for (int i = 0; i < properties.length; i++) {
+ anims[i] = new SpringAnimation(mView1, properties[i], 1);
+ final int finalI = i;
+ anims[i].addUpdateListener(
+ new DynamicAnimation.OnAnimationUpdateListener() {
+ boolean mIsFirstFrame = true;
+ @Override
+ public void onAnimationUpdate(DynamicAnimation animation, float value,
+ float velocity) {
+ if (mIsFirstFrame) {
+ assertEquals(value, 0f, 0f);
+ }
+ mIsFirstFrame = false;
+ }
+ });
+ mockListeners[i] = mock(DynamicAnimation.OnAnimationUpdateListener.class);
+ anims[i].addUpdateListener(mockListeners[i]);
+ }
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ for (int i = properties.length - 1; i >= 0; i--) {
+ anims[i].start();
+ }
+ }
+ });
+
+ for (int i = 0; i < properties.length; i++) {
+ int timeout = i == 0 ? 100 : 0;
+ verify(mockListeners[i], timeout(timeout).atLeast(1)).onAnimationUpdate(
+ any(SpringAnimation.class), any(float.class), any(float.class));
+ }
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ for (int i = 0; i < properties.length; i++) {
+ anims[i].cancel();
+ }
+ }
+ });
+ }
+
+ /**
+ * Test start() on a test thread.
+ */
+ @Test
+ public void testStartOnNonMainThread() {
+ mExpectedException.expect(AndroidRuntimeException.class);
+ SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.ALPHA, 0f);
+ anim.start();
+ }
+
+ /**
+ * Test cancel() on a test thread.
+ */
+ @Test
+ public void testCancelOnNonMainThread() {
+ mExpectedException.expect(AndroidRuntimeException.class);
+ SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.ALPHA, 0f);
+ anim.cancel();
+ }
+
+ /**
+ * Test skipToEnd() on a test thread.
+ */
+ @Test
+ public void testSkipToEndOnNonMainThread() {
+ mExpectedException.expect(AndroidRuntimeException.class);
+ SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.ALPHA, 0f);
+ anim.skipToEnd();
+ }
+
+ /**
+ * Test invalid start condition: no spring position specified, final position > max value,
+ * and final position < min. Expect exception in all these cases.
+ */
+ @Test
+ public void testInvalidStartingCondition() {
+ final SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.X);
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ // Expect exception from not setting spring final position before calling start.
+ try {
+ anim.start();
+ fail("No exception is thrown when calling start() from non-main thread.");
+ } catch (UnsupportedOperationException e) {
+ }
+
+ // Expect exception from having a final position < min value
+ try {
+ anim.setMinValue(50);
+ // Final position < min value, expect exception.
+ anim.setStartValue(50).animateToFinalPosition(40);
+ fail("No exception is thrown when spring position is less than min value.");
+ } catch (UnsupportedOperationException e) {
+ }
+
+ // Expect exception from not setting spring final position before calling start.
+ try {
+ anim.setMaxValue(60);
+ // Final position < min value, expect exception.
+ anim.setStartValue(60).animateToFinalPosition(70);
+ fail("No exception is thrown when spring position is greater than max value.");
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+ });
+ }
+
+ /**
+ * Try skipToEnd() on an undamped spring, and expect exception.
+ */
+ @Test
+ public void testUndampedSpring() {
+ final SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.Y);
+ anim.setSpring(new SpringForce(10).setDampingRatio(0));
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ // Expect exception for ending an undamped spring.
+ try {
+ anim.skipToEnd();
+ fail("No exception is thrown when calling skipToEnd() on an undamped spring");
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+ });
+
+ }
+
static class MyEndListener implements DynamicAnimation.OnAnimationEndListener {
public long endTime = -1;
diff --git a/emoji/appcompat/AndroidManifest.xml b/emoji/appcompat/AndroidManifest.xml
new file mode 100644
index 0000000..81bc0f8
--- /dev/null
+++ b/emoji/appcompat/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.support.text.emoji.appcompat">
+ <uses-sdk android:minSdkVersion="19"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+ <application />
+</manifest>
diff --git a/emoji/appcompat/build.gradle b/emoji/appcompat/build.gradle
new file mode 100644
index 0000000..6074e02
--- /dev/null
+++ b/emoji/appcompat/build.gradle
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+apply plugin: android.support.SupportLibraryPlugin
+archivesBaseName = 'support-emoji-appcompat'
+
+dependencies {
+ compile fileTree(include: ['*.jar'], dir: 'libs')
+ compile project(':support-emoji')
+ compile project(':support-appcompat-v7')
+
+ androidTestCompile (libs.test_runner) {
+ exclude module: 'support-annotations'
+ }
+ androidTestCompile (libs.espresso_core) {
+ exclude module: 'support-annotations'
+ }
+ androidTestCompile libs.mockito_core
+ androidTestCompile libs.dexmaker
+ androidTestCompile libs.dexmaker_mockito
+}
+
+android {
+ compileSdkVersion project.ext.currentSdk
+
+ defaultConfig {
+ minSdkVersion 19
+ }
+
+ sourceSets {
+ main.java.srcDir 'src'
+ }
+}
+
+supportLibrary {
+ name 'Android Emoji AppCompat'
+ inceptionYear '2017'
+ description 'EmojiCompat Widgets for AppCompat integration'
+}
\ No newline at end of file
diff --git a/emoji/appcompat/src/android/support/text/emoji/widget/EmojiAppCompatButton.java b/emoji/appcompat/src/android/support/text/emoji/widget/EmojiAppCompatButton.java
new file mode 100644
index 0000000..8672beb
--- /dev/null
+++ b/emoji/appcompat/src/android/support/text/emoji/widget/EmojiAppCompatButton.java
@@ -0,0 +1,70 @@
+/*
+ * 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.text.emoji.widget;
+
+import android.content.Context;
+import android.support.v7.widget.AppCompatButton;
+import android.text.InputFilter;
+import android.util.AttributeSet;
+
+/**
+ * AppCompatButton widget enhanced with emoji capability by using {@link EmojiTextViewHelper}.
+ */
+public class EmojiAppCompatButton extends AppCompatButton {
+ private EmojiTextViewHelper mEmojiTextViewHelper;
+ private boolean mInitialized;
+
+ public EmojiAppCompatButton(Context context) {
+ super(context);
+ init();
+ }
+
+ public EmojiAppCompatButton(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public EmojiAppCompatButton(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ private void init() {
+ if (!mInitialized) {
+ mInitialized = true;
+ getEmojiTextViewHelper().updateTransformationMethod();
+ }
+ }
+
+ @Override
+ public void setFilters(InputFilter[] filters) {
+ super.setFilters(getEmojiTextViewHelper().getFilters(filters));
+ }
+
+ @Override
+ public void setAllCaps(boolean allCaps) {
+ super.setAllCaps(allCaps);
+ getEmojiTextViewHelper().setAllCaps(allCaps);
+ }
+
+ private EmojiTextViewHelper getEmojiTextViewHelper() {
+ if (mEmojiTextViewHelper == null) {
+ mEmojiTextViewHelper = new EmojiTextViewHelper(this);
+ }
+ return mEmojiTextViewHelper;
+ }
+}
diff --git a/emoji/appcompat/src/android/support/text/emoji/widget/EmojiAppCompatEditText.java b/emoji/appcompat/src/android/support/text/emoji/widget/EmojiAppCompatEditText.java
new file mode 100644
index 0000000..2689294
--- /dev/null
+++ b/emoji/appcompat/src/android/support/text/emoji/widget/EmojiAppCompatEditText.java
@@ -0,0 +1,71 @@
+/*
+ * 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.text.emoji.widget;
+
+import android.content.Context;
+import android.support.v7.widget.AppCompatEditText;
+import android.util.AttributeSet;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+
+/**
+ * AppCompatEditText widget enhanced with emoji capability by using {@link EmojiEditTextHelper}.
+ */
+public class EmojiAppCompatEditText extends AppCompatEditText {
+ private EmojiEditTextHelper mEmojiEditTextHelper;
+ private boolean mInitialized;
+
+ public EmojiAppCompatEditText(Context context) {
+ super(context);
+ init();
+ }
+
+ public EmojiAppCompatEditText(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public EmojiAppCompatEditText(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ private void init() {
+ if (!mInitialized) {
+ mInitialized = true;
+ setKeyListener(getKeyListener());
+ }
+ }
+
+ @Override
+ public void setKeyListener(android.text.method.KeyListener input) {
+ super.setKeyListener(getEmojiEditTextHelper().getKeyListener(input));
+ }
+
+ @Override
+ public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+ InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
+ return getEmojiEditTextHelper().onCreateInputConnection(inputConnection, outAttrs);
+ }
+
+ private EmojiEditTextHelper getEmojiEditTextHelper() {
+ if (mEmojiEditTextHelper == null) {
+ mEmojiEditTextHelper = new EmojiEditTextHelper(this);
+ }
+ return mEmojiEditTextHelper;
+ }
+}
diff --git a/emoji/appcompat/src/android/support/text/emoji/widget/EmojiAppCompatTextView.java b/emoji/appcompat/src/android/support/text/emoji/widget/EmojiAppCompatTextView.java
new file mode 100644
index 0000000..00c99ab
--- /dev/null
+++ b/emoji/appcompat/src/android/support/text/emoji/widget/EmojiAppCompatTextView.java
@@ -0,0 +1,70 @@
+/*
+ * 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.text.emoji.widget;
+
+import android.content.Context;
+import android.support.v7.widget.AppCompatTextView;
+import android.text.InputFilter;
+import android.util.AttributeSet;
+
+/**
+ * AppCompatTextView widget enhanced with emoji capability by using {@link EmojiTextViewHelper}.
+ */
+public class EmojiAppCompatTextView extends AppCompatTextView {
+ private EmojiTextViewHelper mEmojiTextViewHelper;
+ private boolean mInitialized;
+
+ public EmojiAppCompatTextView(Context context) {
+ super(context);
+ init();
+ }
+
+ public EmojiAppCompatTextView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public EmojiAppCompatTextView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ private void init() {
+ if (!mInitialized) {
+ mInitialized = true;
+ getEmojiTextViewHelper().updateTransformationMethod();
+ }
+ }
+
+ @Override
+ public void setFilters(InputFilter[] filters) {
+ super.setFilters(getEmojiTextViewHelper().getFilters(filters));
+ }
+
+ @Override
+ public void setAllCaps(boolean allCaps) {
+ super.setAllCaps(allCaps);
+ getEmojiTextViewHelper().setAllCaps(allCaps);
+ }
+
+ private EmojiTextViewHelper getEmojiTextViewHelper() {
+ if (mEmojiTextViewHelper == null) {
+ mEmojiTextViewHelper = new EmojiTextViewHelper(this);
+ }
+ return mEmojiTextViewHelper;
+ }
+}
diff --git a/dynamic-animation/AndroidManifest-make.xml b/emoji/bundled-typeface/AndroidManifest.xml
similarity index 77%
copy from dynamic-animation/AndroidManifest-make.xml
copy to emoji/bundled-typeface/AndroidManifest.xml
index bfe97cc..2c5bc46 100644
--- a/dynamic-animation/AndroidManifest-make.xml
+++ b/emoji/bundled-typeface/AndroidManifest.xml
@@ -14,6 +14,8 @@
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.support.dynamicanimation">
- <uses-sdk android:minSdkVersion="16"/>
-</manifest>
+ package="android.support.text.emoji.typeface">
+ <uses-sdk android:minSdkVersion="19"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}"/>
+ <application/>
+</manifest>
\ No newline at end of file
diff --git a/emoji/bundled-typeface/assets/NotoColorEmojiCompat.ttf b/emoji/bundled-typeface/assets/NotoColorEmojiCompat.ttf
new file mode 100644
index 0000000..0c59d8e
--- /dev/null
+++ b/emoji/bundled-typeface/assets/NotoColorEmojiCompat.ttf
Binary files differ
diff --git a/emoji/bundled-typeface/build.gradle b/emoji/bundled-typeface/build.gradle
new file mode 100644
index 0000000..5014649
--- /dev/null
+++ b/emoji/bundled-typeface/build.gradle
@@ -0,0 +1,25 @@
+apply plugin: android.support.SupportLibraryPlugin
+archivesBaseName = 'support-emoji-typeface'
+
+android {
+ compileSdkVersion project.ext.currentSdk
+
+ defaultConfig {
+ minSdkVersion 19
+ }
+
+ sourceSets {
+ main.java.srcDir 'src'
+ main.assets.srcDirs 'assets'
+ }
+}
+
+dependencies {
+ compile project(path: ':support-emoji')
+}
+
+supportLibrary {
+ name 'Android Emoji Compat'
+ inceptionYear '2017'
+ description 'Library bundled with assets to enable emoji compatibility in Kitkat and newer devices to avoid the empty emoji characters.'
+}
\ No newline at end of file
diff --git a/emoji/bundled-typeface/src/android/support/text/emoji/bundled/BundledEmojiCompatConfig.java b/emoji/bundled-typeface/src/android/support/text/emoji/bundled/BundledEmojiCompatConfig.java
new file mode 100644
index 0000000..5b0740d
--- /dev/null
+++ b/emoji/bundled-typeface/src/android/support/text/emoji/bundled/BundledEmojiCompatConfig.java
@@ -0,0 +1,85 @@
+/*
+ * 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.text.emoji.bundled;
+
+import android.content.Context;
+import android.content.res.AssetManager;
+import android.support.annotation.NonNull;
+import android.support.text.emoji.EmojiCompat;
+import android.support.text.emoji.MetadataRepo;
+import android.support.v4.util.Preconditions;
+
+/**
+ * {@link EmojiCompat.Config} implementation that loads the metadata using AssetManager and
+ * bundled resources.
+ * <p/>
+ * <pre><code>EmojiCompat.init(new BundledEmojiCompatConfig(context));</code></pre>
+ *
+ * @see EmojiCompat
+ */
+public class BundledEmojiCompatConfig extends EmojiCompat.Config {
+
+ /**
+ * Default constructor.
+ *
+ * @param context Context instance
+ */
+ public BundledEmojiCompatConfig(@NonNull Context context) {
+ super(new BundledMetadataLoader(context));
+ }
+
+ private static class BundledMetadataLoader implements EmojiCompat.MetadataLoader {
+ private final Context mContext;
+
+ private BundledMetadataLoader(@NonNull Context context) {
+ mContext = context.getApplicationContext();
+ }
+
+ @Override
+ public void load(@NonNull EmojiCompat.LoaderCallback loaderCallback) {
+ Preconditions.checkNotNull(loaderCallback, "loaderCallback cannot be null");
+ final InitRunnable runnable = new InitRunnable(mContext, loaderCallback);
+ final Thread thread = new Thread(runnable);
+ thread.setDaemon(false);
+ thread.start();
+ }
+
+ }
+
+ private static class InitRunnable implements Runnable {
+ private static final String FONT_NAME = "NotoColorEmojiCompat.ttf";
+ private final EmojiCompat.LoaderCallback mLoaderCallback;
+ private final Context mContext;
+
+ private InitRunnable(final Context context,
+ final EmojiCompat.LoaderCallback loaderCallback) {
+ mContext = context;
+ mLoaderCallback = loaderCallback;
+ }
+
+ @Override
+ public void run() {
+ try {
+ final AssetManager assetManager = mContext.getAssets();
+ final MetadataRepo resourceIndex = MetadataRepo.create(assetManager, FONT_NAME);
+ mLoaderCallback.onLoaded(resourceIndex);
+ } catch (Throwable t) {
+ mLoaderCallback.onFailed(t);
+ }
+ }
+ }
+}
diff --git a/dynamic-animation/AndroidManifest-make.xml b/emoji/core/AndroidManifest.xml
similarity index 78%
copy from dynamic-animation/AndroidManifest-make.xml
copy to emoji/core/AndroidManifest.xml
index bfe97cc..b288921 100644
--- a/dynamic-animation/AndroidManifest-make.xml
+++ b/emoji/core/AndroidManifest.xml
@@ -14,6 +14,8 @@
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.support.dynamicanimation">
- <uses-sdk android:minSdkVersion="16"/>
+ package="android.support.text.emoji">
+ <uses-sdk android:minSdkVersion="19"/>
+ <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+ <application />
</manifest>
diff --git a/emoji/core/build.gradle b/emoji/core/build.gradle
new file mode 100644
index 0000000..cc389d1
--- /dev/null
+++ b/emoji/core/build.gradle
@@ -0,0 +1,41 @@
+apply plugin: android.support.SupportLibraryPlugin
+apply plugin: 'org.anarres.jarjar'
+archivesBaseName = 'support-emoji'
+
+dependencies {
+ compile project(':support-compat')
+
+ compile jarjar.repackage {
+ from files('third_party/flatbuffers/flatbuffers-java-1.6.0.jar')
+ destinationName 'flatbuffers-java-1.6.0-repacked.jar'
+ classRename 'com.google.flatbuffers.**', 'com.google.flatbuffers.emojicompat.@1'
+ }
+
+ androidTestCompile (libs.test_runner) {
+ exclude module: 'support-annotations'
+ }
+ androidTestCompile (libs.espresso_core) {
+ exclude module: 'support-annotations'
+ }
+ androidTestCompile libs.mockito_core
+ androidTestCompile libs.dexmaker
+ androidTestCompile libs.dexmaker_mockito
+}
+
+android {
+ compileSdkVersion project.ext.currentSdk
+
+ defaultConfig {
+ minSdkVersion 19
+ }
+
+ sourceSets {
+ main.java.srcDir 'src'
+ }
+}
+
+supportLibrary {
+ name 'Android Emoji Compat'
+ inceptionYear '2017'
+ description 'Core library to enable emoji compatibility in Kitkat and newer devices to avoid the empty emoji characters.'
+}
\ No newline at end of file
diff --git a/emoji/core/src/android/support/text/emoji/EmojiCompat.java b/emoji/core/src/android/support/text/emoji/EmojiCompat.java
new file mode 100644
index 0000000..cd235a3
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/EmojiCompat.java
@@ -0,0 +1,683 @@
+/*
+ * 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.text.emoji;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.graphics.Typeface;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.AnyThread;
+import android.support.annotation.GuardedBy;
+import android.support.annotation.IntDef;
+import android.support.annotation.IntRange;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
+import android.support.annotation.VisibleForTesting;
+import android.support.v4.util.ArraySet;
+import android.support.v4.util.Preconditions;
+import android.text.Editable;
+import android.text.method.KeyListener;
+import android.view.KeyEvent;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * Main class to keep Android devices up to date with the newest emojis by adding {@link EmojiSpan}s
+ * to a given {@link CharSequence}. It is a singleton class that can be configured using a {@link
+ * EmojiCompat.Config} instance.
+ * <p/>
+ * EmojiCompat has to be initialized using {@link #init(EmojiCompat.Config)} function before it can
+ * process a {@link CharSequence}.
+ * <pre><code>EmojiCompat.init(/* a config instance */);</code></pre>
+ * <p/>
+ * It is suggested to make the initialization as early as possible in your app. Please check {@link
+ * EmojiCompat.Config} for more configuration parameters.
+ * <p/>
+ * During initialization information about emojis is loaded on a background thread. Before the
+ * EmojiCompat instance is initialized, calls to functions such as {@link
+ * EmojiCompat#process(CharSequence)} will throw an exception. You can use the {@link InitCallback}
+ * class to be informed about the state of initialization.
+ * <p/>
+ * After initialization the {@link #get()} function can be used to get the configured instance and
+ * the {@link #process(CharSequence)} function can be used to update a CharSequence with emoji
+ * EmojiSpans.
+ * <p/>
+ * <pre><code>CharSequence processedSequence = EmojiCompat.get().process("some string")</pre>
+ */
+@AnyThread
+public class EmojiCompat {
+ /**
+ * Key in {@link EditorInfo#extras} that represents the emoji metadata version used by the
+ * widget. The existence of the value means that the widget is using EmojiCompat.
+ * <p/>
+ * If exists, the value for the key is an {@code int} and can be used to query EmojiCompat to
+ * see whether the widget has the ability to display a certain emoji using
+ * {@link #hasEmojiGlyph(CharSequence, int)}.
+ */
+ public static final String EDITOR_INFO_METAVERSION_KEY =
+ "android.support.text.emoji.emojiCompat_metadataVersion";
+
+ /**
+ * Key in {@link EditorInfo#extras} that represents {@link
+ * EmojiCompat.Config#setReplaceAll(boolean)} configuration parameter. The key is added only if
+ * EmojiCompat is used by the widget. If exists, the value is a boolean.
+ */
+ public static final String EDITOR_INFO_REPLACE_ALL_KEY =
+ "android.support.text.emoji.emojiCompat_replaceAll";
+
+ private static final Object sInstanceLock = new Object();
+
+ @GuardedBy("sInstanceLock")
+ private static volatile EmojiCompat sInstance;
+
+ private final ReadWriteLock mInitLock;
+
+ @GuardedBy("mInitLock")
+ private final Set<InitCallback> mInitCallbacks;
+
+ @GuardedBy("mInitLock")
+ @LoadState
+ private int mLoadState;
+
+ private final Config mConfig;
+ private final Handler mMainHandler;
+
+ /**
+ * Responsible to process a CharSequence and add the spans. @{code Null} until the time the
+ * metadata is loaded.
+ */
+ private EmojiProcessor mProcessor;
+
+ /**
+ * Keeps the information about emojis. Null until the time the data is loaded.
+ */
+ private MetadataRepo mMetadataRepo;
+
+ private static final int LOAD_STATE_LOADING = 0;
+ private static final int LOAD_STATE_SUCCESS = 1;
+ private static final int LOAD_STATE_FAIL = 2;
+
+ @IntDef({LOAD_STATE_LOADING, LOAD_STATE_SUCCESS, LOAD_STATE_FAIL})
+ @Retention(RetentionPolicy.SOURCE)
+ private @interface LoadState {
+ }
+
+ /**
+ * Private constructor for singleton instance.
+ *
+ * @see #init(Config)
+ */
+ private EmojiCompat(@NonNull final Config config) {
+ mInitLock = new ReentrantReadWriteLock();
+ mConfig = config;
+ mMainHandler = new Handler(Looper.getMainLooper());
+ mInitCallbacks = new ArraySet<>();
+ if (mConfig.mInitCallbacks != null && !mConfig.mInitCallbacks.isEmpty()) {
+ mInitCallbacks.addAll(mConfig.mInitCallbacks);
+ }
+ loadMetadata();
+ }
+
+ /**
+ * Initialize the singleton instance with a configuration.
+ *
+ * @see EmojiCompat.Config
+ */
+ public static EmojiCompat init(@NonNull final Config config) {
+ if (sInstance == null) {
+ synchronized (sInstanceLock) {
+ if (sInstance == null) {
+ sInstance = new EmojiCompat(config);
+ }
+ }
+ }
+ return sInstance;
+ }
+
+ /**
+ * Used by the tests to reset EmojiCompat with a new configuration. Every time it is called a
+ * new instance is created with the new configuration.
+ *
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ @VisibleForTesting
+ public static EmojiCompat reset(@NonNull final Config config) {
+ synchronized (sInstanceLock) {
+ sInstance = new EmojiCompat(config);
+ }
+ return sInstance;
+ }
+
+ /**
+ * Used by the tests to reset EmojiCompat with a new singleton instance.
+ *
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ @VisibleForTesting
+ public static EmojiCompat reset(final EmojiCompat emojiCompat) {
+ synchronized (sInstanceLock) {
+ sInstance = emojiCompat;
+ }
+ return sInstance;
+ }
+
+ /**
+ * Return singleton EmojiCompat instance. Should be called after
+ * {@link #init(EmojiCompat.Config)} is called to initialize the singleton instance.
+ *
+ * @return EmojiCompat instance
+ *
+ * @throws IllegalStateException if called before {@link #init(EmojiCompat.Config)}
+ */
+ public static EmojiCompat get() {
+ synchronized (sInstanceLock) {
+ Preconditions.checkState(sInstance != null,
+ "EmojiCompat is not initialized. Please call EmojiCompat.init() first");
+ return sInstance;
+ }
+ }
+
+ private void loadMetadata() {
+ mInitLock.writeLock().lock();
+ try {
+ mLoadState = LOAD_STATE_LOADING;
+ } finally {
+ mInitLock.writeLock().unlock();
+ }
+
+ try {
+ mConfig.mMetadataLoader.load(new LoaderCallback() {
+ @Override
+ public void onLoaded(@NonNull MetadataRepo metadataRepo) {
+ onMetadataLoadSuccess(metadataRepo);
+ }
+
+ @Override
+ public void onFailed(@Nullable Throwable throwable) {
+ onMetadataLoadFailed(throwable);
+ }
+ });
+ } catch (Throwable t) {
+ onMetadataLoadFailed(t);
+ }
+ }
+
+ private void onMetadataLoadSuccess(@NonNull final MetadataRepo metadataRepo) {
+ if (metadataRepo == null) {
+ onMetadataLoadFailed(new IllegalArgumentException("metadataRepo cannot be null"));
+ return;
+ }
+
+ mMetadataRepo = metadataRepo;
+ mProcessor = new EmojiProcessor(mMetadataRepo, new SpanFactory(),
+ mConfig.mReplaceAll, mConfig.mMaxEmojiPerText);
+
+ final Collection<InitCallback> initCallbacks = new ArrayList<>();
+ mInitLock.writeLock().lock();
+ try {
+ mLoadState = LOAD_STATE_SUCCESS;
+ initCallbacks.addAll(mInitCallbacks);
+ mInitCallbacks.clear();
+ } finally {
+ mInitLock.writeLock().unlock();
+ }
+
+ mMainHandler.post(new ListenerDispatcher(initCallbacks, mLoadState));
+ }
+
+ private void onMetadataLoadFailed(@Nullable final Throwable throwable) {
+ final Collection<InitCallback> initCallbacks = new ArrayList<>();
+ mInitLock.writeLock().lock();
+ try {
+ mLoadState = LOAD_STATE_FAIL;
+ initCallbacks.addAll(mInitCallbacks);
+ mInitCallbacks.clear();
+ } finally {
+ mInitLock.writeLock().unlock();
+ }
+ mMainHandler.post(new ListenerDispatcher(initCallbacks, mLoadState, throwable));
+ }
+
+ /**
+ * Registers an initialization callback. If the initialization is already completed by the time
+ * the listener is added, the callback functions are called immediately. Callbacks are called on
+ * the main looper.
+ *
+ * @param initCallback the initialization callback to register, cannot be {@code null}
+ *
+ * @see #unregisterInitCallback(InitCallback)
+ */
+ public void registerInitCallback(@NonNull InitCallback initCallback) {
+ Preconditions.checkNotNull(initCallback, "initCallback cannot be null");
+
+ mInitLock.writeLock().lock();
+ try {
+ if (mLoadState == LOAD_STATE_SUCCESS || mLoadState == LOAD_STATE_FAIL) {
+ mMainHandler.post(new ListenerDispatcher(initCallback, mLoadState));
+ } else {
+ mInitCallbacks.add(initCallback);
+ }
+ } finally {
+ mInitLock.writeLock().unlock();
+ }
+ }
+
+ /**
+ * Unregisters a callback that was added before.
+ *
+ * @param initCallback the callback to be removed, cannot be {@code null}
+ */
+ public void unregisterInitCallback(@NonNull InitCallback initCallback) {
+ Preconditions.checkNotNull(initCallback, "initCallback cannot be null");
+ mInitLock.writeLock().lock();
+ try {
+ mInitCallbacks.remove(initCallback);
+ } finally {
+ mInitLock.writeLock().unlock();
+ }
+ }
+
+ /**
+ * @return {@code true} if EmojiCompat is successfully initialized
+ */
+ public boolean isInitialized() {
+ mInitLock.readLock().lock();
+ try {
+ return mLoadState == LOAD_STATE_SUCCESS;
+ } finally {
+ mInitLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Handles onKeyDown commands from a {@link KeyListener} and if {@code keyCode} is one of
+ * {@link KeyEvent#KEYCODE_DEL} or {@link KeyEvent#KEYCODE_FORWARD_DEL} it tries to delete an
+ * {@link EmojiSpan} from an {@link Editable}. Returns {@code true} if an {@link EmojiSpan} is
+ * deleted with the characters it covers.
+ * <p/>
+ * If there is a selection where selection start is not equal to selection end, does not
+ * delete.
+ *
+ * @param editable Editable instance passed to {@link KeyListener#onKeyDown(android.view.View,
+ * Editable, int, KeyEvent)}
+ * @param keyCode keyCode passed to {@link KeyListener#onKeyDown(android.view.View, Editable,
+ * int, KeyEvent)}
+ * @param event KeyEvent passed to {@link KeyListener#onKeyDown(android.view.View, Editable,
+ * int, KeyEvent)}
+ *
+ * @return {@code true} if an {@link EmojiSpan} is deleted
+ */
+ public static boolean handleOnKeyDown(@NonNull final Editable editable, final int keyCode,
+ final KeyEvent event) {
+ return EmojiProcessor.handleOnKeyDown(editable, keyCode, event);
+ }
+
+ /**
+ * Handles deleteSurroundingText commands from {@link InputConnection} and tries to delete an
+ * {@link EmojiSpan} from an {@link Editable}. Returns {@code true} if an {@link EmojiSpan} is
+ * deleted.
+ * <p/>
+ * If there is a selection where selection start is not equal to selection end, does not
+ * delete.
+ *
+ * @param inputConnection InputConnection instance
+ * @param editable TextView.Editable instance
+ * @param beforeLength the number of characters before the cursor to be deleted
+ * @param afterLength the number of characters after the cursor to be deleted
+ * @param inCodePoints {@code true} if length parameters are in codepoints
+ *
+ * @return {@code true} if an {@link EmojiSpan} is deleted
+ */
+ public static boolean handleDeleteSurroundingText(
+ @NonNull final InputConnection inputConnection, @NonNull final Editable editable,
+ @IntRange(from = 0) final int beforeLength, @IntRange(from = 0) final int afterLength,
+ final boolean inCodePoints) {
+ return EmojiProcessor.handleDeleteSurroundingText(inputConnection, editable, beforeLength,
+ afterLength, inCodePoints);
+ }
+
+ /**
+ * Returns {@code true} if EmojiCompat is capable of rendering an emoji.
+ *
+ * @param sequence CharSequence representing the emoji
+ *
+ * @return {@code true} if EmojiCompat can render given emoji, cannot be {@code null}
+ *
+ * @throws IllegalStateException if not initialized yet
+ */
+ public boolean hasEmojiGlyph(@NonNull final CharSequence sequence) {
+ Preconditions.checkState(isInitialized(), "Not initialized yet");
+ Preconditions.checkNotNull(sequence, "sequence cannot be null");
+ return mProcessor.getEmojiMetadata(sequence) != null;
+ }
+
+ /**
+ * Returns {@code true} if EmojiCompat is capable of rendering an emoji at the given metadata
+ * version.
+ *
+ * @param sequence CharSequence representing the emoji
+ * @param metadataVersion the metadata version to check against
+ *
+ * @return {@code true} if EmojiCompat can render given emoji, cannot be {@code null}
+ *
+ * @throws IllegalStateException if not initialized yet
+ */
+ public boolean hasEmojiGlyph(@NonNull final CharSequence sequence, final int metadataVersion) {
+ Preconditions.checkState(isInitialized(), "Not initialized yet");
+ Preconditions.checkNotNull(sequence, "sequence cannot be null");
+ final EmojiMetadata emojiMetadata = mProcessor.getEmojiMetadata(sequence);
+ return emojiMetadata != null && emojiMetadata.getCompatAdded() <= metadataVersion;
+ }
+
+ /**
+ * Checks a given CharSequence for emojis, and adds EmojiSpans if any emojis are found.
+ *
+ * @param charSequence CharSequence to add the EmojiSpans
+ *
+ * @throws IllegalStateException if not initialized yet
+ * @see #process(CharSequence, int, int)
+ */
+ public CharSequence process(@NonNull final CharSequence charSequence) {
+ // since charSequence might be null here we have to check it. Passing through here to the
+ // main function so that it can do all the checks including isInitialized. It will also
+ // be the main point that decides what to return.
+ @IntRange(from = 0) final int length = charSequence == null ? 0 : charSequence.length();
+ return process(charSequence, 0, length);
+ }
+
+ /**
+ * Checks a given CharSequence for emojis, and adds EmojiSpans if any emojis are found.
+ * <p>
+ * <ul>
+ * <li>If no emojis are found, {@code charSequence} given as the input is returned without
+ * any changes. i.e. charSequence is a String, and no emojis are found, the same String is
+ * returned.</li>
+ * <li>If the given input is not a Spannable (such as String), and at least one emoji is found
+ * a new {@link android.text.Spannable} instance is returned. </li>
+ * <li>If the given input is a Spannable, the same instance is returned. </li>
+ * </ul>
+ *
+ * @param charSequence CharSequence to add the EmojiSpans, cannot be {@code null}
+ * @param start start index in the charSequence to look for emojis, should be greater than or
+ * equal to {@code 0}, also less than {@code charSequence.length()}
+ * @param end end index in the charSequence to look for emojis, should be greater than or
+ * equal to {@code start} parameter, also less than {@code charSequence.length()}
+ *
+ * @throws IllegalStateException if not initialized yet
+ */
+ public CharSequence process(@NonNull final CharSequence charSequence,
+ @IntRange(from = 0) final int start, @IntRange(from = 0) final int end) {
+ Preconditions.checkState(isInitialized(), "Not initialized yet");
+ return mProcessor.process(charSequence, start, end);
+ }
+
+ /**
+ * Returns the Typeface instance that is created using the emoji font.
+ *
+ * @return {@link Typeface} instance that is created using the emoji font
+ *
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ Typeface getTypeface() {
+ if (mMetadataRepo != null) {
+ return mMetadataRepo.getTypeface();
+ }
+ return null;
+ }
+
+ /**
+ * Updates the EditorInfo attributes in order to communicate information to Keyboards.
+ *
+ * @param outAttrs EditorInfo instance passed to
+ * {@link android.widget.TextView#onCreateInputConnection(EditorInfo)}
+ *
+ * @see #EDITOR_INFO_METAVERSION_KEY
+ * @see #EDITOR_INFO_REPLACE_ALL_KEY
+ *
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ public void updateEditorInfoAttrs(@NonNull final EditorInfo outAttrs) {
+ if (isInitialized() && outAttrs != null && outAttrs.extras != null) {
+ outAttrs.extras.putInt(EDITOR_INFO_METAVERSION_KEY, mMetadataRepo.getMetadataVersion());
+ outAttrs.extras.putBoolean(EDITOR_INFO_REPLACE_ALL_KEY, mConfig.mReplaceAll);
+ }
+ }
+
+ /**
+ * Factory class that creates the EmojiSpans. By default it creates {@link TypefaceEmojiSpan}.
+ *
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ static class SpanFactory {
+ /**
+ * Create EmojiSpan instance.
+ *
+ * @param metadata EmojiMetadata instance
+ *
+ * @return EmojiSpan instance
+ */
+ EmojiSpan createSpan(@NonNull final EmojiMetadata metadata) {
+ return new TypefaceEmojiSpan(metadata);
+ }
+ }
+
+ /**
+ * Listener class for the initialization of the EmojiCompat.
+ */
+ public abstract static class InitCallback {
+ /**
+ * Called when EmojiCompat is initialized and the emoji data is loaded.
+ */
+ public void onInitialized() {
+ }
+
+ /**
+ * Called when an unrecoverable error occurs during EmojiCompat initialization.
+ */
+ public void onFailed(@Nullable Throwable throwable) {
+ }
+ }
+
+ /**
+ * Interface to load emoji metadata.
+ */
+ public interface MetadataLoader {
+ /**
+ * Start loading the metadata. When the loading operation is finished {@link
+ * LoaderCallback#onLoaded(MetadataRepo)} or
+ * {@link LoaderCallback#onFailed(Throwable)}
+ * should be called.
+ *
+ * @param loaderCallback callback to signal the loading state
+ */
+ void load(@NonNull LoaderCallback loaderCallback);
+ }
+
+ /**
+ * Callback to inform EmojiCompat about the state of the metadata load. Passed to MetadataLoader
+ * during {@link MetadataLoader#load(LoaderCallback)} call.
+ */
+ public abstract static class LoaderCallback {
+ /**
+ * Called by {@link MetadataLoader} when metadata is loaded successfully.
+ *
+ * @param metadataRepo MetadataRepo instance, cannot be {@code null}
+ */
+ public abstract void onLoaded(@NonNull MetadataRepo metadataRepo);
+
+ /**
+ * Called by {@link MetadataLoader} if an error occurs while loading the metadata.
+ *
+ * @param throwable the exception that caused the failure, {@code nullable}
+ */
+ public abstract void onFailed(@Nullable Throwable throwable);
+ }
+
+ /**
+ * Configuration class for EmojiCompat.
+ *
+ * @see #init(EmojiCompat.Config)
+ */
+ public abstract static class Config {
+ private final MetadataLoader mMetadataLoader;
+ /**
+ * Measurements on Pixel XL, Android N MR2, EditText delete operation takes 7ms for
+ * 100 EmojiSpans.
+ */
+ private int mMaxEmojiPerText = 100;
+ private boolean mReplaceAll;
+ private Set<InitCallback> mInitCallbacks;
+
+ /**
+ * Default constructor.
+ *
+ * @param metadataLoader MetadataLoader instance, cannot be {@code null}
+ */
+ protected Config(@NonNull final MetadataLoader metadataLoader) {
+ Preconditions.checkNotNull(metadataLoader, "metadataLoader cannot be null.");
+ mMetadataLoader = metadataLoader;
+ }
+
+ /**
+ * Set the limit of EmojiSpans to be added to a CharSequence. The number of spans in a
+ * CharSequence affects the performance of the EditText, TextView.
+ * <p/>
+ * Default value is {@code 100}.
+ *
+ * @param maxEmojiPerText maximum number of EmojiSpans to be added to a single
+ * CharSequence, should be equal or greater than 0
+ *
+ * @return EmojiCompat.Config instance
+ */
+ public Config setMaxEmojiPerText(@IntRange(from = 0) final int maxEmojiPerText) {
+ Preconditions.checkArgumentNonnegative(maxEmojiPerText,
+ "maxEmojiPerText cannot be negative");
+ mMaxEmojiPerText = maxEmojiPerText;
+ return this;
+ }
+
+ /**
+ * Registers an initialization callback.
+ *
+ * @param initCallback the initialization callback to register, cannot be {@code null}
+ *
+ * @return EmojiCompat.Config instance
+ */
+ public Config registerInitCallback(@NonNull InitCallback initCallback) {
+ Preconditions.checkNotNull(initCallback, "initCallback cannot be null");
+ if (mInitCallbacks == null) {
+ mInitCallbacks = new ArraySet<>();
+ }
+
+ mInitCallbacks.add(initCallback);
+
+ return this;
+ }
+
+ /**
+ * Unregisters a callback that was added before.
+ *
+ * @param initCallback the initialization callback to be removed, cannot be {@code null}
+ *
+ * @return EmojiCompat.Config instance
+ */
+ public Config unregisterInitCallback(@NonNull InitCallback initCallback) {
+ Preconditions.checkNotNull(initCallback, "initCallback cannot be null");
+ if (mInitCallbacks != null) {
+ mInitCallbacks.remove(initCallback);
+ }
+ return this;
+ }
+
+ /**
+ * Determines whether EmojiCompat should replace all the emojis it finds with the
+ * EmojiSpans. By default EmojiCompat tries its best to understand if the system already
+ * can render an emoji and do not replace those emojis.
+ *
+ * @param replaceAll replace all emojis found with EmojiSpans
+ *
+ * @return EmojiCompat.Config instance
+ */
+ public Config setReplaceAll(final boolean replaceAll) {
+ mReplaceAll = replaceAll;
+ return this;
+ }
+ }
+
+ /**
+ * Runnable to call success/failure case for the listeners.
+ */
+ private static class ListenerDispatcher implements Runnable {
+ private final List<InitCallback> mInitCallbacks;
+ private final Throwable mThrowable;
+ private final int mLoadState;
+
+ ListenerDispatcher(@NonNull final InitCallback initCallback,
+ @LoadState final int loadState) {
+ this(Arrays.asList(Preconditions.checkNotNull(initCallback,
+ "initCallback cannot be null")), loadState, null);
+ }
+
+ ListenerDispatcher(@NonNull final Collection<InitCallback> initCallbacks,
+ @LoadState final int loadState) {
+ this(initCallbacks, loadState, null);
+ }
+
+ ListenerDispatcher(@NonNull final Collection<InitCallback> initCallbacks,
+ @LoadState final int loadState,
+ @Nullable final Throwable throwable) {
+ Preconditions.checkNotNull(initCallbacks, "initCallbacks cannot be null");
+ mInitCallbacks = new ArrayList<>(initCallbacks);
+ mLoadState = loadState;
+ mThrowable = throwable;
+ }
+
+ @Override
+ public void run() {
+ final int size = mInitCallbacks.size();
+ switch (mLoadState) {
+ case LOAD_STATE_SUCCESS:
+ for (int i = 0; i < size; i++) {
+ mInitCallbacks.get(i).onInitialized();
+ }
+ break;
+ case LOAD_STATE_FAIL:
+ default:
+ for (int i = 0; i < size; i++) {
+ mInitCallbacks.get(i).onFailed(mThrowable);
+ }
+ break;
+ }
+ }
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/EmojiMetadata.java b/emoji/core/src/android/support/text/emoji/EmojiMetadata.java
new file mode 100644
index 0000000..cdc916d
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/EmojiMetadata.java
@@ -0,0 +1,206 @@
+/*
+ * 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.text.emoji;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.support.annotation.AnyThread;
+import android.support.annotation.IntDef;
+import android.support.annotation.IntRange;
+import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
+import android.support.text.emoji.flatbuffer.MetadataItem;
+import android.support.text.emoji.flatbuffer.MetadataList;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Information about a single emoji.
+ *
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+@AnyThread
+public class EmojiMetadata {
+ /**
+ * Defines whether the system can render the emoji.
+ */
+ @IntDef({HAS_GLYPH_UNKNOWN, HAS_GLYPH_ABSENT, HAS_GLYPH_EXISTS})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface HasGlyph {
+ }
+
+ /**
+ * Not calculated on device yet.
+ */
+ public static final int HAS_GLYPH_UNKNOWN = 0;
+
+ /**
+ * Device cannot render the emoji.
+ */
+ public static final int HAS_GLYPH_ABSENT = 1;
+
+ /**
+ * Device can render the emoji.
+ */
+ public static final int HAS_GLYPH_EXISTS = 2;
+
+ /**
+ * @see #getMetadataItem()
+ */
+ private static final ThreadLocal<MetadataItem> sMetadataItem = new ThreadLocal<>();
+
+ /**
+ * Index of the EmojiMetadata in {@link MetadataList}.
+ */
+ private final int mIndex;
+
+ /**
+ * MetadataRepo that holds this instance.
+ */
+ private final MetadataRepo mMetadataRepo;
+
+ /**
+ * Whether the system can render the emoji. Calculated at runtime on the device.
+ */
+ @HasGlyph
+ private volatile int mHasGlyph = HAS_GLYPH_UNKNOWN;
+
+ EmojiMetadata(@NonNull final MetadataRepo metadataRepo, @IntRange(from = 0) final int index) {
+ mMetadataRepo = metadataRepo;
+ mIndex = index;
+ }
+
+ /**
+ * Draws the emoji represented by this EmojiMetadata onto a canvas with origin at (x,y), using
+ * the specified paint.
+ *
+ * @param canvas Canvas to be drawn
+ * @param x x-coordinate of the origin of the emoji being drawn
+ * @param y y-coordinate of the baseline of the emoji being drawn
+ * @param paint Paint used for the text (e.g. color, size, style)
+ */
+ public void draw(@NonNull final Canvas canvas, final float x, final float y,
+ @NonNull final Paint paint) {
+ // MetadataRepo.getEmojiCharArray() is a continous array of chars that is used to store the
+ // chars for emojis. since all emojis are mapped to a single codepoint, and since it is 2
+ // chars wide, we assume that the start index of the current emoji is mIndex * 2, and it is
+ // 2 chars long.
+ final int charArrayStartIndex = mIndex * 2;
+ canvas.drawText(mMetadataRepo.getEmojiCharArray(), charArrayStartIndex, 2, x, y, paint);
+ }
+
+ /**
+ * @return a ThreadLocal instance of MetadataItem for this EmojiMetadata
+ */
+ private MetadataItem getMetadataItem() {
+ MetadataItem result = sMetadataItem.get();
+ if (result == null) {
+ result = new MetadataItem();
+ sMetadataItem.set(result);
+ }
+ // MetadataList is a wrapper around the metadata ByteBuffer. MetadataItem is a wrapper with
+ // an index (pointer) on this ByteBuffer that represents a single emoji. Both are FlatBuffer
+ // classes that wraps a ByteBuffer and gives access to the information in it. In order not
+ // to create a wrapper class for each EmojiMetadata, we use mIndex as the index of the
+ // MetadataItem in the ByteBuffer. We need to reiniitalize the current thread local instance
+ // by executing the statement below. All the statement does is to set an int index in
+ // MetadataItem. the same instance is used by all EmojiMetadata classes in the same thread.
+ mMetadataRepo.getMetadataList().list(result, mIndex);
+ return result;
+ }
+
+ /**
+ * @return unique id for the emoji
+ */
+ public int getId() {
+ return getMetadataItem().id();
+ }
+
+ /**
+ * @return width of the emoji image
+ */
+ public short getWidth() {
+ return getMetadataItem().width();
+ }
+
+ /**
+ * @return height of the emoji image
+ */
+ public short getHeight() {
+ return getMetadataItem().height();
+ }
+
+ /**
+ * @return in which metadata version the emoji was added to metadata
+ */
+ public short getCompatAdded() {
+ return getMetadataItem().compatAdded();
+ }
+
+ /**
+ * @return first SDK that the support for this emoji was added
+ */
+ public short getSdkAdded() {
+ return getMetadataItem().sdkAdded();
+ }
+
+ /**
+ * @return whether the emoji is in Emoji Presentation by default (without emoji
+ * style selector 0xFE0F)
+ */
+ @HasGlyph
+ public int getHasGlyph() {
+ return mHasGlyph;
+ }
+
+ /**
+ * Set whether the system can render the emoji.
+ *
+ * @param hasGlyph {@code true} if system can render the emoji
+ */
+ public void setHasGlyph(boolean hasGlyph) {
+ mHasGlyph = hasGlyph ? HAS_GLYPH_EXISTS : HAS_GLYPH_ABSENT;
+ }
+
+ /**
+ * @return whether the emoji is in Emoji Presentation by default (without emoji
+ * style selector 0xFE0F)
+ */
+ public boolean isDefaultEmoji() {
+ return getMetadataItem().emojiStyle();
+ }
+
+ /**
+ * @param index index of the codepoint
+ *
+ * @return the codepoint at index
+ */
+ public int getCodepointAt(int index) {
+ return getMetadataItem().codepoints(index);
+ }
+
+ /**
+ * @return the length of the codepoints for this emoji
+ */
+ public int getCodepointsLength() {
+ return getMetadataItem().codepointsLength();
+ }
+
+}
diff --git a/emoji/core/src/android/support/text/emoji/EmojiProcessor.java b/emoji/core/src/android/support/text/emoji/EmojiProcessor.java
new file mode 100644
index 0000000..9712b80
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/EmojiProcessor.java
@@ -0,0 +1,757 @@
+/*
+ * 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.text.emoji;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.os.Build;
+import android.support.annotation.AnyThread;
+import android.support.annotation.IntDef;
+import android.support.annotation.IntRange;
+import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
+import android.support.text.emoji.widget.SpannableBuilder;
+import android.support.v4.graphics.PaintCompat;
+import android.support.v4.util.Preconditions;
+import android.text.Editable;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.TextPaint;
+import android.text.method.KeyListener;
+import android.text.method.MetaKeyKeyListener;
+import android.view.KeyEvent;
+import android.view.inputmethod.InputConnection;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Processes the CharSequence and adds the emojis.
+ *
+ * @hide
+ */
+@AnyThread
+@RestrictTo(LIBRARY_GROUP)
+final class EmojiProcessor {
+
+ /**
+ * State transition commands.
+ */
+ @IntDef({ACTION_ADVANCE_BOTH, ACTION_ADVANCE_END, ACTION_FLUSH})
+ @Retention(RetentionPolicy.SOURCE)
+ @interface Action {
+ }
+
+ /**
+ * Advance the end pointer in CharSequence and reset the start to be the end.
+ */
+ private static final int ACTION_ADVANCE_BOTH = 1;
+
+ /**
+ * Advance end pointer in CharSequence.
+ */
+ private static final int ACTION_ADVANCE_END = 2;
+
+ /**
+ * Add a new emoji with the metadata in {@link ProcessorSm#getFlushMetadata()}. Advance end
+ * pointer in CharSequence and reset the start to be the end.
+ */
+ private static final int ACTION_FLUSH = 3;
+
+ /**
+ * Default text size for {@link #mTextPaint}.
+ */
+ private static final int PAINT_TEXT_SIZE = 10;
+
+ /**
+ * Used to create strings required by
+ * {@link PaintCompat#hasGlyph(android.graphics.Paint, String)}.
+ */
+ private static final ThreadLocal<StringBuilder> sStringBuilder = new ThreadLocal<>();
+
+ /**
+ * Factory used to create EmojiSpans.
+ */
+ private final EmojiCompat.SpanFactory mSpanFactory;
+
+ /**
+ * @see EmojiCompat.Config#setMaxEmojiPerText(int)
+ */
+ private final int mMaxEmojiPerText;
+
+ /**
+ * @see EmojiCompat.Config#setReplaceAll(boolean)
+ */
+ private final boolean mReplaceAll;
+
+ /**
+ * Emoji metadata repository.
+ */
+ private final MetadataRepo mMetadataRepo;
+
+ /**
+ * TextPaint used during {@link PaintCompat#hasGlyph(android.graphics.Paint, String)} check.
+ */
+ private final TextPaint mTextPaint;
+
+ EmojiProcessor(@NonNull final MetadataRepo metadataRepo,
+ @NonNull final EmojiCompat.SpanFactory spanFactory,
+ final boolean replaceAll, @IntRange(from = 0) final int maxEmojiPerText) {
+ mSpanFactory = spanFactory;
+ mMaxEmojiPerText = maxEmojiPerText;
+ mMetadataRepo = metadataRepo;
+ mReplaceAll = replaceAll;
+ mTextPaint = new TextPaint();
+ mTextPaint.setTextSize(PAINT_TEXT_SIZE);
+ }
+
+ EmojiMetadata getEmojiMetadata(@NonNull final CharSequence charSequence) {
+ final ProcessorSm sm = new ProcessorSm(mMetadataRepo.getRootNode());
+ final int end = charSequence.length();
+ int currentOffset = 0;
+
+ while (currentOffset < end) {
+ final int codePoint = Character.codePointAt(charSequence, currentOffset);
+ final int action = sm.check(codePoint);
+ if (action != ACTION_ADVANCE_END) {
+ return null;
+ }
+ currentOffset += Character.charCount(codePoint);
+ }
+
+ if (sm.isInFlushableState()) {
+ return sm.getCurrentMetadata();
+ }
+
+ return null;
+ }
+
+ /**
+ * Checks a given CharSequence for emojis, and adds EmojiSpans if any emojis are found.
+ * <p>
+ * <ul>
+ * <li>If no emojis are found, {@code charSequence} given as the input is returned without
+ * any changes. i.e. charSequence is a String, and no emojis are found, the same String is
+ * returned.</li>
+ * <li>If the given input is not a Spannable (such as String), and at least one emoji is found
+ * a new {@link android.text.Spannable} instance is returned. </li>
+ * <li>If the given input is a Spannable, the same instance is returned. </li>
+ * </ul>
+ *
+ * @param charSequence CharSequence to add the EmojiSpans, cannot be {@code null}
+ * @param start start index in the charSequence to look for emojis, should be greater than or
+ * equal to {@code 0}, also less than {@code charSequence.length()}
+ * @param end end index in the charSequence to look for emojis, should be greater than or
+ * equal to {@code start} parameter, also less than {@code charSequence.length()}
+ *
+ */
+ CharSequence process(@NonNull final CharSequence charSequence, @IntRange(from = 0) int start,
+ @IntRange(from = 0) int end) {
+ Preconditions.checkArgumentNonnegative(start, "start cannot be negative");
+ Preconditions.checkArgumentNonnegative(end, "end cannot be negative");
+ Preconditions.checkArgument(start <= end, "start should be <= than end");
+
+ // early return since there is nothing to do
+ if (charSequence == null) {
+ return charSequence;
+ }
+
+ Preconditions.checkArgument(start <= charSequence.length(),
+ "start should be < than charSequence length");
+ Preconditions.checkArgument(end <= charSequence.length(),
+ "end should be < than charSequence length");
+
+ // early return since there is nothing to do
+ if (charSequence.length() == 0 || start == end) {
+ return charSequence;
+ }
+
+ final boolean isSpannableBuilder = charSequence instanceof SpannableBuilder;
+ if (isSpannableBuilder) {
+ ((SpannableBuilder) charSequence).beginBatchEdit();
+ }
+
+ try {
+ Spannable spannable = null;
+ // if it is a spannable already, use the same instance to add/remove EmojiSpans.
+ // otherwise wait until the the first EmojiSpan found in order to change the result
+ // into a Spannable.
+ if (isSpannableBuilder || charSequence instanceof Spannable) {
+ spannable = (Spannable) charSequence;
+ }
+
+ if (spannable != null) {
+ final EmojiSpan[] spans = spannable.getSpans(start, end, EmojiSpan.class);
+ if (spans != null && spans.length > 0) {
+ // remove existing spans, and realign the start, end according to spans
+ // if start or end is in the middle of an emoji they should be aligned
+ final int length = spans.length;
+ for (int index = 0; index < length; index++) {
+ final EmojiSpan span = spans[index];
+ final int spanStart = spannable.getSpanStart(span);
+ final int spanEnd = spannable.getSpanEnd(span);
+ // Remove span only when its spanStart is NOT equal to current end.
+ // During add operation an emoji at index 0 is added with 0-1 as start and
+ // end indices. Therefore if there are emoji spans at [0-1] and [1-2]
+ // and end is 1, the span between 0-1 should be deleted, not 1-2.
+ if (spanStart != end) {
+ spannable.removeSpan(span);
+ }
+ start = Math.min(spanStart, start);
+ end = Math.max(spanEnd, end);
+ }
+ }
+ }
+
+ if (start == end || start >= charSequence.length()) {
+ return charSequence;
+ }
+
+ // add new ones
+ int addedCount = 0;
+ final ProcessorSm sm = new ProcessorSm(mMetadataRepo.getRootNode());
+
+ int currentOffset = start;
+ int codePoint = Character.codePointAt(charSequence, currentOffset);
+
+ while (currentOffset < end && addedCount < mMaxEmojiPerText) {
+ final int action = sm.check(codePoint);
+
+ switch (action) {
+ case ACTION_ADVANCE_BOTH:
+ currentOffset += Character.charCount(codePoint);
+ start = currentOffset;
+ if (currentOffset < end) {
+ codePoint = Character.codePointAt(charSequence, currentOffset);
+ }
+ break;
+ case ACTION_ADVANCE_END:
+ currentOffset += Character.charCount(codePoint);
+ if (currentOffset < end) {
+ codePoint = Character.codePointAt(charSequence, currentOffset);
+ }
+ break;
+ case ACTION_FLUSH:
+ if (mReplaceAll || !hasGlyph(charSequence, start, currentOffset,
+ sm.getFlushMetadata())) {
+ if (spannable == null) {
+ spannable = new SpannableString(charSequence);
+ }
+ addEmoji(spannable, sm.getFlushMetadata(), start, currentOffset);
+ addedCount++;
+ }
+ start = currentOffset;
+ break;
+ }
+ }
+
+ // After the last codepoint is consumed the state machine might be in a state where it
+ // identified an emoji before. i.e. abc[women-emoji] when the last codepoint is consumed
+ // state machine is waiting to see if there is an emoji sequence (i.e. ZWJ).
+ // Need to check if it is in such a state.
+ if (sm.isInFlushableState() && addedCount < mMaxEmojiPerText) {
+ if (mReplaceAll || !hasGlyph(charSequence, start, currentOffset,
+ sm.getCurrentMetadata())) {
+ if (spannable == null) {
+ spannable = new SpannableString(charSequence);
+ }
+ addEmoji(spannable, sm.getCurrentMetadata(), start, currentOffset);
+ addedCount++;
+ }
+ }
+ return spannable == null ? charSequence : spannable;
+ } finally {
+ if (isSpannableBuilder) {
+ ((SpannableBuilder) charSequence).endBatchEdit();
+ }
+ }
+ }
+
+ /**
+ * Handles onKeyDown commands from a {@link KeyListener} and if {@code keyCode} is one of
+ * {@link KeyEvent#KEYCODE_DEL} or {@link KeyEvent#KEYCODE_FORWARD_DEL} it tries to delete an
+ * {@link EmojiSpan} from an {@link Editable}. Returns {@code true} if an {@link EmojiSpan} is
+ * deleted with the characters it covers.
+ * <p/>
+ * If there is a selection where selection start is not equal to selection end, does not
+ * delete.
+ *
+ * @param editable Editable instance passed to {@link KeyListener#onKeyDown(android.view.View,
+ * Editable, int, KeyEvent)}
+ * @param keyCode keyCode passed to {@link KeyListener#onKeyDown(android.view.View, Editable,
+ * int, KeyEvent)}
+ * @param event KeyEvent passed to {@link KeyListener#onKeyDown(android.view.View, Editable,
+ * int, KeyEvent)}
+ *
+ * @return {@code true} if an {@link EmojiSpan} is deleted
+ */
+ static boolean handleOnKeyDown(@NonNull final Editable editable, final int keyCode,
+ final KeyEvent event) {
+ final boolean handled;
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DEL:
+ handled = delete(editable, event, false /*forwardDelete*/);
+ break;
+ case KeyEvent.KEYCODE_FORWARD_DEL:
+ handled = delete(editable, event, true /*forwardDelete*/);
+ break;
+ default:
+ handled = false;
+ break;
+ }
+
+ if (handled) {
+ MetaKeyKeyListener.adjustMetaAfterKeypress(editable);
+ return true;
+ }
+
+ return false;
+ }
+
+ private static boolean delete(final Editable content, final KeyEvent event,
+ final boolean forwardDelete) {
+ if (hasModifiers(event)) {
+ return false;
+ }
+
+ final int start = Selection.getSelectionStart(content);
+ final int end = Selection.getSelectionEnd(content);
+ if (hasInvalidSelection(start, end)) {
+ return false;
+ }
+
+ final EmojiSpan[] spans = content.getSpans(start, end, EmojiSpan.class);
+ if (spans != null && spans.length > 0) {
+ final int length = spans.length;
+ for (int index = 0; index < length; index++) {
+ final EmojiSpan span = spans[index];
+ final int spanStart = content.getSpanStart(span);
+ final int spanEnd = content.getSpanEnd(span);
+ if ((forwardDelete && spanStart == start)
+ || (!forwardDelete && spanEnd == start)
+ || (start > spanStart && start < spanEnd)) {
+ content.delete(spanStart, spanEnd);
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Handles deleteSurroundingText commands from {@link InputConnection} and tries to delete an
+ * {@link EmojiSpan} from an {@link Editable}. Returns {@code true} if an {@link EmojiSpan} is
+ * deleted.
+ * <p/>
+ * If there is a selection where selection start is not equal to selection end, does not
+ * delete.
+ *
+ * @param inputConnection InputConnection instance
+ * @param editable TextView.Editable instance
+ * @param beforeLength the number of characters before the cursor to be deleted
+ * @param afterLength the number of characters after the cursor to be deleted
+ * @param inCodePoints {@code true} if length parameters are in codepoints
+ *
+ * @return {@code true} if an {@link EmojiSpan} is deleted
+ */
+ static boolean handleDeleteSurroundingText(@NonNull final InputConnection inputConnection,
+ @NonNull final Editable editable, @IntRange(from = 0) final int beforeLength,
+ @IntRange(from = 0) final int afterLength, final boolean inCodePoints) {
+ if (editable == null || inputConnection == null) {
+ return false;
+ }
+
+ if (beforeLength < 0 || afterLength < 0) {
+ return false;
+ }
+
+ final int selectionStart = Selection.getSelectionStart(editable);
+ final int selectionEnd = Selection.getSelectionEnd(editable);
+
+ if (hasInvalidSelection(selectionStart, selectionEnd)) {
+ return false;
+ }
+
+ int start;
+ int end;
+ if (inCodePoints) {
+ // go backwards in terms of codepoints
+ start = CodepointIndexFinder.findIndexBackward(editable, selectionStart,
+ Math.max(beforeLength, 0));
+ end = CodepointIndexFinder.findIndexForward(editable, selectionEnd,
+ Math.max(afterLength, 0));
+
+ if (start == CodepointIndexFinder.INVALID_INDEX
+ || end == CodepointIndexFinder.INVALID_INDEX) {
+ return false;
+ }
+ } else {
+ start = Math.max(selectionStart - beforeLength, 0);
+ end = Math.min(selectionEnd + afterLength, editable.length());
+ }
+
+ final EmojiSpan[] spans = editable.getSpans(start, end, EmojiSpan.class);
+ if (spans != null && spans.length > 0) {
+ final int length = spans.length;
+ for (int index = 0; index < length; index++) {
+ final EmojiSpan span = spans[index];
+ int spanStart = editable.getSpanStart(span);
+ int spanEnd = editable.getSpanEnd(span);
+ start = Math.min(spanStart, start);
+ end = Math.max(spanEnd, end);
+ }
+
+ start = Math.max(start, 0);
+ end = Math.min(end, editable.length());
+
+ inputConnection.beginBatchEdit();
+ editable.delete(start, end);
+ inputConnection.endBatchEdit();
+ return true;
+ }
+
+ return false;
+ }
+
+ private static boolean hasInvalidSelection(final int start, final int end) {
+ return start == -1 || end == -1 || start != end;
+ }
+
+ private static boolean hasModifiers(KeyEvent event) {
+ return !KeyEvent.metaStateHasNoModifiers(event.getMetaState());
+ }
+
+ private void addEmoji(@NonNull final Spannable spannable, final EmojiMetadata metadata,
+ final int start, final int end) {
+ final EmojiSpan span = mSpanFactory.createSpan(metadata);
+ spannable.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+
+ /**
+ * Checks whether the current OS can render a given emoji. Used by the system to decide if an
+ * emoji span should be added. If the system cannot render it, an emoji span will be added.
+ * Used only for the case where replaceAll is set to {@code false}.
+ *
+ * @param charSequence the CharSequence that the emoji is in
+ * @param start start index of the emoji in the CharSequence
+ * @param end end index of the emoji in the CharSequence
+ * @param metadata EmojiMetadata instance for the emoji
+ *
+ * @return {@code true} if the OS can render emoji, {@code false} otherwise
+ */
+ private boolean hasGlyph(final CharSequence charSequence, int start, final int end,
+ final EmojiMetadata metadata) {
+ // if the emoji was added to OS at a later version we know that the system cannot render it.
+ // without this check pre M devices result in more false positives.
+ if (metadata.getSdkAdded() > Build.VERSION.SDK_INT) {
+ return false;
+ }
+
+ // if the existence is not calculated yet
+ if (metadata.getHasGlyph() == EmojiMetadata.HAS_GLYPH_UNKNOWN) {
+ final StringBuilder builder = getStringBuilder();
+ builder.setLength(0);
+
+ while (start < end) {
+ builder.append(charSequence.charAt(start));
+ start++;
+ }
+
+ final boolean hasGlyph = PaintCompat.hasGlyph(mTextPaint, builder.toString());
+ metadata.setHasGlyph(hasGlyph);
+ }
+
+ return metadata.getHasGlyph() == EmojiMetadata.HAS_GLYPH_EXISTS;
+ }
+
+ private static StringBuilder getStringBuilder() {
+ if (sStringBuilder.get() == null) {
+ sStringBuilder.set(new StringBuilder());
+ }
+ return sStringBuilder.get();
+ }
+
+ /**
+ * State machine for walking over the metadata trie.
+ */
+ static final class ProcessorSm {
+
+ private static final int STATE_DEFAULT = 1;
+ private static final int STATE_WALKING = 2;
+
+ private int mState = STATE_DEFAULT;
+
+ /**
+ * Root of the trie
+ */
+ private final MetadataRepo.Node mRootNode;
+
+ /**
+ * Pointer to the node after last codepoint.
+ */
+ private MetadataRepo.Node mCurrentNode;
+
+ /**
+ * The node where ACTION_FLUSH is called. Required since after flush action is
+ * returned mCurrentNode is reset to be the root.
+ */
+ private MetadataRepo.Node mFlushNode;
+
+ /**
+ * The code point that was checked.
+ */
+ private int mLastCodepoint;
+
+ /**
+ * Level for mCurrentNode. Root is 0.
+ */
+ private int mCurrentDepth;
+
+ ProcessorSm(MetadataRepo.Node rootNode) {
+ mRootNode = rootNode;
+ mCurrentNode = rootNode;
+ }
+
+ @Action
+ int check(final int codePoint) {
+ final int action;
+ MetadataRepo.Node node = mCurrentNode.get(codePoint);
+ switch (mState) {
+ case STATE_WALKING:
+ if (node != null) {
+ mCurrentNode = node;
+ mCurrentDepth += 1;
+ action = ACTION_ADVANCE_END;
+ } else {
+ if (isTextStyle(codePoint)) {
+ action = reset();
+ } else if (isEmojiStyle(codePoint)) {
+ action = ACTION_ADVANCE_END;
+ } else if (mCurrentNode.getData() != null) {
+ if (mCurrentDepth == 1) {
+ if (mCurrentNode.getData().isDefaultEmoji()
+ || isEmojiStyle(mLastCodepoint)) {
+ mFlushNode = mCurrentNode;
+ action = ACTION_FLUSH;
+ reset();
+ } else {
+ action = reset();
+ }
+ } else {
+ mFlushNode = mCurrentNode;
+ action = ACTION_FLUSH;
+ reset();
+ }
+ } else {
+ action = reset();
+ }
+ }
+ break;
+ case STATE_DEFAULT:
+ default:
+ if (node == null) {
+ action = reset();
+ } else {
+ mState = STATE_WALKING;
+ mCurrentNode = node;
+ mCurrentDepth = 1;
+ action = ACTION_ADVANCE_END;
+ }
+ break;
+ }
+
+ mLastCodepoint = codePoint;
+ return action;
+ }
+
+ @Action
+ private int reset() {
+ mState = STATE_DEFAULT;
+ mCurrentNode = mRootNode;
+ mCurrentDepth = 0;
+ return ACTION_ADVANCE_BOTH;
+ }
+
+ /**
+ * @return the metadata node when ACTION_FLUSH is returned
+ */
+ EmojiMetadata getFlushMetadata() {
+ return mFlushNode.getData();
+ }
+
+ /**
+ * @return current pointer to the metadata node in the trie
+ */
+ EmojiMetadata getCurrentMetadata() {
+ return mCurrentNode.getData();
+ }
+
+ /**
+ * Need for the case where input is consumed, but action_flush was not called. For example
+ * when the char sequence has single codepoint character which is a default emoji. State
+ * machine will wait for the next.
+ *
+ * @return whether the current state requires an emoji to be added
+ */
+ boolean isInFlushableState() {
+ return mState == STATE_WALKING && mCurrentNode.getData() != null
+ && (mCurrentNode.getData().isDefaultEmoji()
+ || isEmojiStyle(mLastCodepoint)
+ || mCurrentDepth > 1);
+ }
+
+ /**
+ * @param codePoint CodePoint to check
+ *
+ * @return {@code true} if the codepoint is a emoji style standardized variation selector
+ */
+ private static boolean isEmojiStyle(int codePoint) {
+ return codePoint == 0xFE0F;
+ }
+
+ /**
+ * @param codePoint CodePoint to check
+ *
+ * @return {@code true} if the codepoint is a text style standardized variation selector
+ */
+ private static boolean isTextStyle(int codePoint) {
+ return codePoint == 0xFE0E;
+ }
+ }
+
+ /**
+ * Copy of BaseInputConnection findIndexBackward and findIndexForward functions.
+ */
+ private static final class CodepointIndexFinder {
+ private static final int INVALID_INDEX = -1;
+
+ /**
+ * Find start index of the character in {@code cs} that is {@code numCodePoints} behind
+ * starting from {@code from}.
+ *
+ * @param cs CharSequence to work on
+ * @param from the index to start going backwards
+ * @param numCodePoints the number of codepoints
+ *
+ * @return start index of the character
+ */
+ private static int findIndexBackward(final CharSequence cs, final int from,
+ final int numCodePoints) {
+ int currentIndex = from;
+ boolean waitingHighSurrogate = false;
+ final int length = cs.length();
+ if (currentIndex < 0 || length < currentIndex) {
+ return INVALID_INDEX; // The starting point is out of range.
+ }
+ if (numCodePoints < 0) {
+ return INVALID_INDEX; // Basically this should not happen.
+ }
+ int remainingCodePoints = numCodePoints;
+ while (true) {
+ if (remainingCodePoints == 0) {
+ return currentIndex; // Reached to the requested length in code points.
+ }
+
+ --currentIndex;
+ if (currentIndex < 0) {
+ if (waitingHighSurrogate) {
+ return INVALID_INDEX; // An invalid surrogate pair is found.
+ }
+ return 0; // Reached to the beginning of the text w/o any invalid surrogate
+ // pair.
+ }
+ final char c = cs.charAt(currentIndex);
+ if (waitingHighSurrogate) {
+ if (!Character.isHighSurrogate(c)) {
+ return INVALID_INDEX; // An invalid surrogate pair is found.
+ }
+ waitingHighSurrogate = false;
+ --remainingCodePoints;
+ continue;
+ }
+ if (!Character.isSurrogate(c)) {
+ --remainingCodePoints;
+ continue;
+ }
+ if (Character.isHighSurrogate(c)) {
+ return INVALID_INDEX; // A invalid surrogate pair is found.
+ }
+ waitingHighSurrogate = true;
+ }
+ }
+
+ /**
+ * Find start index of the character in {@code cs} that is {@code numCodePoints} ahead
+ * starting from {@code from}.
+ *
+ * @param cs CharSequence to work on
+ * @param from the index to start going forward
+ * @param numCodePoints the number of codepoints
+ *
+ * @return start index of the character
+ */
+ private static int findIndexForward(final CharSequence cs, final int from,
+ final int numCodePoints) {
+ int currentIndex = from;
+ boolean waitingLowSurrogate = false;
+ final int length = cs.length();
+ if (currentIndex < 0 || length < currentIndex) {
+ return INVALID_INDEX; // The starting point is out of range.
+ }
+ if (numCodePoints < 0) {
+ return INVALID_INDEX; // Basically this should not happen.
+ }
+ int remainingCodePoints = numCodePoints;
+
+ while (true) {
+ if (remainingCodePoints == 0) {
+ return currentIndex; // Reached to the requested length in code points.
+ }
+
+ if (currentIndex >= length) {
+ if (waitingLowSurrogate) {
+ return INVALID_INDEX; // An invalid surrogate pair is found.
+ }
+ return length; // Reached to the end of the text w/o any invalid surrogate
+ // pair.
+ }
+ final char c = cs.charAt(currentIndex);
+ if (waitingLowSurrogate) {
+ if (!Character.isLowSurrogate(c)) {
+ return INVALID_INDEX; // An invalid surrogate pair is found.
+ }
+ --remainingCodePoints;
+ waitingLowSurrogate = false;
+ ++currentIndex;
+ continue;
+ }
+ if (!Character.isSurrogate(c)) {
+ --remainingCodePoints;
+ ++currentIndex;
+ continue;
+ }
+ if (Character.isLowSurrogate(c)) {
+ return INVALID_INDEX; // A invalid surrogate pair is found.
+ }
+ waitingLowSurrogate = true;
+ ++currentIndex;
+ }
+ }
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/EmojiSpan.java b/emoji/core/src/android/support/text/emoji/EmojiSpan.java
new file mode 100644
index 0000000..2510e2c
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/EmojiSpan.java
@@ -0,0 +1,139 @@
+/*
+ * 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.text.emoji;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.graphics.Paint;
+import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
+import android.support.annotation.VisibleForTesting;
+import android.support.v4.util.Preconditions;
+import android.text.style.ReplacementSpan;
+
+/**
+ * Base span class for the emoji replacement. When an emoji is found and needs to be replaced in a
+ * CharSequence, an instance of this class is added to the CharSequence.
+ */
+public abstract class EmojiSpan extends ReplacementSpan {
+
+ /**
+ * Temporary object to calculate the size of the span.
+ */
+ private final Paint.FontMetricsInt mTmpFontMetrics = new Paint.FontMetricsInt();
+
+ /**
+ * Information about emoji. This is not parcelled since we do not want multiple objects
+ * representing same emoji to be in memory. When unparcelled, EmojiSpan tries to set it back
+ * using the singleton EmojiCompat instance.
+ */
+ private final EmojiMetadata mMetadata;
+
+ /**
+ * Cached width of the span. Width is calculated according to the font metrics.
+ */
+ private short mWidth = -1;
+
+ /**
+ * Cached height of the span. Height is calculated according to the font metrics.
+ */
+ private short mHeight = -1;
+
+ /**
+ * Cached ratio of current font height to emoji image height.
+ */
+ private float mRatio = 1.0f;
+
+ /**
+ * Default constructor.
+ *
+ * @param metadata information about the emoji, cannot be {@code null}
+ *
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ EmojiSpan(@NonNull final EmojiMetadata metadata) {
+ Preconditions.checkNotNull(metadata, "metadata cannot be null");
+ mMetadata = metadata;
+ }
+
+ @Override
+ public int getSize(@NonNull final Paint paint, final CharSequence text, final int start,
+ final int end, final Paint.FontMetricsInt fm) {
+ paint.getFontMetricsInt(mTmpFontMetrics);
+ final int fontHeight = Math.abs(mTmpFontMetrics.descent - mTmpFontMetrics.ascent);
+
+ mRatio = fontHeight * 1.0f / mMetadata.getHeight();
+ mHeight = (short) (mMetadata.getHeight() * mRatio);
+ mWidth = (short) (mMetadata.getWidth() * mRatio);
+
+ if (fm != null) {
+ fm.ascent = mTmpFontMetrics.ascent;
+ fm.descent = mTmpFontMetrics.descent;
+ fm.top = mTmpFontMetrics.top;
+ fm.bottom = mTmpFontMetrics.bottom;
+ }
+
+ return mWidth;
+ }
+
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ final EmojiMetadata getMetadata() {
+ return mMetadata;
+ }
+
+ /**
+ * @return width of the span
+ *
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ final int getWidth() {
+ return mWidth;
+ }
+
+ /**
+ * @return height of the span
+ *
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ final int getHeight() {
+ return mHeight;
+ }
+
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ final float getRatio() {
+ return mRatio;
+ }
+
+ /**
+ * @return unique id for the emoji that this EmojiSpan is used for
+ *
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ @VisibleForTesting
+ public final int getId() {
+ return getMetadata().getId();
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/MetadataListReader.java b/emoji/core/src/android/support/text/emoji/MetadataListReader.java
new file mode 100644
index 0000000..364247b
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/MetadataListReader.java
@@ -0,0 +1,346 @@
+/*
+ * 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.text.emoji;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.content.res.AssetManager;
+import android.support.annotation.AnyThread;
+import android.support.annotation.IntRange;
+import android.support.annotation.RestrictTo;
+import android.support.text.emoji.flatbuffer.MetadataList;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Reads the emoji metadata from a given InputStream or ByteBuffer.
+ *
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+@AnyThread
+class MetadataListReader {
+
+ /**
+ * Meta tag for emoji metadata. This string is used by the font update script to insert the
+ * emoji meta into the font. This meta table contains the list of all emojis which are stored in
+ * binary format using FlatBuffers. This flat list is later converted by the system into a trie.
+ * {@code int} representation for "emji"
+ *
+ * @see MetadataRepo
+ */
+ private static final int EMJI_TAG = 0x656D6A69;
+
+ /**
+ * The name of the meta table in the font. int representation for "meta"
+ */
+ private static final int META_TABLE_NAME = 0x6D657461;
+
+ /**
+ * Construct MetadataList from an input stream. Does not close the given InputStream, therefore
+ * it is caller's responsibility to properly close the stream.
+ *
+ * @param inputStream InputStream to read emoji metadata from
+ */
+ static MetadataList read(InputStream inputStream) throws IOException {
+ final OpenTypeReader openTypeReader = new InputStreamOpenTypeReader(inputStream);
+ final OffsetInfo offsetInfo = findOffsetInfo(openTypeReader);
+ // skip to where metadata is
+ openTypeReader.skip((int) (offsetInfo.getStartOffset() - openTypeReader.getPosition()));
+ // allocate a ByteBuffer and read into it since FlatBuffers can read only from a ByteBuffer
+ final ByteBuffer buffer = ByteBuffer.allocate((int) offsetInfo.getLength());
+ final int numRead = inputStream.read(buffer.array());
+ if (numRead != offsetInfo.getLength()) {
+ throw new IOException("Needed " + offsetInfo.getLength() + " bytes, got " + numRead);
+ }
+
+ return MetadataList.getRootAsMetadataList(buffer);
+ }
+
+ /**
+ * Construct MetadataList from a byte buffer.
+ *
+ * @param byteBuffer ByteBuffer to read emoji metadata from
+ */
+ static MetadataList read(final ByteBuffer byteBuffer) throws IOException {
+ final ByteBuffer newBuffer = byteBuffer.duplicate();
+ final OpenTypeReader reader = new ByteBufferReader(newBuffer);
+ final OffsetInfo offsetInfo = findOffsetInfo(reader);
+ // skip to where metadata is
+ newBuffer.position((int) offsetInfo.getStartOffset());
+ return MetadataList.getRootAsMetadataList(newBuffer);
+ }
+
+ /**
+ * Construct MetadataList from an asset.
+ *
+ * @param assetManager AssetManager instance
+ * @param assetPath asset manager path of the file that the Typeface and metadata will be
+ * created from
+ */
+ static MetadataList read(AssetManager assetManager, String assetPath)
+ throws IOException {
+ InputStream inputStream = null;
+ try {
+ inputStream = assetManager.open(assetPath);
+ return read(inputStream);
+ } finally {
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ /**
+ * Finds the start offset and length of the emoji metadata in the font.
+ *
+ * @return OffsetInfo which contains start offset and length of the emoji metadata in the font
+ *
+ * @throws IOException
+ */
+ private static OffsetInfo findOffsetInfo(OpenTypeReader reader) throws IOException {
+ // skip sfnt version
+ reader.skip(OpenTypeReader.UINT32_BYTE_COUNT);
+ // start of Table Count
+ final int tableCount = reader.readUnsignedShort();
+ if (tableCount > 100) {
+ //something is wrong quit
+ throw new IOException("Cannot read metadata.");
+ }
+ //skip to begining of tables data
+ reader.skip(OpenTypeReader.UINT16_BYTE_COUNT * 3);
+
+ long metaOffset = -1;
+ for (int i = 0; i < tableCount; i++) {
+ final int tag = reader.readTag();
+ // skip checksum
+ reader.skip(OpenTypeReader.UINT32_BYTE_COUNT);
+ final long offset = reader.readUnsignedInt();
+ // skip mLength
+ reader.skip(OpenTypeReader.UINT32_BYTE_COUNT);
+ if (META_TABLE_NAME == tag) {
+ metaOffset = offset;
+ break;
+ }
+ }
+
+ if (metaOffset != -1) {
+ // skip to the begining of meta tables.
+ reader.skip((int) (metaOffset - reader.getPosition()));
+ // skip minorVersion, majorVersion, flags, reserved,
+ reader.skip(
+ OpenTypeReader.UINT16_BYTE_COUNT * 2 + OpenTypeReader.UINT32_BYTE_COUNT * 2);
+ final long mapsCount = reader.readUnsignedInt();
+ for (int i = 0; i < mapsCount; i++) {
+ final int tag = reader.readTag();
+ final long dataOffset = reader.readUnsignedInt();
+ final long dataLength = reader.readUnsignedInt();
+ if (EMJI_TAG == tag) {
+ return new OffsetInfo(dataOffset + metaOffset, dataLength);
+ }
+ }
+ }
+
+ throw new IOException("Cannot read metadata.");
+ }
+
+ /**
+ * Start offset and length of the emoji metadata in the font.
+ */
+ private static class OffsetInfo {
+ private final long mStartOffset;
+ private final long mLength;
+
+ OffsetInfo(long startOffset, long length) {
+ mStartOffset = startOffset;
+ mLength = length;
+ }
+
+ long getStartOffset() {
+ return mStartOffset;
+ }
+
+ long getLength() {
+ return mLength;
+ }
+ }
+
+ static final int toUnsignedShort(final short value) {
+ return value & 0xFFFF;
+ }
+
+ static final long toUnsignedInt(final int value) {
+ return value & 0xFFFFFFFFL;
+ }
+
+ private interface OpenTypeReader {
+ int UINT16_BYTE_COUNT = 2;
+ int UINT32_BYTE_COUNT = 4;
+
+ /**
+ * Reads an {@code OpenType uint16}.
+ *
+ * @throws IOException
+ */
+ int readUnsignedShort() throws IOException;
+
+ /**
+ * Reads an {@code OpenType uint32}.
+ *
+ * @throws IOException
+ */
+ long readUnsignedInt() throws IOException;
+
+ /**
+ * Reads an {@code OpenType Tag}.
+ *
+ * @throws IOException
+ */
+ int readTag() throws IOException;
+
+ /**
+ * Skip the given amount of numOfBytes
+ *
+ * @throws IOException
+ */
+ void skip(int numOfBytes) throws IOException;
+
+ /**
+ * @return the position of the reader
+ */
+ long getPosition();
+ }
+
+ /**
+ * Reads {@code OpenType} data from an {@link InputStream}.
+ */
+ private static class InputStreamOpenTypeReader implements OpenTypeReader {
+
+ private final byte[] mByteArray;
+ private final ByteBuffer mByteBuffer;
+ private final InputStream mInputStream;
+ private long mPosition = 0;
+
+ /**
+ * Constructs the reader with the given InputStream. Does not close the InputStream, it is
+ * caller's responsibility to close it.
+ *
+ * @param inputStream InputStream to read from
+ */
+ InputStreamOpenTypeReader(final InputStream inputStream) {
+ mInputStream = inputStream;
+ mByteArray = new byte[UINT32_BYTE_COUNT];
+ mByteBuffer = ByteBuffer.wrap(mByteArray);
+ mByteBuffer.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ @Override
+ public int readUnsignedShort() throws IOException {
+ mByteBuffer.position(0);
+ read(UINT16_BYTE_COUNT);
+ return toUnsignedShort(mByteBuffer.getShort());
+ }
+
+ @Override
+ public long readUnsignedInt() throws IOException {
+ mByteBuffer.position(0);
+ read(UINT32_BYTE_COUNT);
+ return toUnsignedInt(mByteBuffer.getInt());
+ }
+
+ @Override
+ public int readTag() throws IOException {
+ mByteBuffer.position(0);
+ read(UINT32_BYTE_COUNT);
+ return mByteBuffer.getInt();
+ }
+
+ @Override
+ public void skip(int numOfBytes) throws IOException {
+ while (numOfBytes > 0) {
+ long skipped = mInputStream.skip(numOfBytes);
+ if (skipped < 1) {
+ throw new IOException("Skip didn't move at least 1 byte forward");
+ }
+ numOfBytes -= skipped;
+ mPosition += skipped;
+ }
+ }
+
+ @Override
+ public long getPosition() {
+ return mPosition;
+ }
+
+ private void read(@IntRange(from = 0, to = UINT32_BYTE_COUNT) final int numOfBytes)
+ throws IOException {
+ if (mInputStream.read(mByteArray, 0, numOfBytes) != numOfBytes) {
+ throw new IOException("read failed");
+ }
+ mPosition += numOfBytes;
+ }
+ }
+
+ /**
+ * Reads OpenType data from a ByteBuffer.
+ */
+ private static class ByteBufferReader implements OpenTypeReader {
+
+ private final ByteBuffer mByteBuffer;
+
+ /**
+ * Constructs the reader with the given ByteBuffer.
+ *
+ * @param byteBuffer ByteBuffer to read from
+ */
+ ByteBufferReader(final ByteBuffer byteBuffer) {
+ mByteBuffer = byteBuffer;
+ mByteBuffer.order(ByteOrder.BIG_ENDIAN);
+ }
+
+ @Override
+ public int readUnsignedShort() throws IOException {
+ return toUnsignedShort(mByteBuffer.getShort());
+ }
+
+ @Override
+ public long readUnsignedInt() throws IOException {
+ return toUnsignedInt(mByteBuffer.getInt());
+ }
+
+ @Override
+ public int readTag() throws IOException {
+ return mByteBuffer.getInt();
+ }
+
+ @Override
+ public void skip(final int numOfBytes) throws IOException {
+ mByteBuffer.position(mByteBuffer.position() + numOfBytes);
+ }
+
+ @Override
+ public long getPosition() {
+ return mByteBuffer.position();
+ }
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/MetadataRepo.java b/emoji/core/src/android/support/text/emoji/MetadataRepo.java
new file mode 100644
index 0000000..f192f09
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/MetadataRepo.java
@@ -0,0 +1,239 @@
+/*
+ * 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.text.emoji;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.content.res.AssetManager;
+import android.graphics.Typeface;
+import android.support.annotation.AnyThread;
+import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
+import android.support.annotation.VisibleForTesting;
+import android.support.text.emoji.flatbuffer.MetadataList;
+import android.support.v4.util.Preconditions;
+import android.util.SparseArray;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+/**
+ * Class to hold the emoji metadata required to process and draw emojis.
+ */
+@AnyThread
+public final class MetadataRepo {
+ /**
+ * The default children size of the root node.
+ */
+ private static final int DEFAULT_ROOT_SIZE = 1024;
+
+ /**
+ * MetadataList that contains the emoji metadata.
+ */
+ private final MetadataList mMetadataList;
+
+ /**
+ * char presentation of all EmojiMetadata's in a single array.
+ */
+ private final char[] mEmojiCharArray;
+
+ /**
+ * Empty root node of the trie.
+ */
+ private final Node mRootNode;
+
+ /**
+ * Typeface to be used to render emojis.
+ */
+ private final Typeface mTypeface;
+
+ /**
+ * Constructor used for tests.
+ *
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ MetadataRepo() {
+ mTypeface = null;
+ mMetadataList = null;
+ mRootNode = new Node(DEFAULT_ROOT_SIZE);
+ mEmojiCharArray = new char[0];
+ }
+
+ /**
+ * Private constructor that is called by one of {@code create} methods.
+ *
+ * @param typeface Typeface to be used to render emojis
+ * @param metadataList MetadataList that contains the emoji metadata
+ */
+ private MetadataRepo(@NonNull final Typeface typeface,
+ @NonNull final MetadataList metadataList) {
+ mTypeface = typeface;
+ mMetadataList = metadataList;
+ mRootNode = new Node(DEFAULT_ROOT_SIZE);
+ mEmojiCharArray = new char[mMetadataList.listLength() * 2];
+ constructIndex(mMetadataList);
+ }
+
+ /**
+ * Construct MetadataRepo from an input stream. The library does not close the given
+ * InputStream, therefore it is caller's responsibility to properly close the stream.
+ *
+ * @param typeface Typeface to be used to render emojis
+ * @param inputStream InputStream to read emoji metadata from
+ */
+ public static MetadataRepo create(@NonNull final Typeface typeface,
+ @NonNull final InputStream inputStream) throws IOException {
+ return new MetadataRepo(typeface, MetadataListReader.read(inputStream));
+ }
+
+ /**
+ * Construct MetadataRepo from a byte buffer. The position of the ByteBuffer will change, it is
+ * caller's responsibility to reposition the buffer if required.
+ *
+ * @param typeface Typeface to be used to render emojis
+ * @param byteBuffer ByteBuffer to read emoji metadata from
+ */
+ public static MetadataRepo create(@NonNull final Typeface typeface,
+ @NonNull final ByteBuffer byteBuffer) throws IOException {
+ return new MetadataRepo(typeface, MetadataListReader.read(byteBuffer));
+ }
+
+ /**
+ * Construct MetadataRepo from an asset.
+ *
+ * @param assetManager AssetManager instance
+ * @param assetPath asset manager path of the file that the Typeface and metadata will be
+ * created from
+ */
+ public static MetadataRepo create(@NonNull final AssetManager assetManager,
+ final String assetPath) throws IOException {
+ final Typeface typeface = Typeface.createFromAsset(assetManager, assetPath);
+ return new MetadataRepo(typeface, MetadataListReader.read(assetManager, assetPath));
+ }
+
+ /**
+ * Read emoji metadata list and construct the trie.
+ */
+ private void constructIndex(final MetadataList metadataList) {
+ int length = metadataList.listLength();
+ for (int i = 0; i < length; i++) {
+ final EmojiMetadata metadata = new EmojiMetadata(this, i);
+ Character.toChars(metadata.getId(), mEmojiCharArray, i * 2);
+ put(metadata);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ Typeface getTypeface() {
+ return mTypeface;
+ }
+
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ int getMetadataVersion() {
+ return mMetadataList.version();
+ }
+
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ Node getRootNode() {
+ return mRootNode;
+ }
+
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ public char[] getEmojiCharArray() {
+ return mEmojiCharArray;
+ }
+
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ public MetadataList getMetadataList() {
+ return mMetadataList;
+ }
+
+ /**
+ * Add an EmojiMetadata to the index.
+ *
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ @VisibleForTesting
+ void put(@NonNull final EmojiMetadata data) {
+ Preconditions.checkNotNull(data, "emoji metadata cannot be null");
+ Preconditions.checkArgument(data.getCodepointsLength() > 0,
+ "invalid metadata codepoint length");
+
+ mRootNode.put(data, 0, data.getCodepointsLength() - 1);
+ }
+
+ /**
+ * Trie node that holds mapping from emoji codepoint(s) to EmojiMetadata. A single codepoint
+ * emoji is represented by a child of the root node.
+ *
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ static class Node {
+ private SparseArray<Node> mChildren;
+ private EmojiMetadata mData;
+
+ private Node() {
+ }
+
+ private Node(final int defaultChildrenSize) {
+ mChildren = new SparseArray<>(defaultChildrenSize);
+ }
+
+ Node get(final int key) {
+ return mChildren == null ? null : mChildren.get(key);
+ }
+
+ final EmojiMetadata getData() {
+ return mData;
+ }
+
+ private void put(@NonNull final EmojiMetadata data, final int start, final int end) {
+ Node node = get(data.getCodepointAt(start));
+ if (node == null) {
+ if (mChildren == null) {
+ mChildren = new SparseArray<>(1);
+ }
+ node = new Node();
+ mChildren.put(data.getCodepointAt(start), node);
+ }
+
+ if (end > start) {
+ node.put(data, start + 1, end);
+ } else {
+ node.mData = data;
+ }
+ }
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/TypefaceEmojiSpan.java b/emoji/core/src/android/support/text/emoji/TypefaceEmojiSpan.java
new file mode 100644
index 0000000..acc4784
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/TypefaceEmojiSpan.java
@@ -0,0 +1,53 @@
+/*
+ * 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.text.emoji;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Typeface;
+import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
+
+/**
+ * EmojiSpan subclass used to render emojis using Typeface.
+ *
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+public final class TypefaceEmojiSpan extends EmojiSpan {
+
+ /**
+ * Default constructor.
+ *
+ * @param metadata metadata representing the emoji that this span will draw
+ */
+ public TypefaceEmojiSpan(final EmojiMetadata metadata) {
+ super(metadata);
+ }
+
+ @Override
+ public void draw(@NonNull final Canvas canvas, final CharSequence text, final int start,
+ final int end, final float x, final int top, final int y, final int bottom,
+ @NonNull final Paint paint) {
+ final Typeface typeface = EmojiCompat.get().getTypeface();
+ final Typeface oldTypeface = paint.getTypeface();
+ paint.setTypeface(typeface);
+ getMetadata().draw(canvas, x, y, paint);
+ paint.setTypeface(oldTypeface);
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/flatbuffer/MetadataItem.java b/emoji/core/src/android/support/text/emoji/flatbuffer/MetadataItem.java
new file mode 100644
index 0000000..f0466ea
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/flatbuffer/MetadataItem.java
@@ -0,0 +1,166 @@
+// CHECKSTYLE:OFF Generated code
+/*
+ * 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.text.emoji.flatbuffer;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.support.annotation.RestrictTo;
+
+import com.google.flatbuffers.emojicompat.FlatBufferBuilder;
+import com.google.flatbuffers.emojicompat.Table;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Automatically generated by the FlatBuffers compiler, do not modify.
+ *
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+@SuppressWarnings("unused")
+public final class MetadataItem extends Table {
+ public static MetadataItem getRootAsMetadataItem(ByteBuffer _bb) {
+ return getRootAsMetadataItem(_bb, new MetadataItem());
+ }
+
+ public static MetadataItem getRootAsMetadataItem(ByteBuffer _bb, MetadataItem obj) {
+ _bb.order(ByteOrder.LITTLE_ENDIAN);
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb));
+ }
+
+ public void __init(int _i, ByteBuffer _bb) {
+ bb_pos = _i;
+ bb = _bb;
+ }
+
+ public MetadataItem __assign(int _i, ByteBuffer _bb) {
+ __init(_i, _bb);
+ return this;
+ }
+
+ public int id() {
+ int o = __offset(4);
+ return o != 0 ? bb.getInt(o + bb_pos) : 0;
+ }
+
+ public boolean emojiStyle() {
+ int o = __offset(6);
+ return o != 0 ? 0 != bb.get(o + bb_pos) : false;
+ }
+
+ public short sdkAdded() {
+ int o = __offset(8);
+ return o != 0 ? bb.getShort(o + bb_pos) : 0;
+ }
+
+ public short compatAdded() {
+ int o = __offset(10);
+ return o != 0 ? bb.getShort(o + bb_pos) : 0;
+ }
+
+ public short width() {
+ int o = __offset(12);
+ return o != 0 ? bb.getShort(o + bb_pos) : 0;
+ }
+
+ public short height() {
+ int o = __offset(14);
+ return o != 0 ? bb.getShort(o + bb_pos) : 0;
+ }
+
+ public int codepoints(int j) {
+ int o = __offset(16);
+ return o != 0 ? bb.getInt(__vector(o) + j * 4) : 0;
+ }
+
+ public int codepointsLength() {
+ int o = __offset(16);
+ return o != 0 ? __vector_len(o) : 0;
+ }
+
+ public ByteBuffer codepointsAsByteBuffer() {
+ return __vector_as_bytebuffer(16, 4);
+ }
+
+ public static int createMetadataItem(FlatBufferBuilder builder,
+ int id,
+ boolean emojiStyle,
+ short sdkAdded,
+ short compatAdded,
+ short width,
+ short height,
+ int codepointsOffset) {
+ builder.startObject(7);
+ MetadataItem.addCodepoints(builder, codepointsOffset);
+ MetadataItem.addId(builder, id);
+ MetadataItem.addHeight(builder, height);
+ MetadataItem.addWidth(builder, width);
+ MetadataItem.addCompatAdded(builder, compatAdded);
+ MetadataItem.addSdkAdded(builder, sdkAdded);
+ MetadataItem.addEmojiStyle(builder, emojiStyle);
+ return MetadataItem.endMetadataItem(builder);
+ }
+
+ public static void startMetadataItem(FlatBufferBuilder builder) {
+ builder.startObject(7);
+ }
+
+ public static void addId(FlatBufferBuilder builder, int id) {
+ builder.addInt(0, id, 0);
+ }
+
+ public static void addEmojiStyle(FlatBufferBuilder builder, boolean emojiStyle) {
+ builder.addBoolean(1, emojiStyle, false);
+ }
+
+ public static void addSdkAdded(FlatBufferBuilder builder, short sdkAdded) {
+ builder.addShort(2, sdkAdded, 0);
+ }
+
+ public static void addCompatAdded(FlatBufferBuilder builder, short compatAdded) {
+ builder.addShort(3, compatAdded, 0);
+ }
+
+ public static void addWidth(FlatBufferBuilder builder, short width) {
+ builder.addShort(4, width, 0);
+ }
+
+ public static void addHeight(FlatBufferBuilder builder, short height) {
+ builder.addShort(5, height, 0);
+ }
+
+ public static void addCodepoints(FlatBufferBuilder builder, int codepointsOffset) {
+ builder.addOffset(6, codepointsOffset, 0);
+ }
+
+ public static int createCodepointsVector(FlatBufferBuilder builder, int[] data) {
+ builder.startVector(4, data.length, 4);
+ for (int i = data.length - 1; i >= 0; i--) builder.addInt(data[i]);
+ return builder.endVector();
+ }
+
+ public static void startCodepointsVector(FlatBufferBuilder builder, int numElems) {
+ builder.startVector(4, numElems, 4);
+ }
+
+ public static int endMetadataItem(FlatBufferBuilder builder) {
+ int o = builder.endObject();
+ return o;
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/flatbuffer/MetadataList.java b/emoji/core/src/android/support/text/emoji/flatbuffer/MetadataList.java
new file mode 100644
index 0000000..4de07d7
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/flatbuffer/MetadataList.java
@@ -0,0 +1,115 @@
+// CHECKSTYLE:OFF Generated code
+/*
+ * 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.text.emoji.flatbuffer;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.support.annotation.RestrictTo;
+
+import com.google.flatbuffers.emojicompat.FlatBufferBuilder;
+import com.google.flatbuffers.emojicompat.Table;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Automatically generated by the FlatBuffers compiler, do not modify.
+ *
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+@SuppressWarnings("unused")
+public final class MetadataList extends Table {
+ public static MetadataList getRootAsMetadataList(ByteBuffer _bb) {
+ return getRootAsMetadataList(_bb, new MetadataList());
+ }
+
+ public static MetadataList getRootAsMetadataList(ByteBuffer _bb, MetadataList obj) {
+ _bb.order(ByteOrder.LITTLE_ENDIAN);
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb));
+ }
+
+ public void __init(int _i, ByteBuffer _bb) {
+ bb_pos = _i;
+ bb = _bb;
+ }
+
+ public MetadataList __assign(int _i, ByteBuffer _bb) {
+ __init(_i, _bb);
+ return this;
+ }
+
+ public int version() {
+ int o = __offset(4);
+ return o != 0 ? bb.getInt(o + bb_pos) : 0;
+ }
+
+ public MetadataItem list(int j) {
+ return list(new MetadataItem(), j);
+ }
+
+ public MetadataItem list(MetadataItem obj, int j) {
+ int o = __offset(6);
+ return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null;
+ }
+
+ public int listLength() {
+ int o = __offset(6);
+ return o != 0 ? __vector_len(o) : 0;
+ }
+
+ public static int createMetadataList(FlatBufferBuilder builder,
+ int version,
+ int listOffset) {
+ builder.startObject(2);
+ MetadataList.addList(builder, listOffset);
+ MetadataList.addVersion(builder, version);
+ return MetadataList.endMetadataList(builder);
+ }
+
+ public static void startMetadataList(FlatBufferBuilder builder) {
+ builder.startObject(2);
+ }
+
+ public static void addVersion(FlatBufferBuilder builder, int version) {
+ builder.addInt(0, version, 0);
+ }
+
+ public static void addList(FlatBufferBuilder builder, int listOffset) {
+ builder.addOffset(1, listOffset, 0);
+ }
+
+ public static int createListVector(FlatBufferBuilder builder, int[] data) {
+ builder.startVector(4, data.length, 4);
+ for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]);
+ return builder.endVector();
+ }
+
+ public static void startListVector(FlatBufferBuilder builder, int numElems) {
+ builder.startVector(4, numElems, 4);
+ }
+
+ public static int endMetadataList(FlatBufferBuilder builder) {
+ int o = builder.endObject();
+ return o;
+ }
+
+ public static void finishMetadataListBuffer(FlatBufferBuilder builder, int offset) {
+ builder.finish(offset);
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/widget/EmojiButton.java b/emoji/core/src/android/support/text/emoji/widget/EmojiButton.java
new file mode 100644
index 0000000..bc55e66
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/widget/EmojiButton.java
@@ -0,0 +1,77 @@
+/*
+ * 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.text.emoji.widget;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.os.Build;
+import android.text.InputFilter;
+import android.util.AttributeSet;
+import android.widget.Button;
+
+/**
+ * Button widget enhanced with emoji capability by using {@link EmojiTextViewHelper}.
+ */
+public class EmojiButton extends Button {
+ private EmojiTextViewHelper mEmojiTextViewHelper;
+ private boolean mInitialized;
+
+ public EmojiButton(Context context) {
+ super(context);
+ init();
+ }
+
+ public EmojiButton(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public EmojiButton(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public EmojiButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ init();
+ }
+
+ private void init() {
+ if (!mInitialized) {
+ mInitialized = true;
+ getEmojiTextViewHelper().updateTransformationMethod();
+ }
+ }
+
+ @Override
+ public void setFilters(InputFilter[] filters) {
+ super.setFilters(getEmojiTextViewHelper().getFilters(filters));
+ }
+
+ @Override
+ public void setAllCaps(boolean allCaps) {
+ super.setAllCaps(allCaps);
+ getEmojiTextViewHelper().setAllCaps(allCaps);
+ }
+
+ private EmojiTextViewHelper getEmojiTextViewHelper() {
+ if (mEmojiTextViewHelper == null) {
+ mEmojiTextViewHelper = new EmojiTextViewHelper(this);
+ }
+ return mEmojiTextViewHelper;
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/widget/EmojiEditText.java b/emoji/core/src/android/support/text/emoji/widget/EmojiEditText.java
new file mode 100644
index 0000000..3e9153b
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/widget/EmojiEditText.java
@@ -0,0 +1,78 @@
+/*
+ * 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.text.emoji.widget;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.widget.EditText;
+
+/**
+ * EditText widget enhanced with emoji capability by using {@link EmojiEditTextHelper}.
+ */
+public class EmojiEditText extends EditText {
+ private EmojiEditTextHelper mEmojiEditTextHelper;
+ private boolean mInitialized;
+
+ public EmojiEditText(Context context) {
+ super(context);
+ init();
+ }
+
+ public EmojiEditText(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public EmojiEditText(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public EmojiEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ init();
+ }
+
+ private void init() {
+ if (!mInitialized) {
+ mInitialized = true;
+ super.setKeyListener(getEmojiEditTextHelper().getKeyListener(getKeyListener()));
+ }
+ }
+
+ @Override
+ public void setKeyListener(android.text.method.KeyListener input) {
+ super.setKeyListener(getEmojiEditTextHelper().getKeyListener(input));
+ }
+
+ @Override
+ public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+ InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
+ return getEmojiEditTextHelper().onCreateInputConnection(inputConnection, outAttrs);
+ }
+
+ private EmojiEditTextHelper getEmojiEditTextHelper() {
+ if (mEmojiEditTextHelper == null) {
+ mEmojiEditTextHelper = new EmojiEditTextHelper(this);
+ }
+ return mEmojiEditTextHelper;
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/widget/EmojiEditTextHelper.java b/emoji/core/src/android/support/text/emoji/widget/EmojiEditTextHelper.java
new file mode 100644
index 0000000..c3d5e84
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/widget/EmojiEditTextHelper.java
@@ -0,0 +1,87 @@
+/*
+ * 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.text.emoji.widget;
+
+import android.support.annotation.NonNull;
+import android.support.v4.util.Preconditions;
+import android.text.method.KeyListener;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.widget.EditText;
+import android.widget.TextView;
+
+/**
+ * Utility class to enhance an EditText with emoji capability.
+ */
+public final class EmojiEditTextHelper {
+ private final EditText mEditText;
+ private final EmojiTextWatcher mTextWatcher;
+
+ /**
+ * Default constructor.
+ *
+ * @param editText EditText instance
+ */
+ public EmojiEditTextHelper(@NonNull final EditText editText) {
+ Preconditions.checkNotNull(editText, "editText cannot be null");
+ mEditText = editText;
+ mTextWatcher = new EmojiTextWatcher(mEditText);
+ editText.addTextChangedListener(mTextWatcher);
+ editText.setEditableFactory(EmojiEditableFactory.getInstance());
+ }
+
+ /**
+ * Attaches EmojiCompat KeyListener to the widget. Should be called from {@link
+ * TextView#setKeyListener(KeyListener)}. Existing keyListener is wrapped into EmojiCompat
+ * KeyListener.
+ * <p/>
+ * <pre><code> {@literal @}Override
+ * public void setKeyListener(android.text.method.KeyListener input) {
+ * super.setKeyListener(getEmojiEditTextHelper().getKeyListener(input));
+ * }</code></pre>
+ *
+ * @param keyListener KeyListener passed into {@link TextView#setKeyListener(KeyListener)}
+ *
+ * @return a new KeyListener instance that wraps {@code keyListener}.
+ */
+
+ public KeyListener getKeyListener(@NonNull final KeyListener keyListener) {
+ Preconditions.checkNotNull(keyListener, "keyListener cannot be null");
+ return new EmojiKeyListener(keyListener);
+ }
+
+ /**
+ * Updates the InputConnection with emoji support. Should be called from {@link
+ * TextView#onCreateInputConnection(EditorInfo)}.
+ * <p/>
+ * <pre><code> {@literal @}Override
+ * public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+ * InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
+ * return getEmojiHelper().onCreateInputConnection(inputConnection, outAttrs);
+ * }</code></pre>
+ *
+ * @param inputConnection InputConnection instance created by TextView
+ * @param outAttrs EditorInfo passed into
+ * {@link TextView#onCreateInputConnection(EditorInfo)}
+ *
+ * @return a new InputConnection instance that wraps {@code inputConnection}
+ */
+ public InputConnection onCreateInputConnection(@NonNull final InputConnection inputConnection,
+ @NonNull final EditorInfo outAttrs) {
+ Preconditions.checkNotNull(inputConnection, "inputConnection cannot be null");
+ return new EmojiInputConnection(mEditText, inputConnection, outAttrs);
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/widget/EmojiEditableFactory.java b/emoji/core/src/android/support/text/emoji/widget/EmojiEditableFactory.java
new file mode 100644
index 0000000..1279b31
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/widget/EmojiEditableFactory.java
@@ -0,0 +1,74 @@
+/*
+ * 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.text.emoji.widget;
+
+import android.support.annotation.GuardedBy;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.Editable;
+
+/**
+ * EditableFactory used to improve editing operations on an EditText.
+ * <p>
+ * EditText uses DynamicLayout, which attaches to the Spannable instance that is being edited using
+ * ChangeWatcher. ChangeWatcher implements SpanWatcher and Textwatcher. Currently every delete/add
+ * operation is reported to DynamicLayout, for every span that has changed. For each change,
+ * DynamicLayout performs some expensive computations. i.e. if there is 100 EmojiSpans and the first
+ * span is deleted, DynamicLayout gets 99 calls about the change of position occurred in the
+ * remaining spans. This causes a huge delay in response time.
+ * <p>
+ * Since "android.text.DynamicLayout$ChangeWatcher" class is not a public class,
+ * EmojiEditableFactory checks if the watcher is in the classpath, and if so uses the modified
+ * Spannable which reduces the total number of calls to DynamicLayout for operations that affect
+ * EmojiSpans.
+ *
+ * @see SpannableBuilder
+ */
+final class EmojiEditableFactory extends Editable.Factory {
+ private static final Object sInstanceLock = new Object();
+ @GuardedBy("sInstanceLock")
+ private static volatile Editable.Factory sInstance;
+
+ @Nullable private static Class<?> sWatcherClass;
+
+ private EmojiEditableFactory() {
+ try {
+ String className = "android.text.DynamicLayout$ChangeWatcher";
+ sWatcherClass = getClass().getClassLoader().loadClass(className);
+ } catch (Throwable t) {
+ // ignore
+ }
+ }
+
+ public static Editable.Factory getInstance() {
+ if (sInstance == null) {
+ synchronized (sInstanceLock) {
+ if (sInstance == null) {
+ sInstance = new EmojiEditableFactory();
+ }
+ }
+ }
+ return sInstance;
+ }
+
+ @Override
+ public Editable newEditable(@NonNull final CharSequence source) {
+ if (sWatcherClass != null) {
+ return SpannableBuilder.create(sWatcherClass, source);
+ }
+ return super.newEditable(source);
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/widget/EmojiInputConnection.java b/emoji/core/src/android/support/text/emoji/widget/EmojiInputConnection.java
new file mode 100644
index 0000000..3347130
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/widget/EmojiInputConnection.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.text.emoji.widget;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
+import android.support.text.emoji.EmojiCompat;
+import android.text.Editable;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputConnectionWrapper;
+import android.widget.TextView;
+
+/**
+ * InputConnectionWrapper for EditText delete operations. Keyboard does not have knowledge about
+ * emojis and therefore might send commands to delete a part of the emoji sequence which creates
+ * invalid codeunits/getCodepointAt in the text.
+ * <p/>
+ * This class tries to correctly delete an emoji checking if there is an emoji span.
+ *
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+final class EmojiInputConnection extends InputConnectionWrapper {
+ private final TextView mTextView;
+
+ EmojiInputConnection(
+ @NonNull final TextView textView,
+ @NonNull final InputConnection inputConnection,
+ @NonNull final EditorInfo outAttrs) {
+ super(inputConnection, false);
+ mTextView = textView;
+ EmojiCompat.get().updateEditorInfoAttrs(outAttrs);
+ }
+
+ @Override
+ public boolean deleteSurroundingText(final int beforeLength, final int afterLength) {
+ final boolean result = EmojiCompat.handleDeleteSurroundingText(this, getEditable(),
+ beforeLength, afterLength, false /* in code ponints */);
+ return result || super.deleteSurroundingText(beforeLength, afterLength);
+ }
+
+ @Override
+ public boolean deleteSurroundingTextInCodePoints(final int beforeLength,
+ final int afterLength) {
+ final boolean result = EmojiCompat.handleDeleteSurroundingText(this, getEditable(),
+ beforeLength, afterLength, true /* in code ponints */);
+ return result || super.deleteSurroundingTextInCodePoints(beforeLength, afterLength);
+ }
+
+ private Editable getEditable() {
+ return mTextView.getEditableText();
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/widget/EmojiInputFilter.java b/emoji/core/src/android/support/text/emoji/widget/EmojiInputFilter.java
new file mode 100644
index 0000000..e716dfd
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/widget/EmojiInputFilter.java
@@ -0,0 +1,125 @@
+/*
+ * 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.text.emoji.widget;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
+import android.support.text.emoji.EmojiCompat;
+import android.support.text.emoji.EmojiCompat.InitCallback;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.Spanned;
+import android.widget.TextView;
+
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+
+/**
+ * InputFilter to add EmojiSpans to the CharSequence set in a TextView. Unlike EditText where a
+ * TextWatcher is used to enhance the CharSequence, InputFilter is used on TextView. The reason is
+ * that if you add a TextWatcher to a TextView, its internal layout mechanism change, and therefore
+ * depending on the CharSequence provided, adding a TextWatcher might have performance side
+ * effects.
+ *
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+final class EmojiInputFilter implements android.text.InputFilter {
+ private final TextView mTextView;
+ private InitCallback mInitCallback;
+
+ EmojiInputFilter(@NonNull final TextView textView) {
+ mTextView = textView;
+ }
+
+ @Override
+ public CharSequence filter(final CharSequence source, final int sourceStart,
+ final int sourceEnd, final Spanned dest, final int destStart, final int destEnd) {
+ if (mTextView.isInEditMode()) {
+ return source;
+ }
+
+ if (EmojiCompat.get().isInitialized()) {
+ boolean process = true;
+ if (destEnd == 0 && destStart == 0 && dest.length() == 0) {
+ final CharSequence oldText = mTextView.getText();
+ if (source == oldText) {
+ process = false;
+ }
+ }
+
+ if (process && source != null) {
+ final CharSequence text;
+ if (sourceStart == 0 && sourceEnd == source.length()) {
+ text = source;
+ } else {
+ text = source.subSequence(sourceStart, sourceEnd);
+ }
+ return EmojiCompat.get().process(text, 0, text.length());
+ }
+
+ return source;
+ } else {
+ EmojiCompat.get().registerInitCallback(getInitCallback());
+ return source;
+ }
+ }
+
+ private InitCallback getInitCallback() {
+ if (mInitCallback == null) {
+ mInitCallback = new InitCallbackImpl(mTextView);
+ }
+ return mInitCallback;
+ }
+
+ private static class InitCallbackImpl extends InitCallback {
+ private final Reference<TextView> mViewRef;
+
+ InitCallbackImpl(TextView textView) {
+ mViewRef = new WeakReference<>(textView);
+ }
+
+ @Override
+ public void onInitialized() {
+ super.onInitialized();
+ final TextView textView = mViewRef.get();
+ if (textView != null && textView.isAttachedToWindow()) {
+ final CharSequence result = EmojiCompat.get().process(textView.getText());
+
+ final int selectionStart = Selection.getSelectionStart(result);
+ final int selectionEnd = Selection.getSelectionEnd(result);
+
+ textView.setText(result);
+
+ if (result instanceof Spannable) {
+ updateSelection((Spannable) result, selectionStart, selectionEnd);
+ }
+ }
+ }
+ }
+
+ static void updateSelection(Spannable spannable, final int start, final int end) {
+ if (start >= 0 && end >= 0) {
+ Selection.setSelection(spannable, start, end);
+ } else if (start >= 0) {
+ Selection.setSelection(spannable, start);
+ } else if (end >= 0) {
+ Selection.setSelection(spannable, end);
+ }
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/widget/EmojiKeyListener.java b/emoji/core/src/android/support/text/emoji/widget/EmojiKeyListener.java
new file mode 100644
index 0000000..f1d18af
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/widget/EmojiKeyListener.java
@@ -0,0 +1,64 @@
+/*
+ * 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.text.emoji.widget;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.support.annotation.RestrictTo;
+import android.support.text.emoji.EmojiCompat;
+import android.text.Editable;
+import android.view.KeyEvent;
+import android.view.View;
+
+/**
+ * KeyListener class to handle delete operations correctly.
+ *
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+final class EmojiKeyListener implements android.text.method.KeyListener {
+ private final android.text.method.KeyListener mKeyListener;
+
+ EmojiKeyListener(android.text.method.KeyListener keyListener) {
+ mKeyListener = keyListener;
+ }
+
+ @Override
+ public int getInputType() {
+ return mKeyListener.getInputType();
+ }
+
+ @Override
+ public boolean onKeyDown(View view, Editable content, int keyCode, KeyEvent event) {
+ final boolean result = EmojiCompat.handleOnKeyDown(content, keyCode, event);
+ return result || mKeyListener.onKeyDown(view, content, keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyUp(View view, Editable text, int keyCode, KeyEvent event) {
+ return mKeyListener.onKeyUp(view, text, keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyOther(View view, Editable text, KeyEvent event) {
+ return mKeyListener.onKeyOther(view, text, event);
+ }
+
+ @Override
+ public void clearMetaKeyState(View view, Editable content, int states) {
+ mKeyListener.clearMetaKeyState(view, content, states);
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/widget/EmojiTextView.java b/emoji/core/src/android/support/text/emoji/widget/EmojiTextView.java
new file mode 100644
index 0000000..86294d0
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/widget/EmojiTextView.java
@@ -0,0 +1,77 @@
+/*
+ * 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.text.emoji.widget;
+
+import android.content.Context;
+import android.os.Build;
+import android.support.annotation.RequiresApi;
+import android.text.InputFilter;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+/**
+ * TextView widget enhanced with emoji capability by using {@link EmojiTextViewHelper}.
+ */
+public class EmojiTextView extends TextView {
+ private EmojiTextViewHelper mEmojiTextViewHelper;
+ private boolean mInitialized;
+
+ public EmojiTextView(Context context) {
+ super(context);
+ init();
+ }
+
+ public EmojiTextView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public EmojiTextView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+ public EmojiTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ init();
+ }
+
+ private void init() {
+ if (!mInitialized) {
+ mInitialized = true;
+ getEmojiTextViewHelper().updateTransformationMethod();
+ }
+ }
+
+ @Override
+ public void setFilters(InputFilter[] filters) {
+ super.setFilters(getEmojiTextViewHelper().getFilters(filters));
+ }
+
+ @Override
+ public void setAllCaps(boolean allCaps) {
+ super.setAllCaps(allCaps);
+ getEmojiTextViewHelper().setAllCaps(allCaps);
+ }
+
+ private EmojiTextViewHelper getEmojiTextViewHelper() {
+ if (mEmojiTextViewHelper == null) {
+ mEmojiTextViewHelper = new EmojiTextViewHelper(this);
+ }
+ return mEmojiTextViewHelper;
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/widget/EmojiTextViewHelper.java b/emoji/core/src/android/support/text/emoji/widget/EmojiTextViewHelper.java
new file mode 100644
index 0000000..e88cc87
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/widget/EmojiTextViewHelper.java
@@ -0,0 +1,112 @@
+/*
+ * 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.text.emoji.widget;
+
+import android.support.annotation.NonNull;
+import android.support.v4.util.Preconditions;
+import android.text.InputFilter;
+import android.text.method.PasswordTransformationMethod;
+import android.text.method.TransformationMethod;
+import android.widget.TextView;
+
+/**
+ * Utility class to enhance a TextView with emoji capability.
+ */
+public final class EmojiTextViewHelper {
+ private final TextView mTextView;
+ private final EmojiInputFilter mEmojiInputFilter;
+
+ /**
+ * Default constructor.
+ *
+ * @param textView TextView instance
+ */
+ public EmojiTextViewHelper(@NonNull TextView textView) {
+ Preconditions.checkNotNull(textView, "textView cannot be null");
+ mTextView = textView;
+ mEmojiInputFilter = new EmojiInputFilter(textView);
+ }
+
+ /**
+ * Updates widget's TransformationMethod so that the transformed text can be processed.
+ * Should be called in the widget constructor.
+ *
+ * @see #getTransformationMethod(TransformationMethod)
+ */
+ public void updateTransformationMethod() {
+ final TransformationMethod transformationMethod = mTextView.getTransformationMethod();
+ if (transformationMethod != null
+ && !(transformationMethod instanceof PasswordTransformationMethod)) {
+ mTextView.setTransformationMethod(getTransformationMethod(transformationMethod));
+ }
+ }
+
+ /**
+ * Appends EmojiCompat InputFilters to the widget InputFilters. Should be called by {@link
+ * TextView#setFilters(InputFilter[])} to update the InputFilters.
+ * <p/>
+ * <pre><code> {@literal @}Override
+ * public void setFilters(InputFilter[] filters) {
+ * super.setFilters(getEmojiTextViewHelper().getFilters(filters));
+ * }</code></pre>
+ *
+ * @param filters InputFilter array passed to {@link TextView#setFilters(InputFilter[])}
+ *
+ * @return same copy if the array already contains EmojiCompat InputFilter. A new array copy if
+ * not.
+ */
+ public InputFilter[] getFilters(@NonNull final InputFilter[] filters) {
+ final int count = filters.length;
+ for (int i = 0; i < count; i++) {
+ if (filters[i] instanceof EmojiInputFilter) {
+ return filters;
+ }
+ }
+ final InputFilter[] newFilters = new InputFilter[filters.length + 1];
+ System.arraycopy(filters, 0, newFilters, 0, count);
+ newFilters[count] = mEmojiInputFilter;
+ return newFilters;
+ }
+
+ /**
+ * Returns transformation method that can update the transformed text to display emojis.
+ *
+ * @param transformationMethod instance to be wrapped
+ */
+ public TransformationMethod getTransformationMethod(
+ final TransformationMethod transformationMethod) {
+ return new EmojiTransformationMethod(transformationMethod);
+ }
+
+ /**
+ * Call when allCaps is set on TextView.
+ * <p/>
+ * <pre><code> {@literal @}Override
+ * public void setAllCaps(boolean allCaps) {
+ * super.setAllCaps(allCaps);
+ * getEmojiTextViewHelper().setAllCaps(allCaps);
+ * }</code></pre>
+ *
+ * @param allCaps allCaps parameter passed to {@link TextView#setAllCaps(boolean)}
+ */
+ public void setAllCaps(boolean allCaps) {
+ // When allCaps is set to false TextView sets the transformation method to be null. We
+ // are only interested when allCaps is set to true in order to wrap the original method.
+ if (allCaps) {
+ updateTransformationMethod();
+ }
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/widget/EmojiTextWatcher.java b/emoji/core/src/android/support/text/emoji/widget/EmojiTextWatcher.java
new file mode 100644
index 0000000..9adc015
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/widget/EmojiTextWatcher.java
@@ -0,0 +1,102 @@
+/*
+ * 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.text.emoji.widget;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.support.annotation.RestrictTo;
+import android.support.text.emoji.EmojiCompat;
+import android.support.text.emoji.EmojiCompat.InitCallback;
+import android.text.Editable;
+import android.text.Selection;
+import android.text.Spannable;
+import android.widget.EditText;
+
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+
+/**
+ * TextWatcher used for an EditText.
+ *
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+final class EmojiTextWatcher implements android.text.TextWatcher {
+ private final EditText mEditText;
+ private InitCallback mInitCallback;
+
+ EmojiTextWatcher(EditText editText) {
+ mEditText = editText;
+ }
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, final int start, final int before,
+ final int after) {
+ if (mEditText.isInEditMode()) {
+ return;
+ }
+ //before > after --> a deletion occured
+ if (before <= after && charSequence instanceof Spannable) {
+ if (EmojiCompat.get().isInitialized()) {
+ final Spannable s = (Spannable) charSequence;
+ EmojiCompat.get().process(s, start, start + after);
+ } else {
+ EmojiCompat.get().registerInitCallback(getInitCallback());
+ }
+ }
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ // do nothing
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ // do nothing
+ }
+
+ private InitCallback getInitCallback() {
+ if (mInitCallback == null) {
+ mInitCallback = new InitCallbackImpl(mEditText);
+ }
+ return mInitCallback;
+ }
+
+ private static class InitCallbackImpl extends InitCallback {
+ private final Reference<EditText> mViewRef;
+
+ InitCallbackImpl(EditText editText) {
+ mViewRef = new WeakReference<>(editText);
+ }
+
+ @Override
+ public void onInitialized() {
+ super.onInitialized();
+ final EditText editText = mViewRef.get();
+ if (editText != null && editText.isAttachedToWindow()) {
+ final Editable text = editText.getEditableText();
+
+ final int selectionStart = Selection.getSelectionStart(text);
+ final int selectionEnd = Selection.getSelectionEnd(text);
+
+ EmojiCompat.get().process(text);
+
+ EmojiInputFilter.updateSelection(text, selectionStart, selectionEnd);
+ }
+ }
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/widget/EmojiTransformationMethod.java b/emoji/core/src/android/support/text/emoji/widget/EmojiTransformationMethod.java
new file mode 100644
index 0000000..224b600
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/widget/EmojiTransformationMethod.java
@@ -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 android.support.text.emoji.widget;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.graphics.Rect;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
+import android.support.text.emoji.EmojiCompat;
+import android.text.method.TransformationMethod;
+import android.view.View;
+
+/**
+ * TransformationMethod wrapper in order to update transformed text with emojis.
+ *
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+class EmojiTransformationMethod implements TransformationMethod {
+ private final TransformationMethod mTransformationMethod;
+
+ EmojiTransformationMethod(TransformationMethod transformationMethod) {
+ mTransformationMethod = transformationMethod;
+ }
+
+ @Override
+ public CharSequence getTransformation(@Nullable CharSequence source, @NonNull final View view) {
+ if (view.isInEditMode()) {
+ return source;
+ }
+
+ if (mTransformationMethod != null) {
+ source = mTransformationMethod.getTransformation(source, view);
+ }
+
+ if (source != null) {
+ if (EmojiCompat.get().isInitialized()) {
+ return EmojiCompat.get().process(source);
+ }
+ }
+ return source;
+ }
+
+ @Override
+ public void onFocusChanged(final View view, final CharSequence sourceText,
+ final boolean focused, final int direction, final Rect previouslyFocusedRect) {
+ if (mTransformationMethod != null) {
+ mTransformationMethod.onFocusChanged(view, sourceText, focused, direction,
+ previouslyFocusedRect);
+ }
+ }
+}
diff --git a/emoji/core/src/android/support/text/emoji/widget/SpannableBuilder.java b/emoji/core/src/android/support/text/emoji/widget/SpannableBuilder.java
new file mode 100644
index 0000000..bbce352
--- /dev/null
+++ b/emoji/core/src/android/support/text/emoji/widget/SpannableBuilder.java
@@ -0,0 +1,433 @@
+/*
+ * 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.text.emoji.widget;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
+import android.support.text.emoji.EmojiSpan;
+import android.support.v4.util.Preconditions;
+import android.text.Editable;
+import android.text.SpanWatcher;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.text.TextWatcher;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * When setSpan functions is called on EmojiSpannableBuilder, it checks if the mObject is instance
+ * of the DynamicLayout$ChangeWatcher. if so, it wraps it into another listener mObject
+ * (WatcherWrapper) that implements the same interfaces.
+ * <p>
+ * During a span change event WatcherWrapper’s functions are fired, it checks if the span is an
+ * EmojiSpan, and prevents the ChangeWatcher being fired for that span. WatcherWrapper informs
+ * ChangeWatcher only once at the end of the edit. Important point is, the block operation is
+ * applied only for EmojiSpans. Therefore any other span change operation works the same way as in
+ * the framework.
+ *
+ * @hide
+ * @see EmojiEditableFactory
+ */
+@RestrictTo(LIBRARY_GROUP)
+public final class SpannableBuilder extends SpannableStringBuilder {
+ /**
+ * DynamicLayout$ChangeWatcher class.
+ */
+ private final Class<?> mWatcherClass;
+
+ /**
+ * All WatcherWrappers.
+ */
+ private final List<WatcherWrapper> mWatchers = new ArrayList<>();
+
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ SpannableBuilder(@NonNull Class<?> watcherClass) {
+ Preconditions.checkNotNull(watcherClass, "watcherClass cannot be null");
+ mWatcherClass = watcherClass;
+ }
+
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ SpannableBuilder(@NonNull Class<?> watcherClass, @NonNull CharSequence text) {
+ super(text);
+ Preconditions.checkNotNull(watcherClass, "watcherClass cannot be null");
+ mWatcherClass = watcherClass;
+ }
+
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ SpannableBuilder(@NonNull Class<?> watcherClass, @NonNull CharSequence text, int start,
+ int end) {
+ super(text, start, end);
+ Preconditions.checkNotNull(watcherClass, "watcherClass cannot be null");
+ mWatcherClass = watcherClass;
+ }
+
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ static SpannableBuilder create(@NonNull Class<?> clazz, @NonNull CharSequence text) {
+ return new SpannableBuilder(clazz, text);
+ }
+
+ /**
+ * Checks whether the mObject is instance of the DynamicLayout$ChangeWatcher.
+ *
+ * @param object mObject to be checked
+ *
+ * @return true if mObject is instance of the DynamicLayout$ChangeWatcher.
+ */
+ private boolean isWatcher(@Nullable Object object) {
+ return object != null && isWatcher(object.getClass());
+ }
+
+ /**
+ * Checks whether the class is DynamicLayout$ChangeWatcher.
+ *
+ * @param clazz class to be checked
+ *
+ * @return true if class is DynamicLayout$ChangeWatcher.
+ */
+ private boolean isWatcher(@NonNull Class<?> clazz) {
+ return mWatcherClass == clazz;
+ }
+
+ @Override
+ public CharSequence subSequence(int start, int end) {
+ return new SpannableBuilder(mWatcherClass, this, start, end);
+ }
+
+ /**
+ * If the span being added is instance of DynamicLayout$ChangeWatcher, wrap the watcher in
+ * another internal watcher that will prevent EmojiSpan events to be fired to DynamicLayout. Set
+ * this new mObject as the span.
+ */
+ @Override
+ public void setSpan(Object what, int start, int end, int flags) {
+ if (isWatcher(what)) {
+ final WatcherWrapper span = new WatcherWrapper(what);
+ mWatchers.add(span);
+ what = span;
+ }
+ super.setSpan(what, start, end, flags);
+ }
+
+ /**
+ * If previously a DynamicLayout$ChangeWatcher was wrapped in a WatcherWrapper, return the
+ * correct Object that the client has set.
+ */
+ @Override
+ public <T> T[] getSpans(int queryStart, int queryEnd, Class<T> kind) {
+ if (isWatcher(kind)) {
+ final WatcherWrapper[] spans = super.getSpans(queryStart, queryEnd,
+ WatcherWrapper.class);
+ final T[] result = (T[]) Array.newInstance(kind, spans.length);
+ for (int i = 0; i < spans.length; i++) {
+ result[i] = (T) spans[i].mObject;
+ }
+ return result;
+ }
+ return super.getSpans(queryStart, queryEnd, kind);
+ }
+
+ /**
+ * If the client wants to remove the DynamicLayout$ChangeWatcher span, remove the WatcherWrapper
+ * instead.
+ */
+ @Override
+ public void removeSpan(Object what) {
+ final WatcherWrapper watcher;
+ if (isWatcher(what)) {
+ watcher = getWatcherFor(what);
+ if (watcher != null) {
+ what = watcher;
+ }
+ } else {
+ watcher = null;
+ }
+
+ super.removeSpan(what);
+
+ if (watcher != null) {
+ mWatchers.remove(watcher);
+ }
+ }
+
+ /**
+ * Return the correct start for the DynamicLayout$ChangeWatcher span.
+ */
+ @Override
+ public int getSpanStart(Object tag) {
+ if (isWatcher(tag)) {
+ final WatcherWrapper watcher = getWatcherFor(tag);
+ if (watcher != null) {
+ tag = watcher;
+ }
+ }
+ return super.getSpanStart(tag);
+ }
+
+ /**
+ * Return the correct end for the DynamicLayout$ChangeWatcher span.
+ */
+ @Override
+ public int getSpanEnd(Object tag) {
+ if (isWatcher(tag)) {
+ final WatcherWrapper watcher = getWatcherFor(tag);
+ if (watcher != null) {
+ tag = watcher;
+ }
+ }
+ return super.getSpanEnd(tag);
+ }
+
+ /**
+ * Return the correct flags for the DynamicLayout$ChangeWatcher span.
+ */
+ @Override
+ public int getSpanFlags(Object tag) {
+ if (isWatcher(tag)) {
+ final WatcherWrapper watcher = getWatcherFor(tag);
+ if (watcher != null) {
+ tag = watcher;
+ }
+ }
+ return super.getSpanFlags(tag);
+ }
+
+ /**
+ * Return the correct transition for the DynamicLayout$ChangeWatcher span.
+ */
+ @Override
+ public int nextSpanTransition(int start, int limit, Class type) {
+ if (isWatcher(type)) {
+ type = WatcherWrapper.class;
+ }
+ return super.nextSpanTransition(start, limit, type);
+ }
+
+ /**
+ * Find the WatcherWrapper for a given DynamicLayout$ChangeWatcher.
+ *
+ * @param object DynamicLayout$ChangeWatcher mObject
+ *
+ * @return WatcherWrapper that wraps the mObject.
+ */
+ private WatcherWrapper getWatcherFor(Object object) {
+ for (int i = 0; i < mWatchers.size(); i++) {
+ WatcherWrapper watcher = mWatchers.get(i);
+ if (watcher.mObject == object) {
+ return watcher;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ public void beginBatchEdit() {
+ blockWatchers();
+ }
+
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ public void endBatchEdit() {
+ unblockwatchers();
+ fireWatchers();
+ }
+
+ /**
+ * Block all watcher wrapper events.
+ */
+ private void blockWatchers() {
+ for (int i = 0; i < mWatchers.size(); i++) {
+ mWatchers.get(i).blockCalls();
+ }
+ }
+
+ /**
+ * Unblock all watcher wrapper events.
+ */
+ private void unblockwatchers() {
+ for (int i = 0; i < mWatchers.size(); i++) {
+ mWatchers.get(i).unblockCalls();
+ }
+ }
+
+ /**
+ * Unblock all watcher wrapper events. Called by editing operations, namely
+ * {@link SpannableStringBuilder#replace(int, int, CharSequence)}.
+ */
+ private void fireWatchers() {
+ for (int i = 0; i < mWatchers.size(); i++) {
+ mWatchers.get(i).onTextChanged(this, 0, this.length(), this.length());
+ }
+ }
+
+ @Override
+ public SpannableStringBuilder replace(int start, int end, CharSequence tb) {
+ blockWatchers();
+ super.replace(start, end, tb);
+ unblockwatchers();
+ return this;
+ }
+
+ @Override
+ public SpannableStringBuilder replace(int start, int end, CharSequence tb, int tbstart,
+ int tbend) {
+ blockWatchers();
+ super.replace(start, end, tb, tbstart, tbend);
+ unblockwatchers();
+ return this;
+ }
+
+ @Override
+ public SpannableStringBuilder insert(int where, CharSequence tb) {
+ super.insert(where, tb);
+ return this;
+ }
+
+ @Override
+ public SpannableStringBuilder insert(int where, CharSequence tb, int start, int end) {
+ super.insert(where, tb, start, end);
+ return this;
+ }
+
+ @Override
+ public SpannableStringBuilder delete(int start, int end) {
+ super.delete(start, end);
+ return this;
+ }
+
+ @Override
+ public SpannableStringBuilder append(CharSequence text) {
+ super.append(text);
+ return this;
+ }
+
+ @Override
+ public SpannableStringBuilder append(char text) {
+ super.append(text);
+ return this;
+ }
+
+ @Override
+ public SpannableStringBuilder append(CharSequence text, int start, int end) {
+ super.append(text, start, end);
+ return this;
+ }
+
+ @Override
+ public SpannableStringBuilder append(CharSequence text, Object what, int flags) {
+ super.append(text, what, flags);
+ return this;
+ }
+
+ /**
+ * Wraps a DynamicLayout$ChangeWatcher in order to prevent firing of events to DynamicLayout.
+ */
+ private static class WatcherWrapper implements TextWatcher, SpanWatcher {
+ private final Object mObject;
+ private final AtomicInteger mBlockCalls = new AtomicInteger(0);
+
+ WatcherWrapper(Object object) {
+ this.mObject = object;
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ ((TextWatcher) mObject).beforeTextChanged(s, start, count, after);
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ ((TextWatcher) mObject).onTextChanged(s, start, before, count);
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ ((TextWatcher) mObject).afterTextChanged(s);
+ }
+
+ /**
+ * Prevent the onSpanAdded calls to DynamicLayout$ChangeWatcher if in a replace operation
+ * (mBlockCalls is set) and the span that is added is an EmojiSpan.
+ */
+ @Override
+ public void onSpanAdded(Spannable text, Object what, int start, int end) {
+ if (mBlockCalls.get() > 0 && isEmojiSpan(what)) {
+ return;
+ }
+ ((SpanWatcher) mObject).onSpanAdded(text, what, start, end);
+ }
+
+ /**
+ * Prevent the onSpanRemoved calls to DynamicLayout$ChangeWatcher if in a replace operation
+ * (mBlockCalls is set) and the span that is added is an EmojiSpan.
+ */
+ @Override
+ public void onSpanRemoved(Spannable text, Object what, int start, int end) {
+ if (mBlockCalls.get() > 0 && isEmojiSpan(what)) {
+ return;
+ }
+ ((SpanWatcher) mObject).onSpanRemoved(text, what, start, end);
+ }
+
+ /**
+ * Prevent the onSpanChanged calls to DynamicLayout$ChangeWatcher if in a replace operation
+ * (mBlockCalls is set) and the span that is added is an EmojiSpan.
+ */
+ @Override
+ public void onSpanChanged(Spannable text, Object what, int ostart, int oend, int nstart,
+ int nend) {
+ if (mBlockCalls.get() > 0 && isEmojiSpan(what)) {
+ return;
+ }
+ ((SpanWatcher) mObject).onSpanChanged(text, what, ostart, oend, nstart, nend);
+ }
+
+ final void blockCalls() {
+ mBlockCalls.incrementAndGet();
+ }
+
+ final void unblockCalls() {
+ mBlockCalls.decrementAndGet();
+ }
+
+ private boolean isEmojiSpan(final Object span) {
+ return span instanceof EmojiSpan;
+ }
+ }
+
+}
diff --git a/dynamic-animation/AndroidManifest-make.xml b/emoji/core/tests/AndroidManifest.xml
similarity index 83%
rename from dynamic-animation/AndroidManifest-make.xml
rename to emoji/core/tests/AndroidManifest.xml
index bfe97cc..4c706b2 100644
--- a/dynamic-animation/AndroidManifest-make.xml
+++ b/emoji/core/tests/AndroidManifest.xml
@@ -14,6 +14,10 @@
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.support.dynamicanimation">
- <uses-sdk android:minSdkVersion="16"/>
-</manifest>
+ package="android.support.text.emoji">
+
+ <application>
+ <activity android:name=".TestActivity"/>
+ </application>
+
+</manifest>
\ No newline at end of file
diff --git a/emoji/core/tests/assets/NotoColorEmojiCompat.ttf b/emoji/core/tests/assets/NotoColorEmojiCompat.ttf
new file mode 100644
index 0000000..0c59d8e
--- /dev/null
+++ b/emoji/core/tests/assets/NotoColorEmojiCompat.ttf
Binary files differ
diff --git a/emoji/core/tests/java/android/support/text/emoji/AllEmojisTest.java b/emoji/core/tests/java/android/support/text/emoji/AllEmojisTest.java
new file mode 100644
index 0000000..f84ecbc
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/AllEmojisTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.text.emoji;
+
+import static android.support.text.emoji.util.EmojiMatcher.hasEmojiAt;
+import static android.support.text.emoji.util.EmojiMatcher.hasEmojiCount;
+
+import static junit.framework.TestCase.assertTrue;
+
+import static org.junit.Assert.assertThat;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.text.emoji.test.R;
+import android.support.text.emoji.util.TestString;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Reads raw/allemojis.txt which includes all the emojis known to human kind and tests that
+ * EmojiCompat creates EmojiSpans for each one of them.
+ */
+@SmallTest
+@RunWith(Parameterized.class)
+public class AllEmojisTest {
+
+ /**
+ * String representation for a single emoji
+ */
+ private String mString;
+
+ /**
+ * Codepoints of emoji for better assert error message.
+ */
+ private String mCodepoints;
+
+ @BeforeClass
+ public static void setup() {
+ EmojiCompat.reset(TestConfigBuilder.config());
+ }
+
+ @Parameterized.Parameters
+ public static Collection<Object[]> data() {
+ final Context context = InstrumentationRegistry.getTargetContext();
+ final InputStream inputStream = context.getResources().openRawResource(R.raw.all_emojis);
+ final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+ final Collection<Object[]> data = new ArrayList<>();
+ final StringBuilder stringBuilder = new StringBuilder();
+ final StringBuilder codePointsBuilder = new StringBuilder();
+ final int hexPrefixLength = "0x".length();
+
+ try {
+ String s;
+ while ((s = reader.readLine()) != null) {
+ stringBuilder.setLength(0);
+ codePointsBuilder.setLength(0);
+
+ // emoji codepoints are space separated: i.e. 0x1f1e6 0x1f1e8
+ final String[] split = s.split(" ");
+
+ for (int index = 0; index < split.length; index++) {
+ final String part = split[index];
+ final String substring = part.substring(hexPrefixLength, part.length());
+ codePointsBuilder.append(substring);
+ codePointsBuilder.append(",");
+ stringBuilder.append(Character.toChars(Integer.parseInt(substring, 16)));
+ }
+ data.add(new Object[]{stringBuilder.toString(), codePointsBuilder.toString()});
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return data;
+ }
+
+ public AllEmojisTest(String string, String codepoints) {
+ mString = string;
+ mCodepoints = codepoints;
+ }
+
+ @Test
+ public void testEmoji() {
+ assertTrue("EmojiCompat should have emoji: " + mCodepoints,
+ EmojiCompat.get().hasEmojiGlyph(mString));
+ assertEmojiCompatAddsEmoji(mString);
+ }
+
+ private void assertEmojiCompatAddsEmoji(final String str) {
+ TestString string = new TestString(str);
+ CharSequence sequence = EmojiCompat.get().process(string.toString());
+ assertThat(sequence, hasEmojiCount(1));
+ assertThat(sequence, hasEmojiAt(string.emojiStartIndex(), string.emojiEndIndex()));
+
+ // case where Emoji is in the middle of string
+ string = new TestString(str).withPrefix().withSuffix();
+ sequence = EmojiCompat.get().process(string.toString());
+ assertThat(sequence, hasEmojiCount(1));
+ assertThat(sequence, hasEmojiAt(string.emojiStartIndex(), string.emojiEndIndex()));
+
+ // case where Emoji is at the end of string
+ string = new TestString(str).withSuffix();
+ sequence = EmojiCompat.get().process(string.toString());
+ assertThat(sequence, hasEmojiCount(1));
+ assertThat(sequence, hasEmojiAt(string.emojiStartIndex(), string.emojiEndIndex()));
+ }
+
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/ConfigTest.java b/emoji/core/tests/java/android/support/text/emoji/ConfigTest.java
new file mode 100644
index 0000000..d293dab
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/ConfigTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.text.emoji;
+
+import static android.support.text.emoji.util.Emoji.EMOJI_SINGLE_CODEPOINT;
+import static android.support.text.emoji.util.EmojiMatcher.hasEmoji;
+import static android.support.text.emoji.util.EmojiMatcher.hasEmojiCount;
+
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.text.emoji.util.TestString;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ConfigTest {
+
+ Context mContext;
+
+ @Before
+ public void setup() {
+ mContext = InstrumentationRegistry.getTargetContext();
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testConstructor_throwsExceptionIfMetadataLoaderNull() {
+ new TestConfigBuilder.TestConfig(null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testMaxEmojiPerText_throwsExceptionIfNegative() {
+ new ValidTestConfig().setMaxEmojiPerText(-1);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testInitCallback_throwsExceptionIfNull() {
+ new ValidTestConfig().registerInitCallback(null);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testUnregisterInitCallback_throwsExceptionIfNull() {
+ new ValidTestConfig().unregisterInitCallback(null);
+ }
+
+ @Test
+ public void testBuild_withDefaultValues() {
+ final EmojiCompat.Config config = new ValidTestConfig().setReplaceAll(true);
+
+ final EmojiCompat emojiCompat = EmojiCompat.reset(config);
+
+ final CharSequence processed = emojiCompat.process(new TestString(EMOJI_SINGLE_CODEPOINT)
+ .toString());
+ assertThat(processed, hasEmojiCount(1));
+ assertThat(processed, hasEmoji(EMOJI_SINGLE_CODEPOINT));
+ }
+
+ @Test
+ public void testBuild_withMaxEmojiSetToZero() {
+ final EmojiCompat.Config config = new ValidTestConfig().setReplaceAll(true)
+ .setMaxEmojiPerText(0);
+
+ final EmojiCompat emojiCompat = EmojiCompat.reset(config);
+ final String original = new TestString(EMOJI_SINGLE_CODEPOINT).toString();
+ final CharSequence processed = emojiCompat.process(original);
+
+ assertThat(processed, not(hasEmoji()));
+ }
+
+ @Test
+ public void testBuild_withMaxEmojiSetToOne() {
+ final EmojiCompat.Config config = new ValidTestConfig().setReplaceAll(true)
+ .setMaxEmojiPerText(1);
+
+ final EmojiCompat emojiCompat = EmojiCompat.reset(config);
+ final String original = new TestString(EMOJI_SINGLE_CODEPOINT).toString();
+ final CharSequence processed = emojiCompat.process(original);
+
+ assertThat(processed, hasEmojiCount(1));
+ assertThat(processed, hasEmoji(EMOJI_SINGLE_CODEPOINT));
+ }
+
+ @Test
+ public void testInitCallback_callsSuccessCallback() {
+ final EmojiCompat.InitCallback initCallback1 = mock(EmojiCompat.InitCallback.class);
+ final EmojiCompat.InitCallback initCallback2 = mock(EmojiCompat.InitCallback.class);
+
+ final EmojiCompat.Config config = new ValidTestConfig().registerInitCallback(initCallback1)
+ .registerInitCallback(initCallback2);
+ EmojiCompat.reset(config);
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ verify(initCallback1, times(1)).onInitialized();
+ verify(initCallback2, times(1)).onInitialized();
+ }
+
+ @Test
+ public void testInitCallback_callsFailCallback() {
+ final EmojiCompat.InitCallback initCallback1 = mock(EmojiCompat.InitCallback.class);
+ final EmojiCompat.InitCallback initCallback2 = mock(EmojiCompat.InitCallback.class);
+ final EmojiCompat.MetadataLoader loader = mock(EmojiCompat.MetadataLoader.class);
+ doThrow(new RuntimeException("")).when(loader).load(any(EmojiCompat.LoaderCallback
+ .class));
+
+ final EmojiCompat.Config config = new TestConfigBuilder.TestConfig(loader)
+ .registerInitCallback(initCallback1)
+ .registerInitCallback(initCallback2);
+ EmojiCompat.reset(config);
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ verify(initCallback1, times(1)).onFailed(any(Throwable.class));
+ verify(initCallback2, times(1)).onFailed(any(Throwable.class));
+ }
+
+ private static class ValidTestConfig extends EmojiCompat.Config {
+ ValidTestConfig() {
+ super(new TestConfigBuilder.TestEmojiDataLoader());
+ }
+ }
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/EmojiCompatTest.java b/emoji/core/tests/java/android/support/text/emoji/EmojiCompatTest.java
new file mode 100644
index 0000000..05c1367
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/EmojiCompatTest.java
@@ -0,0 +1,478 @@
+/*
+ * 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.text.emoji;
+
+import static android.support.text.emoji.TestConfigBuilder.TestConfig;
+import static android.support.text.emoji.TestConfigBuilder.WaitingDataLoader;
+import static android.support.text.emoji.TestConfigBuilder.config;
+import static android.support.text.emoji.util.Emoji.CHAR_DEFAULT_EMOJI_STYLE;
+import static android.support.text.emoji.util.Emoji.CHAR_DEFAULT_TEXT_STYLE;
+import static android.support.text.emoji.util.Emoji.CHAR_DIGIT;
+import static android.support.text.emoji.util.Emoji.CHAR_FITZPATRICK;
+import static android.support.text.emoji.util.Emoji.CHAR_VS_EMOJI;
+import static android.support.text.emoji.util.Emoji.CHAR_VS_TEXT;
+import static android.support.text.emoji.util.Emoji.DEFAULT_TEXT_STYLE;
+import static android.support.text.emoji.util.Emoji.EMOJI_ASTERISK_KEYCAP;
+import static android.support.text.emoji.util.Emoji.EMOJI_DIGIT_ES;
+import static android.support.text.emoji.util.Emoji.EMOJI_DIGIT_ES_KEYCAP;
+import static android.support.text.emoji.util.Emoji.EMOJI_DIGIT_KEYCAP;
+import static android.support.text.emoji.util.Emoji.EMOJI_FLAG;
+import static android.support.text.emoji.util.Emoji.EMOJI_GENDER;
+import static android.support.text.emoji.util.Emoji.EMOJI_GENDER_WITHOUT_VS;
+import static android.support.text.emoji.util.Emoji.EMOJI_REGIONAL_SYMBOL;
+import static android.support.text.emoji.util.Emoji.EMOJI_SINGLE_CODEPOINT;
+import static android.support.text.emoji.util.Emoji.EMOJI_SKIN_MODIFIER;
+import static android.support.text.emoji.util.Emoji.EMOJI_SKIN_MODIFIER_TYPE_ONE;
+import static android.support.text.emoji.util.Emoji.EMOJI_SKIN_MODIFIER_WITH_VS;
+import static android.support.text.emoji.util.Emoji.EMOJI_UNKNOWN_FLAG;
+import static android.support.text.emoji.util.Emoji.EMOJI_WITH_ZWJ;
+import static android.support.text.emoji.util.EmojiMatcher.hasEmoji;
+import static android.support.text.emoji.util.EmojiMatcher.hasEmojiAt;
+import static android.support.text.emoji.util.EmojiMatcher.hasEmojiCount;
+
+import static junit.framework.TestCase.assertFalse;
+
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Bundle;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.text.emoji.EmojiCompat.Config;
+import android.support.text.emoji.util.Emoji.EmojiMapping;
+import android.support.text.emoji.util.TestString;
+import android.text.Editable;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
+import android.text.SpannedString;
+import android.view.inputmethod.EditorInfo;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class EmojiCompatTest {
+
+ @Before
+ public void setup() {
+ EmojiCompat.reset(config());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testGet_throwsException() throws Exception {
+ EmojiCompat.reset((EmojiCompat) null);
+ EmojiCompat.get();
+ }
+
+ @Test
+ public void testProcess_doesNothing_withNullCharSequence() throws Exception {
+ assertNull(EmojiCompat.get().process(null));
+ }
+
+ @Test
+ public void testProcess_returnsEmptySpanned_withEmptyString() throws Exception {
+ final CharSequence charSequence = EmojiCompat.get().process("");
+ assertNotNull(charSequence);
+ assertEquals(0, charSequence.length());
+ assertThat(charSequence, not(hasEmoji()));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testProcess_withNegativeStartValue() throws Exception {
+ EmojiCompat.get().process("a", -1, 1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testProcess_withNegativeEndValue() throws Exception {
+ EmojiCompat.get().process("a", 1, -1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testProcess_withStartSmallerThanEndValue() throws Exception {
+ EmojiCompat.get().process("aa", 1, 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testProcess_withStartGreaterThanLength() throws Exception {
+ EmojiCompat.get().process("a", 2, 2);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testProcess_withEndGreaterThanLength() throws Exception {
+ EmojiCompat.get().process("a", 0, 2);
+ }
+
+ @Test
+ public void testProcessWithStartEnd_withNoOpValues() throws Exception {
+ final Spannable spannable = new SpannableString(new TestString('a')
+ .withPrefix().withSuffix().toString());
+ // early return check
+ assertSame(spannable, EmojiCompat.get().process(spannable, 0, 0));
+ assertSame(spannable, EmojiCompat.get().process(spannable, 1, 1));
+ assertSame(spannable, EmojiCompat.get().process(spannable, spannable.length(),
+ spannable.length()));
+ }
+
+
+ @Test
+ public void testProcess_doesNotAddEmojiSpan() throws Exception {
+ final String string = "abc";
+ final CharSequence charSequence = EmojiCompat.get().process(string);
+ assertNotNull(charSequence);
+ assertEquals(string, charSequence.toString());
+ assertThat(charSequence, not(hasEmoji()));
+ }
+
+ @Test
+ public void testProcess_addsSingleCodePointEmoji() throws Exception {
+ assertCodePointMatch(EMOJI_SINGLE_CODEPOINT);
+ }
+
+ @Test
+ public void testProcess_addsFlagEmoji() throws Exception {
+ assertCodePointMatch(EMOJI_FLAG);
+ }
+
+ @Test
+ public void testProcess_addsUnknownFlagEmoji() throws Exception {
+ assertCodePointMatch(EMOJI_UNKNOWN_FLAG);
+ }
+
+ @Test
+ public void testProcess_addsRegionalIndicatorSymbol() throws Exception {
+ assertCodePointMatch(EMOJI_REGIONAL_SYMBOL);
+ }
+
+ @Test
+ public void testProcess_addsKeyCapEmoji() throws Exception {
+ assertCodePointMatch(EMOJI_DIGIT_KEYCAP);
+ }
+
+ @Test
+ public void testProcess_doesNotAddEmojiForNumbers() throws Exception {
+ assertCodePointDoesNotMatch(new int[] {CHAR_DIGIT});
+ }
+
+ @Test
+ public void testProcess_doesNotAddEmojiForNumbers_1() throws Exception {
+ final TestString string = new TestString(EMOJI_SINGLE_CODEPOINT).append('1', 'f');
+ CharSequence charSequence = EmojiCompat.get().process(string.toString());
+ assertThat(charSequence, hasEmojiCount(1));
+ }
+
+ @Test
+ public void testProcess_addsVariantSelectorEmoji() throws Exception {
+ assertCodePointMatch(EMOJI_DIGIT_ES);
+ }
+
+ @Test
+ public void testProcess_doesNotAddVariantSelectorTextStyle() throws Exception {
+ assertCodePointDoesNotMatch(new int[]{CHAR_DIGIT, CHAR_VS_TEXT});
+ }
+
+ @Test
+ public void testProcess_addsVariantSelectorAndKeyCapEmoji() throws Exception {
+ assertCodePointMatch(EMOJI_DIGIT_ES_KEYCAP);
+ }
+
+ @Test
+ public void testProcess_doesNotAddEmoji_forVariantBaseWithoutSelector() throws Exception {
+ assertCodePointDoesNotMatch(new int[]{CHAR_DIGIT});
+ }
+
+ @Test
+ public void testProcess_addsAsteriskKeyCapEmoji() throws Exception {
+ assertCodePointMatch(EMOJI_ASTERISK_KEYCAP);
+ }
+
+ @Test
+ public void testProcess_addsSkinModifierEmoji() throws Exception {
+ assertCodePointMatch(EMOJI_SKIN_MODIFIER);
+ assertCodePointMatch(EMOJI_SKIN_MODIFIER_TYPE_ONE);
+ }
+
+ @Test
+ public void testProcess_addsSkinModifierEmoji_withVariantSelector() throws Exception {
+ assertCodePointMatch(EMOJI_SKIN_MODIFIER_WITH_VS);
+ }
+
+ @Test
+ public void testProcess_addsSkinModifierEmoji_270c_withVariantSelector() throws Exception {
+ // 0x270c is a Standardized Variant Base, Emoji Modifier Base and also Emoji
+ // therefore it is different than i.e. 0x1f3c3. The code actually failed for this test
+ // at first.
+ assertCodePointMatch(0xF0734, new int[]{0x270C, CHAR_VS_EMOJI, CHAR_FITZPATRICK});
+ }
+
+ @Test
+ public void testProcess_defaultStyleDoesNotAddSpan() throws Exception {
+ assertCodePointDoesNotMatch(new int[]{CHAR_DEFAULT_TEXT_STYLE});
+ assertCodePointMatch(DEFAULT_TEXT_STYLE);
+ }
+
+ @Test
+ public void testProcess_defaultEmojiStyle_withTextStyleVs() throws Exception {
+ assertCodePointMatch(EMOJI_SINGLE_CODEPOINT.id(),
+ new int[]{CHAR_DEFAULT_EMOJI_STYLE, CHAR_VS_EMOJI});
+ assertCodePointDoesNotMatch(new int[]{CHAR_DEFAULT_EMOJI_STYLE, CHAR_VS_TEXT});
+ }
+
+ @Test
+ public void testProcess_genderEmoji() throws Exception {
+ assertCodePointMatch(EMOJI_GENDER);
+ assertCodePointMatch(EMOJI_GENDER_WITHOUT_VS);
+ }
+
+ @Test
+ public void testProcess_standardizedVariantEmojiExceptions() throws Exception {
+ final int[][] exceptions = new int[][]{
+ {0x2600, 0xF034D},
+ {0x2601, 0xF0167},
+ {0x260E, 0xF034E},
+ {0x261D, 0xF0227},
+ {0x263A, 0xF02A6},
+ {0x2660, 0xF0350},
+ {0x2663, 0xF033F},
+ {0x2665, 0xF033B},
+ {0x2666, 0xF033E},
+ {0x270C, 0xF0079},
+ {0x2744, 0xF0342},
+ {0x2764, 0xF0362}
+ };
+
+ for (int i = 0; i < exceptions.length; i++) {
+ final int[] codepoints = new int[]{exceptions[i][0]};
+ assertCodePointMatch(exceptions[i][1], codepoints);
+ }
+ }
+
+ @Test
+ public void testProcess_addsZwjEmoji() throws Exception {
+ assertCodePointMatch(EMOJI_WITH_ZWJ);
+ }
+
+ @Test
+ public void testProcess_doesNotAddEmojiForNumbersAfterZwjEmo() throws Exception {
+ TestString string = new TestString(EMOJI_WITH_ZWJ).append(0x20, 0x2B, 0x31)
+ .withSuffix().withPrefix();
+ CharSequence charSequence = EmojiCompat.get().process(string.toString());
+ assertThat(charSequence, hasEmojiAt(EMOJI_WITH_ZWJ, string.emojiStartIndex(),
+ string.emojiEndIndex() - 3));
+ assertThat(charSequence, hasEmojiCount(1));
+
+ string = new TestString(EMOJI_WITH_ZWJ).withSuffix().withPrefix();
+ charSequence = EmojiCompat.get().process(string.toString());
+ assertThat(charSequence, hasEmojiCount(1));
+ }
+
+ @Test
+ public void testProcess_withAppend() throws Exception {
+ final Editable editable = new SpannableStringBuilder(new TestString('a').withPrefix()
+ .withSuffix().toString());
+ final int start = 1;
+ final int end = start + EMOJI_SINGLE_CODEPOINT.charCount();
+ editable.insert(start, new TestString(EMOJI_SINGLE_CODEPOINT).toString());
+ EmojiCompat.get().process(editable, start, end);
+ assertThat(editable, hasEmojiCount(1));
+ assertThat(editable, hasEmojiAt(EMOJI_SINGLE_CODEPOINT, start, end));
+ }
+
+ @Test
+ public void testProcess_doesNotCreateSpannable_ifNoEmoji() throws Exception {
+ CharSequence processed = EmojiCompat.get().process("abc");
+ assertNotNull(processed);
+ assertThat(processed, instanceOf(String.class));
+
+ processed = EmojiCompat.get().process(new SpannedString("abc"));
+ assertNotNull(processed);
+ assertThat(processed, instanceOf(SpannedString.class));
+ }
+
+ @Test
+ public void testProcess_reprocess() throws Exception {
+ final String string = new TestString(EMOJI_SINGLE_CODEPOINT)
+ .append(EMOJI_SINGLE_CODEPOINT)
+ .append(EMOJI_SINGLE_CODEPOINT)
+ .withPrefix().withSuffix().toString();
+
+ Spannable processed = (Spannable) EmojiCompat.get().process(string);
+ assertThat(processed, hasEmojiCount(3));
+
+ final EmojiSpan[] spans = processed.getSpans(0, processed.length(), EmojiSpan.class);
+ final Set<EmojiSpan> spanSet = new HashSet<>();
+ for (int i = 0; i < spans.length; i++) {
+ spanSet.add(spans[i]);
+ }
+
+ processed = (Spannable) EmojiCompat.get().process(processed);
+ assertThat(processed, hasEmojiCount(3));
+ // new spans should be new instances
+ final EmojiSpan[] newSpans = processed.getSpans(0, processed.length(), EmojiSpan.class);
+ for (int i = 0; i < newSpans.length; i++) {
+ assertFalse(spanSet.contains(newSpans[i]));
+ }
+ }
+
+ @Test
+ public void testHasGlyph_returnsMetadata() throws Exception {
+ final String sequence = new TestString(EMOJI_FLAG).toString();
+ assertNotNull(EmojiCompat.get().hasEmojiGlyph(sequence));
+ }
+
+ @Test
+ public void testHasGlyph_returnsNullForNonExistentEmoji() throws Exception {
+ final String sequence = new TestString(EMOJI_FLAG).append(0x1111).toString();
+ assertFalse(EmojiCompat.get().hasEmojiGlyph(sequence));
+ }
+
+ @Test
+ public void testHashGlyph_withDefaultEmojiStyles() throws Exception {
+ String sequence = new TestString(new int[]{CHAR_DEFAULT_EMOJI_STYLE}).toString();
+ assertTrue(EmojiCompat.get().hasEmojiGlyph(sequence));
+
+ sequence = new TestString(new int[]{CHAR_DEFAULT_EMOJI_STYLE, CHAR_VS_EMOJI}).toString();
+ assertTrue(EmojiCompat.get().hasEmojiGlyph(sequence));
+
+ sequence = new TestString(new int[]{CHAR_DEFAULT_EMOJI_STYLE, CHAR_VS_TEXT}).toString();
+ assertFalse(EmojiCompat.get().hasEmojiGlyph(sequence));
+ }
+
+ @Test
+ public void testHashGlyph_withMetadataVersion() throws Exception {
+ final String sequence = new TestString(EMOJI_SINGLE_CODEPOINT).toString();
+ assertFalse(EmojiCompat.get().hasEmojiGlyph(sequence, 0));
+ assertTrue(EmojiCompat.get().hasEmojiGlyph(sequence, Integer.MAX_VALUE));
+ }
+
+ @Test
+ public void testIsInitialized_returnsTrueIfLoadSuccess() throws InterruptedException {
+ final WaitingDataLoader metadataLoader = new WaitingDataLoader(true /*success*/);
+ final Config config = new TestConfig(metadataLoader);
+ EmojiCompat.reset(config);
+
+ assertFalse(EmojiCompat.get().isInitialized());
+
+ metadataLoader.getLoaderLatch().countDown();
+ metadataLoader.getTestLatch().await();
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ assertTrue(EmojiCompat.get().isInitialized());
+ }
+
+ @Test
+ public void testIsInitialized_returnsFalseIfLoadFail() throws InterruptedException {
+ final WaitingDataLoader metadataLoader = new WaitingDataLoader(false/*fail*/);
+ final Config config = new TestConfig(metadataLoader);
+ EmojiCompat.reset(config);
+
+ assertFalse(EmojiCompat.get().isInitialized());
+
+ metadataLoader.getLoaderLatch().countDown();
+ metadataLoader.getTestLatch().await();
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ assertFalse(EmojiCompat.get().isInitialized());
+ }
+
+ @Test
+ public void testUpdateEditorInfoAttrs_doesNotSetKeyIfNotInitialized() {
+ final EditorInfo editorInfo = new EditorInfo();
+ editorInfo.extras = new Bundle();
+
+ final WaitingDataLoader metadataLoader = new WaitingDataLoader();
+ final Config config = new TestConfig(metadataLoader);
+ EmojiCompat.reset(config);
+
+ EmojiCompat.get().updateEditorInfoAttrs(editorInfo);
+
+ final Bundle extras = editorInfo.extras;
+ assertFalse(extras.containsKey(EmojiCompat.EDITOR_INFO_METAVERSION_KEY));
+ assertFalse(extras.containsKey(EmojiCompat.EDITOR_INFO_REPLACE_ALL_KEY));
+
+ metadataLoader.getLoaderLatch().countDown();
+ }
+
+ @Test
+ public void testUpdateEditorInfoAttrs_setsKeysIfInitialized() {
+ final EditorInfo editorInfo = new EditorInfo();
+ editorInfo.extras = new Bundle();
+ Config config = new TestConfig().setReplaceAll(false);
+ EmojiCompat.reset(config);
+ EmojiCompat.get().updateEditorInfoAttrs(editorInfo);
+
+ final Bundle extras = editorInfo.extras;
+ assertTrue(extras.containsKey(EmojiCompat.EDITOR_INFO_METAVERSION_KEY));
+ assertTrue(extras.getInt(EmojiCompat.EDITOR_INFO_METAVERSION_KEY) > 0);
+ assertTrue(extras.containsKey(EmojiCompat.EDITOR_INFO_REPLACE_ALL_KEY));
+ assertFalse(extras.getBoolean(EmojiCompat.EDITOR_INFO_REPLACE_ALL_KEY));
+
+ config = new TestConfig().setReplaceAll(true);
+ EmojiCompat.reset(config);
+ EmojiCompat.get().updateEditorInfoAttrs(editorInfo);
+
+ assertTrue(extras.containsKey(EmojiCompat.EDITOR_INFO_REPLACE_ALL_KEY));
+ assertTrue(extras.getBoolean(EmojiCompat.EDITOR_INFO_REPLACE_ALL_KEY));
+ }
+
+ private void assertCodePointMatch(EmojiMapping emoji) {
+ assertCodePointMatch(emoji.id(), emoji.codepoints());
+ }
+
+ private void assertCodePointMatch(int id, int[] codepoints) {
+ TestString string = new TestString(codepoints);
+ CharSequence charSequence = EmojiCompat.get().process(string.toString());
+ assertThat(charSequence, hasEmojiAt(id, string.emojiStartIndex(), string.emojiEndIndex()));
+
+ // case where Emoji is in the middle of string
+ string = new TestString(codepoints).withPrefix().withSuffix();
+ charSequence = EmojiCompat.get().process(string.toString());
+ assertThat(charSequence, hasEmojiAt(id, string.emojiStartIndex(), string.emojiEndIndex()));
+
+ // case where Emoji is at the end of string
+ string = new TestString(codepoints).withSuffix();
+ charSequence = EmojiCompat.get().process(string.toString());
+ assertThat(charSequence, hasEmojiAt(id, string.emojiStartIndex(), string.emojiEndIndex()));
+ }
+
+ private void assertCodePointDoesNotMatch(int[] codepoints) {
+ TestString string = new TestString(codepoints);
+ CharSequence charSequence = EmojiCompat.get().process(string.toString());
+ assertThat(charSequence, not(hasEmoji()));
+
+ string = new TestString(codepoints).withSuffix().withPrefix();
+ charSequence = EmojiCompat.get().process(string.toString());
+ assertThat(charSequence, not(hasEmoji()));
+
+ string = new TestString(codepoints).withPrefix();
+ charSequence = EmojiCompat.get().process(string.toString());
+ assertThat(charSequence, not(hasEmoji()));
+ }
+
+ //FAILS: CHAR_DIGIT, CHAR_VS_EMOJI, CHAR_VS_TEXT
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/EmojiInstrumentationTest.java b/emoji/core/tests/java/android/support/text/emoji/EmojiInstrumentationTest.java
new file mode 100644
index 0000000..eb0ba3a
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/EmojiInstrumentationTest.java
@@ -0,0 +1,249 @@
+/*
+ * 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.text.emoji;
+
+import static android.support.text.emoji.util.Emoji.EMOJI_SINGLE_CODEPOINT;
+import static android.support.text.emoji.util.Emoji.EMOJI_WITH_ZWJ;
+import static android.support.text.emoji.util.EmojiMatcher.hasEmoji;
+import static android.support.text.emoji.util.EmojiMatcher.hasEmojiAt;
+import static android.support.text.emoji.util.EmojiMatcher.hasEmojiCount;
+import static android.support.text.emoji.util.KeyboardUtil.del;
+import static android.support.text.emoji.util.KeyboardUtil.forwardDel;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertThat;
+
+import android.app.Instrumentation;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.text.emoji.test.R;
+import android.support.text.emoji.util.KeyboardUtil;
+import android.support.text.emoji.util.TestString;
+import android.text.Editable;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.Spanned;
+import android.text.style.RelativeSizeSpan;
+import android.util.TypedValue;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class EmojiInstrumentationTest {
+
+ @Rule
+ public ActivityTestRule<TestActivity> mActivityRule = new ActivityTestRule<>(
+ TestActivity.class);
+ private Instrumentation mInstrumentation;
+
+ @BeforeClass
+ public static void setupEmojiCompat() {
+ EmojiCompat.reset(TestConfigBuilder.config());
+ }
+
+ @Before
+ public void setup() {
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ }
+
+ @Test
+ public void testGetSize_withRelativeSizeSpan() throws Exception {
+ final TestActivity activity = mActivityRule.getActivity();
+ final TextView textView = (TextView) activity.findViewById(R.id.text);
+
+ // create a string with single codepoint emoji
+ final TestString string = new TestString(EMOJI_SINGLE_CODEPOINT).withPrefix().withSuffix();
+ final CharSequence charSequence = EmojiCompat.get().process(string.toString());
+ assertNotNull(charSequence);
+ assertThat(charSequence, hasEmojiCount(1));
+
+ final Spannable spanned = (Spannable) charSequence;
+ final EmojiSpan[] spans = spanned.getSpans(0, charSequence.length(), EmojiSpan.class);
+ final EmojiSpan span = spans[0];
+
+ // set text to the charSequence with the EmojiSpan
+ mInstrumentation.runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ textView.setText(charSequence);
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+
+ // record height of the default span
+ final int defaultHeight = span.getHeight();
+
+ // cover the charsequence with RelativeSizeSpan which will triple the size of the
+ // characters.
+ final RelativeSizeSpan sizeSpan = new RelativeSizeSpan(3.0f);
+ spanned.setSpan(sizeSpan, 0, charSequence.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ // set the new text
+ mInstrumentation.runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ textView.setText(charSequence);
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+
+ // record the height measured after RelativeSizeSpan
+ final int heightWithRelativeSpan = span.getHeight();
+
+ // accept 1sp error rate.
+ final float delta = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 1,
+ mInstrumentation.getTargetContext().getResources().getDisplayMetrics());
+ assertEquals(defaultHeight * 3, heightWithRelativeSpan, delta);
+ }
+
+ @Test
+ public void testAppendWithSoftKeyboard() throws Exception {
+ TestActivity activity = mActivityRule.getActivity();
+ final EditText editText = (EditText) activity.findViewById(R.id.editText);
+ final TestString string = new TestString(EMOJI_WITH_ZWJ).withPrefix()
+ .withSuffix();
+ final InputConnection inputConnection = editText.onCreateInputConnection(new EditorInfo());
+ mInstrumentation.runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ KeyboardUtil.setComposingTextInBatch(inputConnection, string.toString());
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+
+ Editable editable = editText.getEditableText();
+
+ // 0xf0950 is the remapped codepoint for WOMEN_WITH_BALL
+ assertThat(editable, hasEmojiAt(EMOJI_WITH_ZWJ, string.emojiStartIndex(),
+ string.emojiEndIndex()));
+ }
+
+ @Test
+ public void testBackDeleteWithSoftKeyboard() throws Exception {
+ TestActivity activity = mActivityRule.getActivity();
+ final EditText editText = (EditText) activity.findViewById(R.id.editText);
+ final TestString string = new TestString(EMOJI_WITH_ZWJ).withPrefix()
+ .withSuffix();
+ final InputConnection inputConnection = editText.onCreateInputConnection(new EditorInfo());
+ mInstrumentation.runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ KeyboardUtil.setComposingTextInBatch(inputConnection, string.toString());
+ Selection.setSelection(editText.getEditableText(), string.emojiEndIndex());
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+ final Editable editable = editText.getEditableText();
+ assertThat(editable, hasEmoji());
+
+ mInstrumentation.runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ KeyboardUtil.deleteSurrondingText(inputConnection, 1, 0);
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+ assertThat(editable, not(hasEmoji()));
+ }
+
+ @Test
+ public void testForwardDeleteWithSoftKeyboard() throws Exception {
+ TestActivity activity = mActivityRule.getActivity();
+ final EditText editText = (EditText) activity.findViewById(R.id.editText);
+ final TestString string = new TestString(EMOJI_WITH_ZWJ).withPrefix()
+ .withSuffix();
+ final InputConnection inputConnection = editText.onCreateInputConnection(new EditorInfo());
+ mInstrumentation.runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ KeyboardUtil.setComposingTextInBatch(inputConnection, string.toString());
+ Selection.setSelection(editText.getEditableText(), string.emojiStartIndex());
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+ final Editable editable = editText.getEditableText();
+ assertThat(editable, hasEmoji());
+
+ mInstrumentation.runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ KeyboardUtil.deleteSurrondingText(inputConnection, 0, 1);
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+ assertThat(editable, not(hasEmoji()));
+ }
+
+ @Test
+ public void testBackDeleteWithHardwareKeyboard() throws Exception {
+ TestActivity activity = mActivityRule.getActivity();
+ final EditText editText = (EditText) activity.findViewById(R.id.editText);
+ final TestString string = new TestString(EMOJI_WITH_ZWJ).withPrefix()
+ .withSuffix();
+ final InputConnection inputConnection = editText.onCreateInputConnection(new EditorInfo());
+ mInstrumentation.runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ KeyboardUtil.setComposingTextInBatch(inputConnection, string.toString());
+ Selection.setSelection(editText.getEditableText(), string.emojiEndIndex());
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+ final Editable editable = editText.getEditableText();
+ assertThat(editable, hasEmoji());
+
+
+ mInstrumentation.sendKeySync(del());
+ mInstrumentation.waitForIdleSync();
+ assertThat(editable, not(hasEmoji()));
+ }
+
+ @Test
+ public void testForwardDeleteWithHardwareKeyboard() throws Exception {
+ TestActivity activity = mActivityRule.getActivity();
+ final EditText editText = (EditText) activity.findViewById(R.id.editText);
+ final TestString string = new TestString(EMOJI_WITH_ZWJ).withPrefix()
+ .withSuffix();
+ final InputConnection inputConnection = editText.onCreateInputConnection(new EditorInfo());
+ mInstrumentation.runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ KeyboardUtil.setComposingTextInBatch(inputConnection, string.toString());
+ Selection.setSelection(editText.getEditableText(), string.emojiStartIndex());
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+ final Editable editable = editText.getEditableText();
+ assertThat(editable, hasEmoji());
+
+ mInstrumentation.sendKeySync(forwardDel());
+ mInstrumentation.waitForIdleSync();
+ assertThat(editable, not(hasEmoji()));
+ }
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/EmojiSpanTest.java b/emoji/core/tests/java/android/support/text/emoji/EmojiSpanTest.java
new file mode 100644
index 0000000..3abf89e
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/EmojiSpanTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.text.emoji;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.graphics.Paint.FontMetricsInt;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.text.TextPaint;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class EmojiSpanTest {
+
+ @Before
+ public void setup() {
+ EmojiCompat.reset(TestConfigBuilder.config());
+ }
+
+ @Test
+ public void testGetSize() throws Exception {
+ final short dimensionX = 18;
+ final short dimensionY = 20;
+ final int fontHeight = 10;
+ final float expectedRatio = fontHeight * 1.0f / dimensionY;
+ final TextPaint paint = mock(TextPaint.class);
+
+ // mock TextPaint to return test font metrics
+ when(paint.getFontMetricsInt(any(FontMetricsInt.class))).thenAnswer(new Answer<Object>() {
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ final FontMetricsInt fontMetrics = (FontMetricsInt) invocation.getArguments()[0];
+ fontMetrics.ascent = 0;
+ fontMetrics.descent = -fontHeight;
+ return null;
+ }
+ });
+
+ final EmojiMetadata metadata = mock(EmojiMetadata.class);
+ when(metadata.getWidth()).thenReturn(dimensionX);
+ when(metadata.getHeight()).thenReturn(dimensionY);
+ final EmojiSpan span = new TypefaceEmojiSpan(metadata);
+
+ final int resultSize = span.getSize(paint, "", 0, 0, null);
+ assertEquals((int) (dimensionX * expectedRatio), resultSize);
+ assertEquals(expectedRatio, span.getRatio());
+ assertEquals((int) (dimensionX * expectedRatio), span.getWidth());
+ assertEquals((int) (dimensionY * expectedRatio), span.getHeight());
+ }
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/HardDeleteTest.java b/emoji/core/tests/java/android/support/text/emoji/HardDeleteTest.java
new file mode 100644
index 0000000..53078ae
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/HardDeleteTest.java
@@ -0,0 +1,220 @@
+/*
+ * 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.text.emoji;
+
+import static android.support.text.emoji.util.Emoji.EMOJI_FLAG;
+import static android.support.text.emoji.util.Emoji.EMOJI_GENDER;
+import static android.support.text.emoji.util.Emoji.EMOJI_WITH_ZWJ;
+import static android.support.text.emoji.util.EmojiMatcher.hasEmoji;
+import static android.support.text.emoji.util.EmojiMatcher.hasEmojiCount;
+import static android.support.text.emoji.util.KeyboardUtil.altDel;
+import static android.support.text.emoji.util.KeyboardUtil.ctrlDel;
+import static android.support.text.emoji.util.KeyboardUtil.del;
+import static android.support.text.emoji.util.KeyboardUtil.fnDel;
+import static android.support.text.emoji.util.KeyboardUtil.forwardDel;
+import static android.support.text.emoji.util.KeyboardUtil.shiftDel;
+import static android.support.text.emoji.util.KeyboardUtil.zero;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.TestCase.assertEquals;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.text.emoji.util.TestString;
+import android.text.Editable;
+import android.text.Selection;
+import android.text.SpannableStringBuilder;
+import android.view.KeyEvent;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class HardDeleteTest {
+
+ private TestString mTestString;
+ private Editable mEditable;
+
+ @BeforeClass
+ public static void setupEmojiCompat() {
+ EmojiCompat.reset(TestConfigBuilder.config());
+ }
+
+ @Before
+ public void setup() {
+ mTestString = new TestString(EMOJI_WITH_ZWJ).withPrefix().withSuffix();
+ mEditable = new SpannableStringBuilder(mTestString.toString());
+ EmojiCompat.get().process(mEditable);
+ assertThat(mEditable, hasEmojiCount(1));
+ assertThat(mEditable, hasEmoji(EMOJI_WITH_ZWJ));
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotDelete_whenKeyCodeIsNotDelOrForwardDel() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+ final KeyEvent event = zero();
+ assertFalse(EmojiCompat.handleOnKeyDown(mEditable, event.getKeyCode(), event));
+ assertThat(mEditable, hasEmoji());
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotDelete_withOtherModifiers() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+ final KeyEvent event = fnDel();
+ assertFalse(EmojiCompat.handleOnKeyDown(mEditable, event.getKeyCode(), event));
+ assertThat(mEditable, hasEmoji());
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotDelete_withAltModifier() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+ final KeyEvent event = altDel();
+ assertFalse(EmojiCompat.handleOnKeyDown(mEditable, event.getKeyCode(), event));
+ assertThat(mEditable, hasEmoji());
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotDelete_withCtrlModifier() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+ final KeyEvent event = ctrlDel();
+ assertFalse(EmojiCompat.handleOnKeyDown(mEditable, event.getKeyCode(), event));
+ assertThat(mEditable, hasEmoji());
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotDelete_withShiftModifier() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+ final KeyEvent event = shiftDel();
+ assertFalse(EmojiCompat.handleOnKeyDown(mEditable, event.getKeyCode(), event));
+ assertThat(mEditable, hasEmoji());
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotDelete_withSelectionLongerThanZeroLength() {
+ // when there is a selection which is longer than 0, it should not delete.
+ Selection.setSelection(mEditable, 0, mEditable.length());
+ final KeyEvent event = del();
+ assertFalse(EmojiCompat.handleOnKeyDown(mEditable, event.getKeyCode(), event));
+ assertThat(mEditable, hasEmoji());
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotDelete_withoutEmojiSpans() {
+ final Editable editable = new SpannableStringBuilder("abc");
+ Selection.setSelection(editable, 1);
+ final KeyEvent event = del();
+ assertFalse(EmojiCompat.handleOnKeyDown(mEditable, event.getKeyCode(), event));
+ assertThat(mEditable, hasEmoji());
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotDelete_whenNoSpansBefore() {
+ Selection.setSelection(mEditable, mTestString.emojiStartIndex());
+ final KeyEvent event = del();
+ assertFalse(EmojiCompat.handleOnKeyDown(mEditable, event.getKeyCode(), event));
+ assertThat(mEditable, hasEmoji());
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testOnKeyDown_deletesEmoji() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+ final KeyEvent event = del();
+ assertTrue(EmojiCompat.handleOnKeyDown(mEditable, event.getKeyCode(), event));
+ assertThat(mEditable, not(hasEmoji()));
+ assertEquals(new TestString().withPrefix().withSuffix().toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotForwardDeleteEmoji_withNoSpansAfter() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+ final KeyEvent event = forwardDel();
+ assertFalse(EmojiCompat.handleOnKeyDown(mEditable, event.getKeyCode(), event));
+ assertThat(mEditable, hasEmoji());
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testOnKeyDown_forwardDeletesEmoji() {
+ Selection.setSelection(mEditable, mTestString.emojiStartIndex());
+ final KeyEvent event = forwardDel();
+ assertTrue(EmojiCompat.handleOnKeyDown(mEditable, event.getKeyCode(), event));
+ assertThat(mEditable, not(hasEmoji()));
+ assertEquals(new TestString().withPrefix().withSuffix().toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testOnKeyDown_deletesEmoji_ifSelectionIsInSpanBoundaries() {
+ Selection.setSelection(mEditable, mTestString.emojiStartIndex() + 1);
+ final KeyEvent delEvent = del();
+ assertTrue(EmojiCompat.handleOnKeyDown(mEditable, delEvent.getKeyCode(), delEvent));
+ assertThat(mEditable, not(hasEmoji()));
+ assertEquals(new TestString().withPrefix().withSuffix().toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testOnKeyDown_deletesEmoji_ifSelectionIsInSpanBoundaries_withForwardDel() {
+ Selection.setSelection(mEditable, mTestString.emojiStartIndex() + 1);
+ final KeyEvent forwardDelEvent = forwardDel();
+ assertTrue(EmojiCompat.handleOnKeyDown(mEditable, forwardDelEvent.getKeyCode(),
+ forwardDelEvent));
+ assertThat(mEditable, not(hasEmoji()));
+ assertEquals(new TestString().withPrefix().withSuffix().toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testOnKeyDown_deletesOnlyEmojiBeforeTheCursor() {
+ // contains three emojis
+ mTestString = new TestString(EMOJI_FLAG)
+ .append(EMOJI_WITH_ZWJ)
+ .append(EMOJI_GENDER)
+ .withPrefix().withSuffix();
+ mEditable = new SpannableStringBuilder(mTestString.toString());
+ EmojiCompat.get().process(mEditable);
+
+ // put the cursor after the second emoji
+ Selection.setSelection(mEditable, mTestString.emojiStartIndex()
+ + EMOJI_FLAG.charCount()
+ + EMOJI_WITH_ZWJ.charCount());
+
+ // delete
+ final KeyEvent forwardDelEvent = del();
+ assertTrue(EmojiCompat.handleOnKeyDown(mEditable, forwardDelEvent.getKeyCode(),
+ forwardDelEvent));
+
+ assertThat(mEditable, hasEmojiCount(2));
+ assertThat(mEditable, hasEmoji(EMOJI_FLAG));
+ assertThat(mEditable, hasEmoji(EMOJI_GENDER));
+
+ assertEquals(new TestString(EMOJI_FLAG).append(EMOJI_GENDER)
+ .withPrefix().withSuffix().toString(), mEditable.toString());
+ }
+
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/InitCallbackTest.java b/emoji/core/tests/java/android/support/text/emoji/InitCallbackTest.java
new file mode 100644
index 0000000..ae07af5
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/InitCallbackTest.java
@@ -0,0 +1,162 @@
+/*
+ * 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.text.emoji;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.text.emoji.TestConfigBuilder.TestConfig;
+import android.support.text.emoji.TestConfigBuilder.WaitingDataLoader;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class InitCallbackTest {
+
+ @Test
+ public void testRegisterInitCallback_callsSuccessCallback() {
+ final EmojiCompat.InitCallback initCallback1 = mock(EmojiCompat.InitCallback.class);
+ final EmojiCompat.InitCallback initCallback2 = mock(EmojiCompat.InitCallback.class);
+
+ final EmojiCompat.Config config = TestConfigBuilder.config();
+ final EmojiCompat emojiCompat = EmojiCompat.reset(config);
+ emojiCompat.registerInitCallback(initCallback1);
+ emojiCompat.registerInitCallback(initCallback2);
+
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ verify(initCallback1, times(1)).onInitialized();
+ verify(initCallback2, times(1)).onInitialized();
+ }
+
+ @Test
+ public void testRegisterInitCallback_callsFailCallback() {
+ final EmojiCompat.InitCallback initCallback1 = mock(EmojiCompat.InitCallback.class);
+ final EmojiCompat.InitCallback initCallback2 = mock(EmojiCompat.InitCallback.class);
+ final EmojiCompat.MetadataLoader loader = mock(EmojiCompat.MetadataLoader.class);
+ doThrow(new RuntimeException("")).when(loader).load(any(EmojiCompat.LoaderCallback
+ .class));
+
+ final EmojiCompat.Config config = new TestConfig(loader);
+ final EmojiCompat emojiCompat = EmojiCompat.reset(config);
+ emojiCompat.registerInitCallback(initCallback1);
+ emojiCompat.registerInitCallback(initCallback2);
+
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ verify(initCallback1, times(1)).onFailed(any(Throwable.class));
+ verify(initCallback2, times(1)).onFailed(any(Throwable.class));
+ }
+
+ @Test
+ public void testRegisterInitCallback_callsFailCallback_whenOnFailCalledByLoader() {
+ final EmojiCompat.InitCallback initCallback = mock(EmojiCompat.InitCallback.class);
+ final EmojiCompat.MetadataLoader loader = new EmojiCompat.MetadataLoader() {
+ @Override
+ public void load(EmojiCompat.LoaderCallback loaderCallback) {
+ loaderCallback.onFailed(new RuntimeException(""));
+ }
+ };
+
+ final EmojiCompat.Config config = new TestConfig(loader);
+ final EmojiCompat emojiCompat = EmojiCompat.reset(config);
+ emojiCompat.registerInitCallback(initCallback);
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ verify(initCallback, times(1)).onFailed(any(Throwable.class));
+ }
+
+ @Test
+ public void testRegisterInitCallback_callsFailCallback_whenMetadataRepoIsNull() {
+ final EmojiCompat.InitCallback initCallback = mock(EmojiCompat.InitCallback.class);
+ final EmojiCompat.MetadataLoader loader = new EmojiCompat.MetadataLoader() {
+ @Override
+ public void load(EmojiCompat.LoaderCallback loaderCallback) {
+ loaderCallback.onLoaded(null);
+ }
+ };
+
+ final EmojiCompat.Config config = new TestConfig(loader);
+ final EmojiCompat emojiCompat = EmojiCompat.reset(config);
+ emojiCompat.registerInitCallback(initCallback);
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ verify(initCallback, times(1)).onFailed(any(Throwable.class));
+ }
+
+ @Test
+ public void testUnregisterInitCallback_doesNotInteractWithCallback()
+ throws InterruptedException {
+ // will be registered
+ final EmojiCompat.InitCallback callback = mock(EmojiCompat.InitCallback.class);
+ // will be registered, and then unregistered before metadata load is complete
+ final EmojiCompat.InitCallback callbackUnregister = mock(EmojiCompat.InitCallback.class);
+ // will be registered to config
+ final EmojiCompat.InitCallback callbackConfigUnregister = mock(
+ EmojiCompat.InitCallback.class);
+ // will be registered to config and then unregistered
+ final EmojiCompat.InitCallback callbackConfig = mock(EmojiCompat.InitCallback.class);
+
+ //make sure that loader does not load before unregister
+ final WaitingDataLoader metadataLoader = new WaitingDataLoader(false/*fail*/);
+ final EmojiCompat.Config config = new TestConfig(metadataLoader)
+ .registerInitCallback(callbackConfig)
+ .registerInitCallback(callbackConfigUnregister)
+ .unregisterInitCallback(callbackConfigUnregister);
+ final EmojiCompat emojiCompat = EmojiCompat.reset(config);
+ // register before metadata is loaded
+ emojiCompat.registerInitCallback(callbackUnregister);
+ emojiCompat.registerInitCallback(callback);
+
+ // unregister before metadata is loaded
+ emojiCompat.unregisterInitCallback(callbackUnregister);
+
+ // fire metadata loaded event
+ metadataLoader.getLoaderLatch().countDown();
+ metadataLoader.getTestLatch().await();
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ verify(callbackUnregister, times(0)).onFailed(any(Throwable.class));
+ verify(callbackConfigUnregister, times(0)).onFailed(any(Throwable.class));
+ verify(callback, times(1)).onFailed(any(Throwable.class));
+ verify(callbackConfig, times(1)).onFailed(any(Throwable.class));
+ }
+
+ @Test
+ public void testInitCallback_addedToConfigAndInstance_callsSuccess() {
+ final EmojiCompat.InitCallback initCallback1 = mock(EmojiCompat.InitCallback.class);
+ final EmojiCompat.InitCallback initCallback2 = mock(EmojiCompat.InitCallback.class);
+
+ final EmojiCompat.Config config = TestConfigBuilder.config()
+ .registerInitCallback(initCallback1);
+ final EmojiCompat emojiCompat = EmojiCompat.reset(config);
+ emojiCompat.registerInitCallback(initCallback2);
+
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ verify(initCallback1, times(1)).onInitialized();
+ verify(initCallback2, times(1)).onInitialized();
+ }
+
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/MetadataRepoTest.java b/emoji/core/tests/java/android/support/text/emoji/MetadataRepoTest.java
new file mode 100644
index 0000000..58764a2
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/MetadataRepoTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.text.emoji;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.text.emoji.MetadataRepo.Node;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class MetadataRepoTest {
+
+ MetadataRepo mMetadataRepo;
+
+ @Before
+ public void clearResourceIndex() {
+ mMetadataRepo = new MetadataRepo();
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testPut_withNullMetadata() throws Exception {
+ mMetadataRepo.put(null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testPut_withEmptyKeys() throws Exception {
+ mMetadataRepo.put(new TestEmojiMetadata(new int[0]));
+ }
+
+ @Test
+ public void testPut_withSingleCodePointMapping() throws Exception {
+ final int[] codePoint = new int[]{1};
+ final TestEmojiMetadata metadata = new TestEmojiMetadata(codePoint);
+ mMetadataRepo.put(metadata);
+ assertSame(metadata, getNode(codePoint));
+ }
+
+ @Test
+ public void testPut_withMultiCodePointsMapping() throws Exception {
+ final int[] codePoint = new int[]{1, 2, 3, 4};
+ final TestEmojiMetadata metadata = new TestEmojiMetadata(codePoint);
+ mMetadataRepo.put(metadata);
+ assertSame(metadata, getNode(codePoint));
+
+ assertEquals(null, getNode(new int[]{1}));
+ assertEquals(null, getNode(new int[]{1, 2}));
+ assertEquals(null, getNode(new int[]{1, 2, 3}));
+ assertEquals(null, getNode(new int[]{1, 2, 3, 5}));
+ }
+
+ @Test
+ public void testPut_sequentialCodePoints() throws Exception {
+ final int[] codePoint1 = new int[]{1, 2, 3, 4};
+ final EmojiMetadata metadata1 = new TestEmojiMetadata(codePoint1);
+
+ final int[] codePoint2 = new int[]{1, 2, 3};
+ final EmojiMetadata metadata2 = new TestEmojiMetadata(codePoint2);
+
+ final int[] codePoint3 = new int[]{1, 2};
+ final EmojiMetadata metadata3 = new TestEmojiMetadata(codePoint3);
+
+ mMetadataRepo.put(metadata1);
+ mMetadataRepo.put(metadata2);
+ mMetadataRepo.put(metadata3);
+
+ assertSame(metadata1, getNode(codePoint1));
+ assertSame(metadata2, getNode(codePoint2));
+ assertSame(metadata3, getNode(codePoint3));
+
+ assertEquals(null, getNode(new int[]{1}));
+ assertEquals(null, getNode(new int[]{1, 2, 3, 4, 5}));
+ }
+
+ final EmojiMetadata getNode(final int[] codepoints) {
+ return getNode(mMetadataRepo.getRootNode(), codepoints, 0);
+ }
+
+ final EmojiMetadata getNode(Node node, final int[] codepoints, int start) {
+ if (codepoints.length < start) return null;
+ if (codepoints.length == start) return node.getData();
+
+ final Node childNode = node.get(codepoints[start]);
+ if (childNode == null) return null;
+ return getNode(childNode, codepoints, start + 1);
+ }
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/SoftDeleteTest.java b/emoji/core/tests/java/android/support/text/emoji/SoftDeleteTest.java
new file mode 100644
index 0000000..3dd29bc
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/SoftDeleteTest.java
@@ -0,0 +1,272 @@
+/*
+ * 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.text.emoji;
+
+import static android.support.text.emoji.util.Emoji.EMOJI_FLAG;
+import static android.support.text.emoji.util.Emoji.EMOJI_WITH_ZWJ;
+import static android.support.text.emoji.util.EmojiMatcher.hasEmoji;
+import static android.support.text.emoji.util.EmojiMatcher.hasEmojiCount;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.TestCase.assertEquals;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.text.emoji.util.Emoji;
+import android.support.text.emoji.util.TestString;
+import android.text.Editable;
+import android.text.Selection;
+import android.text.SpannableStringBuilder;
+import android.view.inputmethod.InputConnection;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SoftDeleteTest {
+ private InputConnection mInputConnection;
+ private TestString mTestString;
+ private Editable mEditable;
+
+ @BeforeClass
+ public static void setupEmojiCompat() {
+ EmojiCompat.reset(TestConfigBuilder.config());
+ }
+
+ @Before
+ public void setup() {
+ mInputConnection = mock(InputConnection.class);
+ mTestString = new TestString(Emoji.EMOJI_WITH_ZWJ).withPrefix().withSuffix();
+ mEditable = new SpannableStringBuilder(mTestString.toString());
+ EmojiCompat.get().process(mEditable);
+ assertThat(mEditable, hasEmojiCount(1));
+ assertThat(mEditable, hasEmoji(EMOJI_WITH_ZWJ));
+ }
+
+ @Test
+ public void testDelete_doesNotDelete_whenSelectionIsUndefined() {
+ // no selection is set on editable
+ assertFalse(EmojiCompat.handleDeleteSurroundingText(mInputConnection, mEditable, 1, 0,
+ false));
+
+ assertThat(mEditable, hasEmoji(EMOJI_WITH_ZWJ));
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testDelete_doesNotDelete_whenThereIsSelectionLongerThanZero() {
+ Selection.setSelection(mEditable, mTestString.emojiStartIndex(),
+ mTestString.emojiEndIndex() + 1);
+
+ assertFalse(EmojiCompat.handleDeleteSurroundingText(mInputConnection, mEditable, 1, 0,
+ false));
+
+ assertThat(mEditable, hasEmoji(EMOJI_WITH_ZWJ));
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testDelete_withNullEditable() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+
+ assertFalse(EmojiCompat.handleDeleteSurroundingText(mInputConnection, null, 1, 0, false));
+
+ assertThat(mEditable, hasEmoji(EMOJI_WITH_ZWJ));
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testDelete_withNullInputConnection() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+
+ assertFalse(EmojiCompat.handleDeleteSurroundingText(null, mEditable, 1, 0, false));
+
+ assertThat(mEditable, hasEmoji(EMOJI_WITH_ZWJ));
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testDelete_withInvalidLength() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+
+ assertFalse(EmojiCompat.handleDeleteSurroundingText(mInputConnection, mEditable, -1, 0,
+ false));
+
+ assertThat(mEditable, hasEmoji(EMOJI_WITH_ZWJ));
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testDelete_withInvalidAfterLength() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+
+ assertFalse(EmojiCompat.handleDeleteSurroundingText(mInputConnection, mEditable, 0, -1,
+ false));
+
+ assertThat(mEditable, hasEmoji(EMOJI_WITH_ZWJ));
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testDelete_backward() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+
+ // backwards delete 1 character, it will delete the emoji
+ assertTrue(EmojiCompat.handleDeleteSurroundingText(mInputConnection, mEditable, 1, 0,
+ false));
+
+ assertThat(mEditable, not(hasEmoji()));
+ assertEquals(new TestString().withPrefix().withSuffix().toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testDelete_backward_inCodepoints() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+
+ // backwards delete 1 character, it will delete the emoji
+ assertTrue(EmojiCompat.handleDeleteSurroundingText(mInputConnection, mEditable, 1, 0,
+ true));
+
+ assertThat(mEditable, not(hasEmoji()));
+ assertEquals(new TestString().withPrefix().withSuffix().toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testDelete_forward() {
+ Selection.setSelection(mEditable, mTestString.emojiStartIndex());
+
+ // forward delete 1 character, it will dele the emoji.
+ assertTrue(EmojiCompat.handleDeleteSurroundingText(mInputConnection, mEditable, 0, 1,
+ false));
+
+ assertThat(mEditable, not(hasEmoji()));
+ assertEquals(new TestString().withPrefix().withSuffix().toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testDelete_forward_inCodepoints() {
+ Selection.setSelection(mEditable, mTestString.emojiStartIndex());
+
+ // forward delete 1 codepoint, it will delete the emoji.
+ assertTrue(EmojiCompat.handleDeleteSurroundingText(mInputConnection, mEditable, 0, 1,
+ false));
+
+ assertThat(mEditable, not(hasEmoji()));
+ assertEquals(new TestString().withPrefix().withSuffix().toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testDelete_backward_doesNotDeleteWhenSelectionAtCharSequenceStart() {
+ // make sure selection at 0 does not do something weird for backward delete
+ Selection.setSelection(mEditable, 0);
+
+ assertFalse(EmojiCompat.handleDeleteSurroundingText(mInputConnection, mEditable, 1, 0,
+ false));
+
+ assertThat(mEditable, hasEmoji());
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testDelete_forward_doesNotDeleteWhenSelectionAtCharSequenceEnd() {
+ // make sure selection at end does not do something weird for forward delete
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+
+ assertFalse(EmojiCompat.handleDeleteSurroundingText(mInputConnection, mEditable, 0, 1,
+ false));
+
+ assertThat(mEditable, hasEmoji());
+ assertEquals(mTestString.toString(), mEditable.toString());
+ }
+
+ @Test
+ public void testDelete_withMultipleCharacters() {
+ // prepare string as abc[emoji]def
+ mTestString = new TestString(EMOJI_FLAG);
+ mEditable = new SpannableStringBuilder("abc" + mTestString.toString() + "def");
+ EmojiCompat.get().process(mEditable);
+
+ // set the selection in the middle of emoji
+ Selection.setSelection(mEditable, "abc".length() + EMOJI_FLAG.charCount() / 2);
+
+ // delete 4 characters forward, 4 character backwards
+ assertTrue(
+ EmojiCompat.handleDeleteSurroundingText(mInputConnection, mEditable, 4, 4, false));
+
+ assertThat(mEditable, not(hasEmoji()));
+ assertEquals("af", mEditable.toString());
+ }
+
+ @Test
+ public void testDelete_withMultipleCodepoints() {
+ // prepare string as abc[emoji]def
+ mTestString = new TestString(EMOJI_FLAG);
+ mEditable = new SpannableStringBuilder("abc" + mTestString.toString() + "def");
+ EmojiCompat.get().process(mEditable);
+
+ // set the selection in the middle of emoji
+ Selection.setSelection(mEditable, "abc".length() + EMOJI_FLAG.charCount() / 2);
+
+ // delete 3 codepoints forward, 3 codepoints backwards
+ assertTrue(
+ EmojiCompat.handleDeleteSurroundingText(mInputConnection, mEditable, 3, 3, true));
+
+ assertThat(mEditable, not(hasEmoji()));
+ assertEquals("af", mEditable.toString());
+ }
+
+ @Test
+ public void testDelete_withMultipleCharacters_withDeleteLengthLongerThanString() {
+ // prepare string as abc[emoji]def
+ mTestString = new TestString(EMOJI_FLAG);
+ mEditable = new SpannableStringBuilder("abc" + mTestString.toString() + "def");
+ EmojiCompat.get().process(mEditable);
+
+ // set the selection in the middle of emoji
+ Selection.setSelection(mEditable, "abc".length() + EMOJI_FLAG.charCount() / 2);
+
+ assertTrue(EmojiCompat.handleDeleteSurroundingText(mInputConnection, mEditable, 100, 100,
+ false));
+
+ assertThat(mEditable, not(hasEmoji()));
+ assertEquals("", mEditable.toString());
+ }
+
+ @Test
+ public void testDelete_withMultipleCodepoints_withDeleteLengthLongerThanString() {
+ // prepare string as abc[emoji]def
+ mTestString = new TestString(EMOJI_FLAG);
+ mEditable = new SpannableStringBuilder("abc" + mTestString.toString() + "def");
+ EmojiCompat.get().process(mEditable);
+
+ // set the selection in the middle of emoji
+ Selection.setSelection(mEditable, "abc".length() + EMOJI_FLAG.charCount() / 2);
+
+ assertTrue(EmojiCompat.handleDeleteSurroundingText(mInputConnection, mEditable, 100, 100,
+ true));
+
+ assertThat(mEditable, not(hasEmoji()));
+ assertEquals("", mEditable.toString());
+ }
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/TestActivity.java b/emoji/core/tests/java/android/support/text/emoji/TestActivity.java
new file mode 100644
index 0000000..06dfcf9
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/TestActivity.java
@@ -0,0 +1,29 @@
+/*
+ * 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.text.emoji;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.text.emoji.test.R;
+
+public class TestActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_default);
+ }
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/TestConfigBuilder.java b/emoji/core/tests/java/android/support/text/emoji/TestConfigBuilder.java
new file mode 100644
index 0000000..bc3eec9
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/TestConfigBuilder.java
@@ -0,0 +1,117 @@
+/*
+ * 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.text.emoji;
+
+import static org.junit.Assert.fail;
+
+import android.content.res.AssetManager;
+import android.support.annotation.GuardedBy;
+import android.support.test.InstrumentationRegistry;
+
+import java.util.concurrent.CountDownLatch;
+
+public class TestConfigBuilder {
+ public static EmojiCompat.Config config() {
+ return new TestConfig().setReplaceAll(true);
+ }
+
+ public static class TestConfig extends EmojiCompat.Config {
+ TestConfig() {
+ super(new TestEmojiDataLoader());
+ }
+
+ TestConfig(final EmojiCompat.MetadataLoader metadataLoader) {
+ super(metadataLoader);
+ }
+ }
+
+ public static class WaitingDataLoader implements EmojiCompat.MetadataLoader {
+ private final CountDownLatch mLoaderLatch;
+ private final CountDownLatch mTestLatch;
+ private final boolean mSuccess;
+
+ public WaitingDataLoader(boolean success) {
+ mLoaderLatch = new CountDownLatch(1);
+ mTestLatch = new CountDownLatch(1);
+ mSuccess = success;
+ }
+
+ public WaitingDataLoader() {
+ this(true);
+ }
+
+ public CountDownLatch getLoaderLatch() {
+ return mLoaderLatch;
+ }
+
+ public CountDownLatch getTestLatch() {
+ return mTestLatch;
+ }
+
+ @Override
+ public void load(final EmojiCompat.LoaderCallback loaderCallback) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ mLoaderLatch.await();
+ if (mSuccess) {
+ loaderCallback.onLoaded(new MetadataRepo());
+ } else {
+ loaderCallback.onFailed(null);
+ }
+
+ mTestLatch.countDown();
+ } catch (Throwable e) {
+ fail();
+ }
+ }
+ }).start();
+ }
+ }
+
+ public static class TestEmojiDataLoader implements EmojiCompat.MetadataLoader {
+ static final Object sMetadataRepoLock = new Object();
+ // keep a static instance to in order not to slow down the tests
+ @GuardedBy("sMetadataRepoLock")
+ static volatile MetadataRepo sMetadataRepo;
+
+ TestEmojiDataLoader() {
+ }
+
+ @Override
+ public void load(EmojiCompat.LoaderCallback loaderCallback) {
+ if (sMetadataRepo == null) {
+ synchronized (sMetadataRepoLock) {
+ if (sMetadataRepo == null) {
+ try {
+ final AssetManager assetManager =
+ InstrumentationRegistry.getContext().getAssets();
+ sMetadataRepo = MetadataRepo.create(assetManager,
+ "NotoColorEmojiCompat.ttf");
+ } catch (Throwable e) {
+ loaderCallback.onFailed(e);
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+
+ loaderCallback.onLoaded(sMetadataRepo);
+ }
+ }
+
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/TestEmojiMetadata.java b/emoji/core/tests/java/android/support/text/emoji/TestEmojiMetadata.java
new file mode 100644
index 0000000..68337ba
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/TestEmojiMetadata.java
@@ -0,0 +1,46 @@
+/*
+ * 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.text.emoji;
+
+public class TestEmojiMetadata extends EmojiMetadata {
+ private final int[] mCodePoints;
+ private int mId;
+
+ TestEmojiMetadata(int[] codePoints, int id) {
+ super(null, 0);
+ mCodePoints = codePoints;
+ mId = id;
+ }
+
+ TestEmojiMetadata(int[] codePoints) {
+ this(codePoints, 0);
+ }
+
+ @Override
+ public int getId() {
+ return mId;
+ }
+
+ @Override
+ public int getCodepointAt(int index) {
+ return mCodePoints[index];
+ }
+
+ @Override
+ public int getCodepointsLength() {
+ return mCodePoints.length;
+ }
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/UninitializedStateTest.java b/emoji/core/tests/java/android/support/text/emoji/UninitializedStateTest.java
new file mode 100644
index 0000000..affda10
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/UninitializedStateTest.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 android.support.text.emoji;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.text.emoji.TestConfigBuilder.TestConfig;
+import android.support.text.emoji.TestConfigBuilder.WaitingDataLoader;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class UninitializedStateTest {
+
+ private WaitingDataLoader mWaitingDataLoader;
+
+ @Before
+ public void setup() {
+ mWaitingDataLoader = new WaitingDataLoader(true);
+ final EmojiCompat.Config config = new TestConfig(mWaitingDataLoader);
+ EmojiCompat.reset(config);
+ }
+
+ @After
+ public void after() {
+ mWaitingDataLoader.getLoaderLatch().countDown();
+ mWaitingDataLoader.getTestLatch().countDown();
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testHasEmojiGlyph() throws Exception {
+ EmojiCompat.get().hasEmojiGlyph("anystring");
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testHasEmojiGlyph_withMetadataVersion() throws Exception {
+ EmojiCompat.get().hasEmojiGlyph("anystring", 1);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testProcess() throws Exception {
+ EmojiCompat.get().process("anystring");
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testProcess_withStartEnd() throws Exception {
+ EmojiCompat.get().process("anystring", 1, 2);
+ }
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/util/Emoji.java b/emoji/core/tests/java/android/support/text/emoji/util/Emoji.java
new file mode 100644
index 0000000..d38e580
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/util/Emoji.java
@@ -0,0 +1,110 @@
+/*
+ * 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.text.emoji.util;
+
+import android.support.annotation.NonNull;
+
+public class Emoji {
+
+ public static final int CHAR_KEYCAP = 0x20E3;
+ public static final int CHAR_DIGIT = 0x0039;
+ public static final int CHAR_ZWJ = 0x200D;
+ public static final int CHAR_VS_EMOJI = 0xFE0f;
+ public static final int CHAR_VS_TEXT = 0xFE0E;
+ public static final int CHAR_FITZPATRICK = 0x1F3FE;
+ public static final int CHAR_FITZPATRICK_TYPE_1 = 0x1F3fB;
+ public static final int CHAR_DEFAULT_TEXT_STYLE = 0x26F9;
+ public static final int CHAR_DEFAULT_EMOJI_STYLE = 0x1f3A2;
+ public static final int CHAR_FEMALE_SIGN = 0x2640;
+ public static final int CHAR_MAN = 0x1F468;
+ public static final int CHAR_HEART = 0x2764;
+ public static final int CHAR_KISS = 0x1F48B;
+ public static final int CHAR_REGIONAL_SYMBOL = 0x1F1E8;
+ public static final int CHAR_ASTERISK = 0x002A;
+
+ public static final EmojiMapping EMOJI_SINGLE_CODEPOINT = new EmojiMapping(
+ new int[]{CHAR_DEFAULT_EMOJI_STYLE}, 0xF01B4);
+
+ public static final EmojiMapping EMOJI_WITH_ZWJ = new EmojiMapping(
+ new int[]{CHAR_MAN, CHAR_ZWJ, CHAR_HEART, CHAR_VS_EMOJI, CHAR_ZWJ, CHAR_KISS, CHAR_ZWJ,
+ CHAR_MAN}, 0xF051F);
+
+ public static final EmojiMapping EMOJI_GENDER = new EmojiMapping(new int[]{
+ CHAR_DEFAULT_TEXT_STYLE, CHAR_VS_EMOJI, CHAR_ZWJ, CHAR_FEMALE_SIGN}, 0xF0950);
+
+ public static final EmojiMapping EMOJI_FLAG = new EmojiMapping(
+ new int[]{CHAR_REGIONAL_SYMBOL, CHAR_REGIONAL_SYMBOL}, 0xF03A0);
+
+ public static final EmojiMapping EMOJI_GENDER_WITHOUT_VS = new EmojiMapping(
+ new int[]{CHAR_DEFAULT_TEXT_STYLE, CHAR_ZWJ, CHAR_FEMALE_SIGN}, 0xF0950);
+
+ public static final EmojiMapping DEFAULT_TEXT_STYLE = new EmojiMapping(
+ new int[]{CHAR_DEFAULT_TEXT_STYLE, CHAR_VS_EMOJI}, 0xF04C6);
+
+ public static final EmojiMapping EMOJI_REGIONAL_SYMBOL = new EmojiMapping(
+ new int[]{CHAR_REGIONAL_SYMBOL}, 0xF0025);
+
+ public static final EmojiMapping EMOJI_UNKNOWN_FLAG = new EmojiMapping(
+ new int[]{0x1F1FA, 0x1F1F3}, 0xF0599);
+
+ public static final EmojiMapping EMOJI_DIGIT_ES = new EmojiMapping(
+ new int[]{CHAR_DIGIT, CHAR_VS_EMOJI}, 0xF0340);
+
+ public static final EmojiMapping EMOJI_DIGIT_KEYCAP = new EmojiMapping(
+ new int[]{CHAR_DIGIT, CHAR_KEYCAP}, 0xF0377);
+
+ public static final EmojiMapping EMOJI_DIGIT_ES_KEYCAP = new EmojiMapping(
+ new int[]{CHAR_DIGIT, CHAR_VS_EMOJI, CHAR_KEYCAP}, 0xF0377);
+
+ public static final EmojiMapping EMOJI_ASTERISK_KEYCAP = new EmojiMapping(
+ new int[]{CHAR_ASTERISK, CHAR_VS_EMOJI, CHAR_KEYCAP}, 0xF051D);
+
+ public static final EmojiMapping EMOJI_SKIN_MODIFIER = new EmojiMapping(
+ new int[]{CHAR_MAN, CHAR_FITZPATRICK}, 0xF0603);
+
+ public static final EmojiMapping EMOJI_SKIN_MODIFIER_TYPE_ONE = new EmojiMapping(
+ new int[]{CHAR_MAN, CHAR_FITZPATRICK_TYPE_1}, 0xF0606);
+
+ public static final EmojiMapping EMOJI_SKIN_MODIFIER_WITH_VS = new EmojiMapping(
+ new int[]{CHAR_MAN, CHAR_VS_EMOJI, CHAR_FITZPATRICK_TYPE_1}, 0xF0606);
+
+ public static class EmojiMapping {
+ private final int[] mCodepoints;
+ private final int mId;
+
+ private EmojiMapping(@NonNull final int[] codepoints, final int id) {
+ mCodepoints = codepoints;
+ mId = id;
+ }
+
+ public final int[] codepoints() {
+ return mCodepoints;
+ }
+
+ public final int id() {
+ return mId;
+ }
+
+ public final int charCount() {
+ int count = 0;
+ for (int i = 0; i < mCodepoints.length; i++) {
+ count += Character.charCount(mCodepoints[i]);
+ }
+ return count;
+ }
+ }
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/util/EmojiMatcher.java b/emoji/core/tests/java/android/support/text/emoji/util/EmojiMatcher.java
new file mode 100644
index 0000000..20f656d
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/util/EmojiMatcher.java
@@ -0,0 +1,256 @@
+/*
+ * 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.text.emoji.util;
+
+import static org.mockito.Matchers.argThat;
+
+import android.support.text.emoji.EmojiSpan;
+import android.text.Spanned;
+import android.text.TextUtils;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+/**
+ * Utility class that includes matchers specific to emojis and EmojiSpans.
+ */
+public class EmojiMatcher {
+
+ public static Matcher<CharSequence> hasEmojiAt(final int id, final int start,
+ final int end) {
+ return new EmojiResourceMatcher(id, start, end);
+ }
+
+ public static Matcher<CharSequence> hasEmojiAt(final Emoji.EmojiMapping emojiMapping,
+ final int start, final int end) {
+ return new EmojiResourceMatcher(emojiMapping.id(), start, end);
+ }
+
+ public static Matcher<CharSequence> hasEmojiAt(final int start, final int end) {
+ return new EmojiResourceMatcher(-1, start, end);
+ }
+
+ public static Matcher<CharSequence> hasEmoji(final int id) {
+ return new EmojiResourceMatcher(id, -1, -1);
+ }
+
+ public static Matcher<CharSequence> hasEmoji(final Emoji.EmojiMapping emojiMapping) {
+ return new EmojiResourceMatcher(emojiMapping.id(), -1, -1);
+ }
+
+ public static Matcher<CharSequence> hasEmoji() {
+ return new EmojiSpanMatcher();
+ }
+
+ public static Matcher<CharSequence> hasEmojiCount(final int count) {
+ return new EmojiCountMatcher(count);
+ }
+
+ public static <T extends CharSequence> T sameCharSequence(final T expected) {
+ return argThat(new BaseMatcher<T>() {
+ @Override
+ public boolean matches(Object o) {
+ if (o instanceof CharSequence && expected.getClass() == o.getClass()) {
+ return TextUtils.equals(expected, (CharSequence) o);
+ }
+ return false;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("doesn't match " + expected);
+ }
+ });
+ }
+
+ private static class EmojiSpanMatcher extends TypeSafeMatcher<CharSequence> {
+
+ private EmojiSpan[] mSpans;
+
+ EmojiSpanMatcher() {
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("should have EmojiSpans");
+ }
+
+ @Override
+ protected void describeMismatchSafely(final CharSequence charSequence,
+ Description mismatchDescription) {
+ mismatchDescription.appendText(" has no EmojiSpans");
+ }
+
+ @Override
+ protected boolean matchesSafely(final CharSequence charSequence) {
+ if (charSequence == null) return false;
+ if (!(charSequence instanceof Spanned)) return false;
+ mSpans = ((Spanned) charSequence).getSpans(0, charSequence.length(), EmojiSpan.class);
+ return mSpans.length != 0;
+ }
+ }
+
+ private static class EmojiCountMatcher extends TypeSafeMatcher<CharSequence> {
+
+ private final int mCount;
+ private EmojiSpan[] mSpans;
+
+ EmojiCountMatcher(final int count) {
+ mCount = count;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("should have ").appendValue(mCount).appendText(" EmojiSpans");
+ }
+
+ @Override
+ protected void describeMismatchSafely(final CharSequence charSequence,
+ Description mismatchDescription) {
+ mismatchDescription.appendText(" has ");
+ if (mSpans == null) {
+ mismatchDescription.appendValue("no");
+ } else {
+ mismatchDescription.appendValue(mSpans.length);
+ }
+
+ mismatchDescription.appendText(" EmojiSpans");
+ }
+
+ @Override
+ protected boolean matchesSafely(final CharSequence charSequence) {
+ if (charSequence == null) return false;
+ if (!(charSequence instanceof Spanned)) return false;
+ mSpans = ((Spanned) charSequence).getSpans(0, charSequence.length(), EmojiSpan.class);
+ return mSpans.length == mCount;
+ }
+ }
+
+ private static class EmojiResourceMatcher extends TypeSafeMatcher<CharSequence> {
+ private static final int ERR_NONE = 0;
+ private static final int ERR_SPANNABLE_NULL = 1;
+ private static final int ERR_NO_SPANS = 2;
+ private static final int ERR_WRONG_INDEX = 3;
+ private final int mResId;
+ private final int mStart;
+ private final int mEnd;
+ private int mError = ERR_NONE;
+ private int mActualStart = -1;
+ private int mActualEnd = -1;
+
+ EmojiResourceMatcher(int resId, int start, int end) {
+ mResId = resId;
+ mStart = start;
+ mEnd = end;
+ }
+
+ @Override
+ public void describeTo(final Description description) {
+ if (mResId == -1) {
+ description.appendText("should have EmojiSpan at ")
+ .appendValue("[" + mStart + "," + mEnd + "]");
+ } else if (mStart == -1 && mEnd == -1) {
+ description.appendText("should have EmojiSpan with resource id ")
+ .appendValue(Integer.toHexString(mResId));
+ } else {
+ description.appendText("should have EmojiSpan with resource id ")
+ .appendValue(Integer.toHexString(mResId))
+ .appendText(" at ")
+ .appendValue("[" + mStart + "," + mEnd + "]");
+ }
+ }
+
+ @Override
+ protected void describeMismatchSafely(final CharSequence charSequence,
+ Description mismatchDescription) {
+ int offset = 0;
+ mismatchDescription.appendText("[");
+ while (offset < charSequence.length()) {
+ int codepoint = Character.codePointAt(charSequence, offset);
+ mismatchDescription.appendText(Integer.toHexString(codepoint));
+ offset += Character.charCount(codepoint);
+ if (offset < charSequence.length()) {
+ mismatchDescription.appendText(",");
+ }
+ }
+ mismatchDescription.appendText("]");
+
+ switch (mError) {
+ case ERR_NO_SPANS:
+ mismatchDescription.appendText(" had no spans");
+ break;
+ case ERR_SPANNABLE_NULL:
+ mismatchDescription.appendText(" was null");
+ break;
+ case ERR_WRONG_INDEX:
+ mismatchDescription.appendText(" had Emoji at ")
+ .appendValue("[" + mActualStart + "," + mActualEnd + "]");
+ break;
+ default:
+ mismatchDescription.appendText(" does not have an EmojiSpan with given "
+ + "resource id ");
+ }
+ }
+
+ @Override
+ protected boolean matchesSafely(final CharSequence charSequence) {
+ if (charSequence == null) {
+ mError = ERR_SPANNABLE_NULL;
+ return false;
+ }
+
+ if (!(charSequence instanceof Spanned)) {
+ mError = ERR_NO_SPANS;
+ return false;
+ }
+
+ Spanned spanned = (Spanned) charSequence;
+ final EmojiSpan[] spans = spanned.getSpans(0, charSequence.length(), EmojiSpan.class);
+
+ if (spans.length == 0) {
+ mError = ERR_NO_SPANS;
+ return false;
+ }
+
+ if (mStart == -1 && mEnd == -1) {
+ for (int index = 0; index < spans.length; index++) {
+ if (mResId == spans[index].getId()) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ for (int index = 0; index < spans.length; index++) {
+ if (mResId == -1 || mResId == spans[index].getId()) {
+ mActualStart = spanned.getSpanStart(spans[index]);
+ mActualEnd = spanned.getSpanEnd(spans[index]);
+ if (mActualStart == mStart && mActualEnd == mEnd) {
+ return true;
+ }
+ }
+ }
+
+ if (mActualStart != -1 && mActualEnd != -1) {
+ mError = ERR_WRONG_INDEX;
+ }
+
+ return false;
+ }
+ }
+ }
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/util/KeyboardUtil.java b/emoji/core/tests/java/android/support/text/emoji/util/KeyboardUtil.java
new file mode 100644
index 0000000..4764455
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/util/KeyboardUtil.java
@@ -0,0 +1,79 @@
+/*
+ * 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.text.emoji.util;
+
+import android.view.KeyEvent;
+import android.view.inputmethod.InputConnection;
+
+/**
+ * Utility class for KeyEvents
+ */
+public class KeyboardUtil {
+ private static final int ALT = KeyEvent.META_ALT_ON | KeyEvent.META_ALT_LEFT_ON;
+ private static final int CTRL = KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON;
+ private static final int SHIFT = KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_LEFT_ON;
+ private static final int FN = KeyEvent.META_FUNCTION_ON;
+
+ public static KeyEvent zero() {
+ return keyEvent(KeyEvent.KEYCODE_0);
+ }
+
+ public static KeyEvent del() {
+ return keyEvent(KeyEvent.KEYCODE_DEL);
+ }
+
+ public static KeyEvent altDel() {
+ return keyEvent(KeyEvent.KEYCODE_DEL, ALT);
+ }
+
+ public static KeyEvent ctrlDel() {
+ return keyEvent(KeyEvent.KEYCODE_DEL, CTRL);
+ }
+
+ public static KeyEvent shiftDel() {
+ return keyEvent(KeyEvent.KEYCODE_DEL, SHIFT);
+ }
+
+ public static KeyEvent fnDel() {
+ return keyEvent(KeyEvent.KEYCODE_DEL, FN);
+ }
+
+ public static KeyEvent forwardDel() {
+ return keyEvent(KeyEvent.KEYCODE_FORWARD_DEL);
+ }
+
+ public static KeyEvent keyEvent(int keycode, int metaState) {
+ final long currentTime = System.currentTimeMillis();
+ return new KeyEvent(currentTime, currentTime, KeyEvent.ACTION_DOWN, keycode, 0, metaState);
+ }
+
+ public static KeyEvent keyEvent(int keycode) {
+ final long currentTime = System.currentTimeMillis();
+ return new KeyEvent(currentTime, currentTime, KeyEvent.ACTION_DOWN, keycode, 0);
+ }
+
+ public static void setComposingTextInBatch(InputConnection input, CharSequence text) {
+ input.beginBatchEdit();
+ input.setComposingText(text, 1);
+ input.endBatchEdit();
+ }
+
+ public static void deleteSurrondingText(InputConnection input, int before, int after) {
+ input.beginBatchEdit();
+ input.deleteSurroundingText(before, after);
+ input.endBatchEdit();
+ }
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/util/TestString.java b/emoji/core/tests/java/android/support/text/emoji/util/TestString.java
new file mode 100644
index 0000000..8f2331e
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/util/TestString.java
@@ -0,0 +1,107 @@
+/*
+ * 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.text.emoji.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility class used to create strings with emojis during tests.
+ */
+public class TestString {
+
+ private static final List<Integer> EMPTY_LIST = new ArrayList<>();
+
+ private static final String EXTRA = "ab";
+ private final List<Integer> mCodePoints;
+ private String mString;
+ private final String mValue;
+ private boolean mHasSuffix;
+ private boolean mHasPrefix;
+
+ public TestString(int... codePoints) {
+ if (codePoints.length == 0) {
+ mCodePoints = EMPTY_LIST;
+ } else {
+ mCodePoints = new ArrayList<>();
+ append(codePoints);
+ }
+ mValue = null;
+ }
+
+ public TestString(Emoji.EmojiMapping emojiMapping) {
+ this(emojiMapping.codepoints());
+ }
+
+ public TestString(String string) {
+ mCodePoints = EMPTY_LIST;
+ mValue = string;
+ }
+
+ public TestString append(int... codePoints) {
+ for (int i = 0; i < codePoints.length; i++) {
+ mCodePoints.add(codePoints[i]);
+ }
+ return this;
+ }
+
+ public TestString append(Emoji.EmojiMapping emojiMapping) {
+ return append(emojiMapping.codepoints());
+ }
+
+ public TestString withSuffix() {
+ mHasSuffix = true;
+ return this;
+ }
+
+ public TestString withPrefix() {
+ mHasPrefix = true;
+ return this;
+ }
+
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ if (mHasPrefix) {
+ builder.append(EXTRA);
+ }
+
+ for (int index = 0; index < mCodePoints.size(); index++) {
+ builder.append(Character.toChars(mCodePoints.get(index)));
+ }
+
+ if (mValue != null) {
+ builder.append(mValue);
+ }
+
+ if (mHasSuffix) {
+ builder.append(EXTRA);
+ }
+ mString = builder.toString();
+ return mString;
+ }
+
+ public int emojiStartIndex() {
+ if (mHasPrefix) return EXTRA.length();
+ return 0;
+ }
+
+ public int emojiEndIndex() {
+ if (mHasSuffix) return mString.lastIndexOf(EXTRA);
+ return mString.length();
+ }
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/widget/EmojiEditableFactoryTest.java b/emoji/core/tests/java/android/support/text/emoji/widget/EmojiEditableFactoryTest.java
new file mode 100644
index 0000000..f75e956
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/widget/EmojiEditableFactoryTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.text.emoji.widget;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertSame;
+import static junit.framework.TestCase.assertNotNull;
+
+import static org.hamcrest.Matchers.arrayWithSize;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.text.emoji.EmojiMetadata;
+import android.support.text.emoji.EmojiSpan;
+import android.support.text.emoji.TypefaceEmojiSpan;
+import android.text.Editable;
+import android.text.SpannableString;
+import android.text.Spanned;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class EmojiEditableFactoryTest {
+
+ @Test
+ public void testGetInstance() {
+ final Editable.Factory instance = EmojiEditableFactory.getInstance();
+ assertNotNull(instance);
+
+ final Editable.Factory instance2 = EmojiEditableFactory.getInstance();
+ assertSame(instance, instance2);
+ }
+
+ @Test
+ public void testNewEditable_returnsEditable() {
+ final Editable editable = EmojiEditableFactory.getInstance().newEditable("abc");
+ assertNotNull(editable);
+ assertThat(editable, instanceOf(Editable.class));
+ }
+
+ @Test
+ public void testNewEditable_preservesCharSequenceData() {
+ final String string = "abc";
+ final SpannableString str = new SpannableString(string);
+ final EmojiMetadata metadata = mock(EmojiMetadata.class);
+ final EmojiSpan span = new TypefaceEmojiSpan(metadata);
+ str.setSpan(span, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ final Editable editable = EmojiEditableFactory.getInstance().newEditable(str);
+ assertNotNull(editable);
+ assertEquals(string, editable.toString());
+ final EmojiSpan[] spans = editable.getSpans(0, 1, EmojiSpan.class);
+ assertThat(spans, arrayWithSize(1));
+ assertSame(spans[0], span);
+ }
+
+ @Test
+ public void testNewEditable_returnsEmojiSpannableIfWatcherClassExists() {
+ Class clazz = null;
+ try {
+ String className = "android.text.DynamicLayout$ChangeWatcher";
+ clazz = getClass().getClassLoader().loadClass(className);
+ } catch (Throwable t) {
+ // ignore
+ }
+
+ if (clazz == null) {
+ final Editable editable = EmojiEditableFactory.getInstance().newEditable("");
+ assertThat(editable, instanceOf(Editable.class));
+ } else {
+ final Editable editable = EmojiEditableFactory.getInstance().newEditable("");
+ assertThat(editable, instanceOf(SpannableBuilder.class));
+ }
+ }
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/widget/EmojiInputConnectionTest.java b/emoji/core/tests/java/android/support/text/emoji/widget/EmojiInputConnectionTest.java
new file mode 100644
index 0000000..4202c38
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/widget/EmojiInputConnectionTest.java
@@ -0,0 +1,158 @@
+/*
+ * 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.text.emoji.widget;
+
+import static android.support.text.emoji.util.EmojiMatcher.hasEmoji;
+
+import static junit.framework.Assert.assertFalse;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.os.Build;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.text.emoji.EmojiCompat;
+import android.support.text.emoji.TestConfigBuilder;
+import android.support.text.emoji.util.Emoji;
+import android.support.text.emoji.util.TestString;
+import android.text.Editable;
+import android.text.Selection;
+import android.text.SpannableStringBuilder;
+import android.view.inputmethod.EditorInfo;
+import android.widget.TextView;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class EmojiInputConnectionTest {
+
+ private android.view.inputmethod.InputConnection mInputConnection;
+ private TestString mTestString;
+ private Editable mEditable;
+ private EmojiInputConnection mEmojiEmojiInputConnection;
+
+ @BeforeClass
+ public static void setupEmojiCompat() {
+ EmojiCompat.reset(TestConfigBuilder.config());
+ }
+
+ @Before
+ public void setup() {
+ mTestString = new TestString(Emoji.EMOJI_WITH_ZWJ).withPrefix().withSuffix();
+ mEditable = new SpannableStringBuilder(mTestString.toString());
+ mInputConnection = mock(android.view.inputmethod.InputConnection.class);
+ final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ final TextView textView = spy(new TextView(context));
+ EmojiCompat.get().process(mEditable);
+ assertThat(mEditable, hasEmoji());
+
+ doReturn(mEditable).when(textView).getEditableText();
+ when(mInputConnection.deleteSurroundingText(anyInt(), anyInt())).thenReturn(false);
+ setupDeleteSurroundingText();
+
+ mEmojiEmojiInputConnection = new EmojiInputConnection(textView, mInputConnection,
+ new EditorInfo());
+ }
+
+ @TargetApi(Build.VERSION_CODES.N)
+ private void setupDeleteSurroundingText() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ when(mInputConnection.deleteSurroundingTextInCodePoints(anyInt(), anyInt())).thenReturn(
+ false);
+ }
+ }
+
+ @Test
+ public void testDeleteSurroundingText_doesNotDelete() {
+ Selection.setSelection(mEditable, 0, mEditable.length());
+ assertFalse(mEmojiEmojiInputConnection.deleteSurroundingText(1, 0));
+ verify(mInputConnection, times(1)).deleteSurroundingText(1, 0);
+ }
+
+ @Test
+ public void testDeleteSurroundingText_deletesEmojiBackward() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+ assertTrue(mEmojiEmojiInputConnection.deleteSurroundingText(1, 0));
+ verify(mInputConnection, never()).deleteSurroundingText(anyInt(), anyInt());
+ }
+
+ @Test
+ public void testDeleteSurroundingText_doesNotDeleteEmojiIfSelectionAtStartIndex() {
+ Selection.setSelection(mEditable, mTestString.emojiStartIndex());
+ assertFalse(mEmojiEmojiInputConnection.deleteSurroundingText(1, 0));
+ verify(mInputConnection, times(1)).deleteSurroundingText(1, 0);
+ }
+
+ @Test
+ public void testDeleteSurroundingText_deletesEmojiForward() {
+ Selection.setSelection(mEditable, mTestString.emojiStartIndex());
+ assertTrue(mEmojiEmojiInputConnection.deleteSurroundingText(0, 1));
+ verify(mInputConnection, never()).deleteSurroundingText(anyInt(), anyInt());
+ }
+
+ @TargetApi(Build.VERSION_CODES.N)
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+ @Test
+ public void testDeleteSurroundingTextInCodePoints_doesNotDelete() {
+ Selection.setSelection(mEditable, 0, mEditable.length());
+ assertFalse(mEmojiEmojiInputConnection.deleteSurroundingTextInCodePoints(1, 0));
+ verify(mInputConnection, times(1)).deleteSurroundingTextInCodePoints(1, 0);
+ }
+
+ @TargetApi(Build.VERSION_CODES.N)
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+ @Test
+ public void testDeleteSurroundingTextInCodePoints_deletesEmojiBackward() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+ assertTrue(mEmojiEmojiInputConnection.deleteSurroundingTextInCodePoints(1, 0));
+ verify(mInputConnection, never()).deleteSurroundingTextInCodePoints(anyInt(), anyInt());
+ }
+
+ @TargetApi(Build.VERSION_CODES.N)
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+ @Test
+ public void testDeleteSurroundingTextInCodePoints_deletesEmojiForward() {
+ Selection.setSelection(mEditable, mTestString.emojiStartIndex());
+ assertTrue(mEmojiEmojiInputConnection.deleteSurroundingTextInCodePoints(0, 1));
+ verify(mInputConnection, never()).deleteSurroundingTextInCodePoints(anyInt(), anyInt());
+ }
+
+ @TargetApi(Build.VERSION_CODES.N)
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+ @Test
+ public void testDeleteSurroundingTextInCodePoints_doesNotDeleteEmojiIfSelectionAtStartIndex() {
+ Selection.setSelection(mEditable, mTestString.emojiStartIndex());
+ assertFalse(mEmojiEmojiInputConnection.deleteSurroundingTextInCodePoints(1, 0));
+ verify(mInputConnection, times(1)).deleteSurroundingTextInCodePoints(1, 0);
+ }
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/widget/EmojiInputFilterTest.java b/emoji/core/tests/java/android/support/text/emoji/widget/EmojiInputFilterTest.java
new file mode 100644
index 0000000..2d30657
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/widget/EmojiInputFilterTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.text.emoji.widget;
+
+import static android.support.text.emoji.util.EmojiMatcher.sameCharSequence;
+
+import static junit.framework.TestCase.assertNotNull;
+import static junit.framework.TestCase.assertSame;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.text.emoji.EmojiCompat;
+import android.text.Spannable;
+import android.text.SpannableString;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class EmojiInputFilterTest {
+
+ private android.widget.TextView mTextView;
+ private EmojiInputFilter mInputFilter;
+ private EmojiCompat mEmojiCompat;
+
+ @Before
+ public void setup() {
+ mTextView = mock(android.widget.TextView.class);
+ mEmojiCompat = mock(EmojiCompat.class);
+ EmojiCompat.reset(mEmojiCompat);
+ when(mEmojiCompat.isInitialized()).thenReturn(true);
+ mInputFilter = new EmojiInputFilter(mTextView);
+ }
+
+ @Test
+ public void testFilter_withNullSource() {
+ assertNull(mInputFilter.filter(null, 0, 1, null, 0, 1));
+ verify(mEmojiCompat, never()).process(any(CharSequence.class));
+ verify(mEmojiCompat, never()).process(any(CharSequence.class), anyInt(), anyInt());
+ }
+
+ @Test
+ public void testFilter_withString() {
+ final String testString = "abc";
+ when(mEmojiCompat.process(any(Spannable.class), anyInt(), anyInt()))
+ .thenReturn(new SpannableString(testString));
+ final CharSequence result = mInputFilter.filter(testString, 0, 1, null, 0, 1);
+
+ assertNotNull(result);
+ assertTrue(result instanceof Spannable);
+ verify(mEmojiCompat, times(1)).process(sameCharSequence("a"), eq(0), eq(1));
+ }
+
+ @Test
+ public void testFilter_withSpannable() {
+ final Spannable testString = new SpannableString("abc");
+ when(mEmojiCompat.process(any(Spannable.class), anyInt(), anyInt())).thenReturn(testString);
+
+ final CharSequence result = mInputFilter.filter(testString, 0, 1, null, 0, 1);
+
+ assertNotNull(result);
+ assertSame(result, testString);
+ verify(mEmojiCompat, times(1)).process(sameCharSequence(testString.subSequence(0, 1)),
+ eq(0), eq(1));
+ }
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/widget/EmojiKeyListenerTest.java b/emoji/core/tests/java/android/support/text/emoji/widget/EmojiKeyListenerTest.java
new file mode 100644
index 0000000..11bd9c1
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/widget/EmojiKeyListenerTest.java
@@ -0,0 +1,183 @@
+/*
+ * 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.text.emoji.widget;
+
+import static android.support.text.emoji.util.Emoji.EMOJI_WITH_ZWJ;
+import static android.support.text.emoji.util.EmojiMatcher.hasEmoji;
+import static android.support.text.emoji.util.KeyboardUtil.altDel;
+import static android.support.text.emoji.util.KeyboardUtil.ctrlDel;
+import static android.support.text.emoji.util.KeyboardUtil.del;
+import static android.support.text.emoji.util.KeyboardUtil.fnDel;
+import static android.support.text.emoji.util.KeyboardUtil.forwardDel;
+import static android.support.text.emoji.util.KeyboardUtil.shiftDel;
+import static android.support.text.emoji.util.KeyboardUtil.zero;
+
+import static junit.framework.Assert.assertFalse;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.same;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.text.emoji.EmojiCompat;
+import android.support.text.emoji.TestConfigBuilder;
+import android.support.text.emoji.util.TestString;
+import android.text.Editable;
+import android.text.Selection;
+import android.text.SpannableStringBuilder;
+import android.text.method.KeyListener;
+import android.view.KeyEvent;
+import android.view.View;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class EmojiKeyListenerTest {
+
+ private KeyListener mKeyListener;
+ private TestString mTestString;
+ private Editable mEditable;
+ private EmojiKeyListener mEmojiKeyListener;
+
+ @BeforeClass
+ public static void setupEmojiCompat() {
+ EmojiCompat.reset(TestConfigBuilder.config());
+ }
+
+ @Before
+ public void setup() {
+ mKeyListener = mock(KeyListener.class);
+ mTestString = new TestString(EMOJI_WITH_ZWJ).withPrefix().withSuffix();
+ mEditable = new SpannableStringBuilder(mTestString.toString());
+ mEmojiKeyListener = new EmojiKeyListener(mKeyListener);
+ EmojiCompat.get().process(mEditable);
+ assertThat(mEditable, hasEmoji());
+
+ when(mKeyListener.onKeyDown(any(View.class), any(Editable.class), anyInt(),
+ any(KeyEvent.class))).thenReturn(false);
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotDelete_whenKeyCodeIsNotDelOrForwardDel() {
+ Selection.setSelection(mEditable, 0);
+ final KeyEvent event = zero();
+ assertFalse(mEmojiKeyListener.onKeyDown(null, mEditable, event.getKeyCode(), event));
+ verify(mKeyListener, times(1)).onKeyDown((View) eq(null), same(mEditable),
+ eq(event.getKeyCode()), same(event));
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotDelete_withOtherModifiers() {
+ Selection.setSelection(mEditable, 0);
+ final KeyEvent event = fnDel();
+ assertFalse(mEmojiKeyListener.onKeyDown(null, mEditable, event.getKeyCode(), event));
+ verify(mKeyListener, times(1)).onKeyDown((View) eq(null), same(mEditable),
+ eq(event.getKeyCode()), same(event));
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotDelete_withAltModifier() {
+ Selection.setSelection(mEditable, 0);
+ final KeyEvent event = altDel();
+ assertFalse(mEmojiKeyListener.onKeyDown(null, mEditable, event.getKeyCode(), event));
+ verify(mKeyListener, times(1)).onKeyDown((View) eq(null), same(mEditable),
+ eq(event.getKeyCode()), same(event));
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotDelete_withCtrlModifier() {
+ Selection.setSelection(mEditable, 0);
+ final KeyEvent event = ctrlDel();
+ assertFalse(mEmojiKeyListener.onKeyDown(null, mEditable, event.getKeyCode(), event));
+ verify(mKeyListener, times(1)).onKeyDown((View) eq(null), same(mEditable),
+ eq(event.getKeyCode()), same(event));
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotDelete_withShiftModifier() {
+ Selection.setSelection(mEditable, 0);
+ final KeyEvent event = shiftDel();
+ assertFalse(mEmojiKeyListener.onKeyDown(null, mEditable, event.getKeyCode(), event));
+ verify(mKeyListener, times(1)).onKeyDown((View) eq(null), same(mEditable),
+ eq(event.getKeyCode()), same(event));
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotDelete_withSelection() {
+ Selection.setSelection(mEditable, 0, mEditable.length());
+ final KeyEvent event = del();
+ assertFalse(mEmojiKeyListener.onKeyDown(null, mEditable, event.getKeyCode(), event));
+ verify(mKeyListener, times(1)).onKeyDown((View) eq(null), same(mEditable),
+ eq(event.getKeyCode()), same(event));
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotDelete_withoutEmojiSpans() {
+ Editable editable = new SpannableStringBuilder("abc");
+ Selection.setSelection(editable, 1);
+ final KeyEvent event = del();
+ assertFalse(mEmojiKeyListener.onKeyDown(null, editable, event.getKeyCode(), event));
+ verify(mKeyListener, times(1)).onKeyDown((View) eq(null), same(editable),
+ eq(event.getKeyCode()), same(event));
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotDelete_whenNoSpansBefore() {
+ Selection.setSelection(mEditable, mTestString.emojiStartIndex());
+ final KeyEvent event = del();
+ assertFalse(mEmojiKeyListener.onKeyDown(null, mEditable, event.getKeyCode(), event));
+ verify(mKeyListener, times(1)).onKeyDown((View) eq(null), same(mEditable),
+ eq(event.getKeyCode()), same(event));
+ }
+
+ @Test
+ public void testOnKeyDown_deletesEmoji() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+ final KeyEvent event = del();
+ assertTrue(mEmojiKeyListener.onKeyDown(null, mEditable, event.getKeyCode(), event));
+ verifyNoMoreInteractions(mKeyListener);
+ }
+
+ @Test
+ public void testOnKeyDown_doesNotForwardDeleteEmoji_withNoSpansAfter() {
+ Selection.setSelection(mEditable, mTestString.emojiEndIndex());
+ final KeyEvent event = forwardDel();
+ assertFalse(mEmojiKeyListener.onKeyDown(null, mEditable, event.getKeyCode(), event));
+ verify(mKeyListener, times(1)).onKeyDown((View) eq(null), same(mEditable),
+ eq(event.getKeyCode()), same(event));
+ }
+
+ @Test
+ public void testOnKeyDown_forwardDeletesEmoji() {
+ Selection.setSelection(mEditable, mTestString.emojiStartIndex());
+ final KeyEvent event = forwardDel();
+ assertTrue(mEmojiKeyListener.onKeyDown(null, mEditable, event.getKeyCode(), event));
+ verifyNoMoreInteractions(mKeyListener);
+ }
+}
diff --git a/emoji/core/tests/java/android/support/text/emoji/widget/SpannableBuilderTest.java b/emoji/core/tests/java/android/support/text/emoji/widget/SpannableBuilderTest.java
new file mode 100644
index 0000000..2359b3b
--- /dev/null
+++ b/emoji/core/tests/java/android/support/text/emoji/widget/SpannableBuilderTest.java
@@ -0,0 +1,215 @@
+/*
+ * 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.text.emoji.widget;
+
+import static junit.framework.Assert.assertSame;
+import static junit.framework.TestCase.assertNotNull;
+
+import static org.hamcrest.Matchers.arrayWithSize;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.same;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.withSettings;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.text.emoji.EmojiSpan;
+import android.text.Editable;
+import android.text.SpanWatcher;
+import android.text.Spannable;
+import android.text.Spanned;
+import android.text.TextWatcher;
+import android.text.style.QuoteSpan;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SpannableBuilderTest {
+
+ private TextWatcher mWatcher;
+ private Class mClass;
+
+ @Before
+ public void setup() {
+ mWatcher = mock(TextWatcher.class, withSettings().extraInterfaces(SpanWatcher.class));
+ mClass = mWatcher.getClass();
+ }
+
+ @Test
+ public void testConstructor() {
+ new SpannableBuilder(mClass);
+
+ new SpannableBuilder(mClass, "abc");
+
+ new SpannableBuilder(mClass, "abc", 0, 3);
+
+ // test spannable copying? do I need it?
+ }
+
+ @Test
+ public void testSubSequence() {
+ final SpannableBuilder spannable = new SpannableBuilder(mClass, "abc");
+ final QuoteSpan span1 = mock(QuoteSpan.class);
+ final QuoteSpan span2 = mock(QuoteSpan.class);
+ spannable.setSpan(span1, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ spannable.setSpan(span2, 2, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ final CharSequence subsequence = spannable.subSequence(0, 1);
+ assertNotNull(subsequence);
+ assertThat(subsequence, instanceOf(SpannableBuilder.class));
+
+ final QuoteSpan[] spans = spannable.getSpans(0, 1, QuoteSpan.class);
+ assertThat(spans, arrayWithSize(1));
+ assertSame(spans[0], span1);
+ }
+
+ @Test
+ public void testSetAndGetSpan() {
+ final SpannableBuilder spannable = new SpannableBuilder(mClass, "abcde");
+ spannable.setSpan(mWatcher, 1, 2, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+
+ // getSpans should return the span
+ Object[] spans = spannable.getSpans(0, spannable.length(), mClass);
+ assertNotNull(spans);
+ assertThat(spans, arrayWithSize(1));
+ assertSame(mWatcher, spans[0]);
+
+ // span attributes should be correct
+ assertEquals(1, spannable.getSpanStart(mWatcher));
+ assertEquals(2, spannable.getSpanEnd(mWatcher));
+ assertEquals(Spanned.SPAN_INCLUSIVE_INCLUSIVE, spannable.getSpanFlags(mWatcher));
+
+ // should remove the span
+ spannable.removeSpan(mWatcher);
+ spans = spannable.getSpans(0, spannable.length(), QuoteSpan.class);
+ assertNotNull(spans);
+ assertThat(spans, arrayWithSize(0));
+ }
+
+ @Test
+ public void testNextSpanTransition() {
+ final SpannableBuilder spannable = new SpannableBuilder(mClass, "abcde");
+ spannable.setSpan(mWatcher, 1, 2, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ final int start = spannable.nextSpanTransition(0, spannable.length(), mClass);
+ Assert.assertEquals(1, start);
+ }
+
+ @Test
+ public void testBlocksSpanCallbacks_forEmojiSpans() {
+ final EmojiSpan span = mock(EmojiSpan.class);
+ final SpannableBuilder spannable = new SpannableBuilder(mClass, "123456");
+ spannable.setSpan(mWatcher, 0, spannable.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ spannable.setSpan(span, 1, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ reset(mWatcher);
+
+ spannable.delete(0, 3);
+
+ // verify that characters are deleted
+ assertEquals("456", spannable.toString());
+ // verify EmojiSpan is deleted
+ EmojiSpan[] spans = spannable.getSpans(0, spannable.length(), EmojiSpan.class);
+ assertThat(spans, arrayWithSize(0));
+
+ // verify the call to span callbacks are blocked
+ verify((SpanWatcher) mWatcher, never()).onSpanRemoved(any(Spannable.class),
+ same(span), anyInt(), anyInt());
+ verify((SpanWatcher) mWatcher, never()).onSpanAdded(any(Spannable.class),
+ same(span), anyInt(), anyInt());
+ verify((SpanWatcher) mWatcher, never()).onSpanChanged(any(Spannable.class),
+ same(span), anyInt(), anyInt(), anyInt(), anyInt());
+
+ // verify the call to TextWatcher callbacks are called
+ verify(mWatcher, times(1)).beforeTextChanged(any(CharSequence.class), anyInt(),
+ anyInt(), anyInt());
+ verify(mWatcher, times(1)).onTextChanged(any(CharSequence.class), anyInt(), anyInt(),
+ anyInt());
+ verify(mWatcher, times(1)).afterTextChanged(any(Editable.class));
+ }
+
+ @Test
+ public void testDoesNotBlockSpanCallbacks_forNonEmojiSpans() {
+ final QuoteSpan span = mock(QuoteSpan.class);
+ final SpannableBuilder spannable = new SpannableBuilder(mClass, "123456");
+ spannable.setSpan(mWatcher, 0, spannable.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ spannable.setSpan(span, 1, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ reset(mWatcher);
+
+ spannable.delete(0, 3);
+
+ // verify that characters are deleted
+ assertEquals("456", spannable.toString());
+ // verify QuoteSpan is deleted
+ QuoteSpan[] spans = spannable.getSpans(0, spannable.length(), QuoteSpan.class);
+ assertThat(spans, arrayWithSize(0));
+
+ // verify the call to span callbacks are not blocked
+ verify((SpanWatcher) mWatcher, times(1)).onSpanRemoved(any(Spannable.class),
+ anyObject(), anyInt(), anyInt());
+
+ // verify the call to TextWatcher callbacks are called
+ verify(mWatcher, times(1)).beforeTextChanged(any(CharSequence.class), anyInt(), anyInt(),
+ anyInt());
+ verify(mWatcher, times(1)).onTextChanged(any(CharSequence.class), anyInt(), anyInt(),
+ anyInt());
+ verify(mWatcher, times(1)).afterTextChanged(any(Editable.class));
+ }
+
+ @Test
+ public void testDoesNotBlockSpanCallbacksForOtherWatchers() {
+ final TextWatcher textWatcher = mock(TextWatcher.class);
+ final SpanWatcher spanWatcher = mock(SpanWatcher.class);
+
+ final EmojiSpan span = mock(EmojiSpan.class);
+ final SpannableBuilder spannable = new SpannableBuilder(mClass, "123456");
+ spannable.setSpan(textWatcher, 0, spannable.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ spannable.setSpan(spanWatcher, 0, spannable.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ spannable.setSpan(span, 1, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ reset(textWatcher);
+
+ spannable.delete(0, 3);
+
+ // verify that characters are deleted
+ assertEquals("456", spannable.toString());
+ // verify EmojiSpan is deleted
+ EmojiSpan[] spans = spannable.getSpans(0, spannable.length(), EmojiSpan.class);
+ assertThat(spans, arrayWithSize(0));
+
+ // verify the call to span callbacks are blocked
+ verify(spanWatcher, times(1)).onSpanRemoved(any(Spannable.class), same(span),
+ anyInt(), anyInt());
+
+ // verify the call to TextWatcher callbacks are called
+ verify(textWatcher, times(1)).beforeTextChanged(any(CharSequence.class), anyInt(),
+ anyInt(), anyInt());
+ verify(textWatcher, times(1)).onTextChanged(any(CharSequence.class), anyInt(), anyInt(),
+ anyInt());
+ verify(textWatcher, times(1)).afterTextChanged(any(Editable.class));
+ }
+}
diff --git a/emoji/core/tests/res/layout/activity_default.xml b/emoji/core/tests/res/layout/activity_default.xml
new file mode 100644
index 0000000..b9a09ca
--- /dev/null
+++ b/emoji/core/tests/res/layout/activity_default.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/root"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ <android.support.text.emoji.widget.EmojiEditText
+ android:id="@+id/editText"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+</LinearLayout>
diff --git a/emoji/core/tests/res/raw/all_emojis.txt b/emoji/core/tests/res/raw/all_emojis.txt
new file mode 100644
index 0000000..0d9ea3c
--- /dev/null
+++ b/emoji/core/tests/res/raw/all_emojis.txt
@@ -0,0 +1,2404 @@
+0x1f004
+0x1f004 0xfe0f
+0x1f0cf
+0x1f170 0xfe0f
+0x1f171 0xfe0f
+0x1f17e 0xfe0f
+0x1f17f 0xfe0f
+0x1f18e
+0x1f191
+0x1f192
+0x1f193
+0x1f194
+0x1f195
+0x1f196
+0x1f197
+0x1f198
+0x1f199
+0x1f19a
+0x1f1e6
+0x1f1e6 0x1f1e8
+0x1f1e6 0x1f1e9
+0x1f1e6 0x1f1ea
+0x1f1e6 0x1f1eb
+0x1f1e6 0x1f1ec
+0x1f1e6 0x1f1ee
+0x1f1e6 0x1f1f1
+0x1f1e6 0x1f1f2
+0x1f1e6 0x1f1f4
+0x1f1e6 0x1f1f6
+0x1f1e6 0x1f1f7
+0x1f1e6 0x1f1f8
+0x1f1e6 0x1f1f9
+0x1f1e6 0x1f1fa
+0x1f1e6 0x1f1fc
+0x1f1e6 0x1f1fd
+0x1f1e6 0x1f1ff
+0x1f1e7
+0x1f1e7 0x1f1e6
+0x1f1e7 0x1f1e7
+0x1f1e7 0x1f1e9
+0x1f1e7 0x1f1ea
+0x1f1e7 0x1f1eb
+0x1f1e7 0x1f1ec
+0x1f1e7 0x1f1ed
+0x1f1e7 0x1f1ee
+0x1f1e7 0x1f1ef
+0x1f1e7 0x1f1f1
+0x1f1e7 0x1f1f2
+0x1f1e7 0x1f1f3
+0x1f1e7 0x1f1f4
+0x1f1e7 0x1f1f6
+0x1f1e7 0x1f1f7
+0x1f1e7 0x1f1f8
+0x1f1e7 0x1f1f9
+0x1f1e7 0x1f1fb
+0x1f1e7 0x1f1fc
+0x1f1e7 0x1f1fe
+0x1f1e7 0x1f1ff
+0x1f1e8
+0x1f1e8 0x1f1e6
+0x1f1e8 0x1f1e8
+0x1f1e8 0x1f1e9
+0x1f1e8 0x1f1eb
+0x1f1e8 0x1f1ec
+0x1f1e8 0x1f1ed
+0x1f1e8 0x1f1ee
+0x1f1e8 0x1f1f0
+0x1f1e8 0x1f1f1
+0x1f1e8 0x1f1f2
+0x1f1e8 0x1f1f3
+0x1f1e8 0x1f1f4
+0x1f1e8 0x1f1f5
+0x1f1e8 0x1f1f7
+0x1f1e8 0x1f1fa
+0x1f1e8 0x1f1fb
+0x1f1e8 0x1f1fc
+0x1f1e8 0x1f1fd
+0x1f1e8 0x1f1fe
+0x1f1e8 0x1f1ff
+0x1f1e9
+0x1f1e9 0x1f1ea
+0x1f1e9 0x1f1ec
+0x1f1e9 0x1f1ef
+0x1f1e9 0x1f1f0
+0x1f1e9 0x1f1f2
+0x1f1e9 0x1f1f4
+0x1f1e9 0x1f1ff
+0x1f1ea
+0x1f1ea 0x1f1e6
+0x1f1ea 0x1f1e8
+0x1f1ea 0x1f1ea
+0x1f1ea 0x1f1ec
+0x1f1ea 0x1f1ed
+0x1f1ea 0x1f1f7
+0x1f1ea 0x1f1f8
+0x1f1ea 0x1f1f9
+0x1f1ea 0x1f1fa
+0x1f1eb
+0x1f1eb 0x1f1ee
+0x1f1eb 0x1f1ef
+0x1f1eb 0x1f1f0
+0x1f1eb 0x1f1f2
+0x1f1eb 0x1f1f4
+0x1f1eb 0x1f1f7
+0x1f1ec
+0x1f1ec 0x1f1e6
+0x1f1ec 0x1f1e7
+0x1f1ec 0x1f1e9
+0x1f1ec 0x1f1ea
+0x1f1ec 0x1f1eb
+0x1f1ec 0x1f1ec
+0x1f1ec 0x1f1ed
+0x1f1ec 0x1f1ee
+0x1f1ec 0x1f1f1
+0x1f1ec 0x1f1f2
+0x1f1ec 0x1f1f3
+0x1f1ec 0x1f1f5
+0x1f1ec 0x1f1f6
+0x1f1ec 0x1f1f7
+0x1f1ec 0x1f1f8
+0x1f1ec 0x1f1f9
+0x1f1ec 0x1f1fa
+0x1f1ec 0x1f1fc
+0x1f1ec 0x1f1fe
+0x1f1ed
+0x1f1ed 0x1f1f0
+0x1f1ed 0x1f1f2
+0x1f1ed 0x1f1f3
+0x1f1ed 0x1f1f7
+0x1f1ed 0x1f1f9
+0x1f1ed 0x1f1fa
+0x1f1ee
+0x1f1ee 0x1f1e8
+0x1f1ee 0x1f1e9
+0x1f1ee 0x1f1ea
+0x1f1ee 0x1f1f1
+0x1f1ee 0x1f1f2
+0x1f1ee 0x1f1f3
+0x1f1ee 0x1f1f4
+0x1f1ee 0x1f1f6
+0x1f1ee 0x1f1f7
+0x1f1ee 0x1f1f8
+0x1f1ee 0x1f1f9
+0x1f1ef
+0x1f1ef 0x1f1ea
+0x1f1ef 0x1f1f2
+0x1f1ef 0x1f1f4
+0x1f1ef 0x1f1f5
+0x1f1f0
+0x1f1f0 0x1f1ea
+0x1f1f0 0x1f1ec
+0x1f1f0 0x1f1ed
+0x1f1f0 0x1f1ee
+0x1f1f0 0x1f1f2
+0x1f1f0 0x1f1f3
+0x1f1f0 0x1f1f5
+0x1f1f0 0x1f1f7
+0x1f1f0 0x1f1fc
+0x1f1f0 0x1f1fe
+0x1f1f0 0x1f1ff
+0x1f1f1
+0x1f1f1 0x1f1e6
+0x1f1f1 0x1f1e7
+0x1f1f1 0x1f1e8
+0x1f1f1 0x1f1ee
+0x1f1f1 0x1f1f0
+0x1f1f1 0x1f1f7
+0x1f1f1 0x1f1f8
+0x1f1f1 0x1f1f9
+0x1f1f1 0x1f1fa
+0x1f1f1 0x1f1fb
+0x1f1f1 0x1f1fe
+0x1f1f2
+0x1f1f2 0x1f1e6
+0x1f1f2 0x1f1e8
+0x1f1f2 0x1f1e9
+0x1f1f2 0x1f1ea
+0x1f1f2 0x1f1eb
+0x1f1f2 0x1f1ec
+0x1f1f2 0x1f1ed
+0x1f1f2 0x1f1f0
+0x1f1f2 0x1f1f1
+0x1f1f2 0x1f1f2
+0x1f1f2 0x1f1f3
+0x1f1f2 0x1f1f4
+0x1f1f2 0x1f1f5
+0x1f1f2 0x1f1f6
+0x1f1f2 0x1f1f7
+0x1f1f2 0x1f1f8
+0x1f1f2 0x1f1f9
+0x1f1f2 0x1f1fa
+0x1f1f2 0x1f1fb
+0x1f1f2 0x1f1fc
+0x1f1f2 0x1f1fd
+0x1f1f2 0x1f1fe
+0x1f1f2 0x1f1ff
+0x1f1f3
+0x1f1f3 0x1f1e6
+0x1f1f3 0x1f1e8
+0x1f1f3 0x1f1ea
+0x1f1f3 0x1f1eb
+0x1f1f3 0x1f1ec
+0x1f1f3 0x1f1ee
+0x1f1f3 0x1f1f1
+0x1f1f3 0x1f1f4
+0x1f1f3 0x1f1f5
+0x1f1f3 0x1f1f7
+0x1f1f3 0x1f1fa
+0x1f1f3 0x1f1ff
+0x1f1f4
+0x1f1f4 0x1f1f2
+0x1f1f5
+0x1f1f5 0x1f1e6
+0x1f1f5 0x1f1ea
+0x1f1f5 0x1f1eb
+0x1f1f5 0x1f1ec
+0x1f1f5 0x1f1ed
+0x1f1f5 0x1f1f0
+0x1f1f5 0x1f1f1
+0x1f1f5 0x1f1f2
+0x1f1f5 0x1f1f3
+0x1f1f5 0x1f1f7
+0x1f1f5 0x1f1f8
+0x1f1f5 0x1f1f9
+0x1f1f5 0x1f1fc
+0x1f1f5 0x1f1fe
+0x1f1f6
+0x1f1f6 0x1f1e6
+0x1f1f7
+0x1f1f7 0x1f1ea
+0x1f1f7 0x1f1f4
+0x1f1f7 0x1f1f8
+0x1f1f7 0x1f1fa
+0x1f1f7 0x1f1fc
+0x1f1f8
+0x1f1f8 0x1f1e6
+0x1f1f8 0x1f1e7
+0x1f1f8 0x1f1e8
+0x1f1f8 0x1f1e9
+0x1f1f8 0x1f1ea
+0x1f1f8 0x1f1ec
+0x1f1f8 0x1f1ed
+0x1f1f8 0x1f1ee
+0x1f1f8 0x1f1ef
+0x1f1f8 0x1f1f0
+0x1f1f8 0x1f1f1
+0x1f1f8 0x1f1f2
+0x1f1f8 0x1f1f3
+0x1f1f8 0x1f1f4
+0x1f1f8 0x1f1f7
+0x1f1f8 0x1f1f8
+0x1f1f8 0x1f1f9
+0x1f1f8 0x1f1fb
+0x1f1f8 0x1f1fd
+0x1f1f8 0x1f1fe
+0x1f1f8 0x1f1ff
+0x1f1f9
+0x1f1f9 0x1f1e6
+0x1f1f9 0x1f1e8
+0x1f1f9 0x1f1e9
+0x1f1f9 0x1f1eb
+0x1f1f9 0x1f1ec
+0x1f1f9 0x1f1ed
+0x1f1f9 0x1f1ef
+0x1f1f9 0x1f1f0
+0x1f1f9 0x1f1f1
+0x1f1f9 0x1f1f2
+0x1f1f9 0x1f1f3
+0x1f1f9 0x1f1f4
+0x1f1f9 0x1f1f7
+0x1f1f9 0x1f1f9
+0x1f1f9 0x1f1fb
+0x1f1f9 0x1f1fc
+0x1f1f9 0x1f1ff
+0x1f1fa
+0x1f1fa 0x1f1e6
+0x1f1fa 0x1f1ec
+0x1f1fa 0x1f1f2
+0x1f1fa 0x1f1f3
+0x1f1fa 0x1f1f8
+0x1f1fa 0x1f1fe
+0x1f1fa 0x1f1ff
+0x1f1fb
+0x1f1fb 0x1f1e6
+0x1f1fb 0x1f1e8
+0x1f1fb 0x1f1ea
+0x1f1fb 0x1f1ec
+0x1f1fb 0x1f1ee
+0x1f1fb 0x1f1f3
+0x1f1fb 0x1f1fa
+0x1f1fc
+0x1f1fc 0x1f1eb
+0x1f1fc 0x1f1f8
+0x1f1fd
+0x1f1fd 0x1f1f0
+0x1f1fe
+0x1f1fe 0x1f1ea
+0x1f1fe 0x1f1f9
+0x1f1ff
+0x1f1ff 0x1f1e6
+0x1f1ff 0x1f1f2
+0x1f1ff 0x1f1fc
+0x1f201
+0x1f202 0xfe0f
+0x1f21a
+0x1f21a 0xfe0f
+0x1f22f
+0x1f22f 0xfe0f
+0x1f232
+0x1f233
+0x1f234
+0x1f235
+0x1f236
+0x1f237 0xfe0f
+0x1f238
+0x1f239
+0x1f23a
+0x1f250
+0x1f251
+0x1f300
+0x1f301
+0x1f302
+0x1f303
+0x1f304
+0x1f305
+0x1f306
+0x1f307
+0x1f308
+0x1f309
+0x1f30a
+0x1f30b
+0x1f30c
+0x1f30d
+0x1f30e
+0x1f30f
+0x1f310
+0x1f311
+0x1f312
+0x1f313
+0x1f314
+0x1f315
+0x1f316
+0x1f317
+0x1f318
+0x1f319
+0x1f31a
+0x1f31b
+0x1f31c
+0x1f31d
+0x1f31e
+0x1f31f
+0x1f320
+0x1f321 0xfe0f
+0x1f324 0xfe0f
+0x1f325 0xfe0f
+0x1f326 0xfe0f
+0x1f327 0xfe0f
+0x1f328 0xfe0f
+0x1f329 0xfe0f
+0x1f32a 0xfe0f
+0x1f32b 0xfe0f
+0x1f32c 0xfe0f
+0x1f32d
+0x1f32e
+0x1f32f
+0x1f330
+0x1f331
+0x1f332
+0x1f333
+0x1f334
+0x1f335
+0x1f336 0xfe0f
+0x1f337
+0x1f338
+0x1f339
+0x1f33a
+0x1f33b
+0x1f33c
+0x1f33d
+0x1f33e
+0x1f33f
+0x1f340
+0x1f341
+0x1f342
+0x1f343
+0x1f344
+0x1f345
+0x1f346
+0x1f347
+0x1f348
+0x1f349
+0x1f34a
+0x1f34b
+0x1f34c
+0x1f34d
+0x1f34e
+0x1f34f
+0x1f350
+0x1f351
+0x1f352
+0x1f353
+0x1f354
+0x1f355
+0x1f356
+0x1f357
+0x1f358
+0x1f359
+0x1f35a
+0x1f35b
+0x1f35c
+0x1f35d
+0x1f35e
+0x1f35f
+0x1f360
+0x1f361
+0x1f362
+0x1f363
+0x1f364
+0x1f365
+0x1f366
+0x1f367
+0x1f368
+0x1f369
+0x1f36a
+0x1f36b
+0x1f36c
+0x1f36d
+0x1f36e
+0x1f36f
+0x1f370
+0x1f371
+0x1f372
+0x1f373
+0x1f374
+0x1f375
+0x1f376
+0x1f377
+0x1f378
+0x1f379
+0x1f37a
+0x1f37b
+0x1f37c
+0x1f37d 0xfe0f
+0x1f37e
+0x1f37f
+0x1f380
+0x1f381
+0x1f382
+0x1f383
+0x1f384
+0x1f385
+0x1f385 0x1f3fb
+0x1f385 0x1f3fc
+0x1f385 0x1f3fd
+0x1f385 0x1f3fe
+0x1f385 0x1f3ff
+0x1f386
+0x1f387
+0x1f388
+0x1f389
+0x1f38a
+0x1f38b
+0x1f38c
+0x1f38d
+0x1f38e
+0x1f38f
+0x1f390
+0x1f391
+0x1f392
+0x1f393
+0x1f396 0xfe0f
+0x1f397 0xfe0f
+0x1f399 0xfe0f
+0x1f39a 0xfe0f
+0x1f39b 0xfe0f
+0x1f39e 0xfe0f
+0x1f39f 0xfe0f
+0x1f3a0
+0x1f3a1
+0x1f3a2
+0x1f3a3
+0x1f3a4
+0x1f3a5
+0x1f3a6
+0x1f3a7
+0x1f3a8
+0x1f3a9
+0x1f3aa
+0x1f3ab
+0x1f3ac
+0x1f3ad
+0x1f3ae
+0x1f3af
+0x1f3b0
+0x1f3b1
+0x1f3b2
+0x1f3b3
+0x1f3b4
+0x1f3b5
+0x1f3b6
+0x1f3b7
+0x1f3b8
+0x1f3b9
+0x1f3ba
+0x1f3bb
+0x1f3bc
+0x1f3bd
+0x1f3be
+0x1f3bf
+0x1f3c0
+0x1f3c1
+0x1f3c2
+0x1f3c3
+0x1f3c3 0x1f3fb
+0x1f3c3 0x1f3fb 0x200d 0x2640
+0x1f3c3 0x1f3fb 0x200d 0x2642
+0x1f3c3 0x1f3fc
+0x1f3c3 0x1f3fc 0x200d 0x2640
+0x1f3c3 0x1f3fc 0x200d 0x2642
+0x1f3c3 0x1f3fd
+0x1f3c3 0x1f3fd 0x200d 0x2640
+0x1f3c3 0x1f3fd 0x200d 0x2642
+0x1f3c3 0x1f3fe
+0x1f3c3 0x1f3fe 0x200d 0x2640
+0x1f3c3 0x1f3fe 0x200d 0x2642
+0x1f3c3 0x1f3ff
+0x1f3c3 0x1f3ff 0x200d 0x2640
+0x1f3c3 0x1f3ff 0x200d 0x2642
+0x1f3c3 0x200d 0x2640
+0x1f3c3 0x200d 0x2642
+0x1f3c4
+0x1f3c4 0x1f3fb
+0x1f3c4 0x1f3fb 0x200d 0x2640
+0x1f3c4 0x1f3fb 0x200d 0x2642
+0x1f3c4 0x1f3fc
+0x1f3c4 0x1f3fc 0x200d 0x2640
+0x1f3c4 0x1f3fc 0x200d 0x2642
+0x1f3c4 0x1f3fd
+0x1f3c4 0x1f3fd 0x200d 0x2640
+0x1f3c4 0x1f3fd 0x200d 0x2642
+0x1f3c4 0x1f3fe
+0x1f3c4 0x1f3fe 0x200d 0x2640
+0x1f3c4 0x1f3fe 0x200d 0x2642
+0x1f3c4 0x1f3ff
+0x1f3c4 0x1f3ff 0x200d 0x2640
+0x1f3c4 0x1f3ff 0x200d 0x2642
+0x1f3c4 0x200d 0x2640
+0x1f3c4 0x200d 0x2642
+0x1f3c5
+0x1f3c6
+0x1f3c7
+0x1f3c8
+0x1f3c9
+0x1f3ca
+0x1f3ca 0x1f3fb
+0x1f3ca 0x1f3fb 0x200d 0x2640
+0x1f3ca 0x1f3fb 0x200d 0x2642
+0x1f3ca 0x1f3fc
+0x1f3ca 0x1f3fc 0x200d 0x2640
+0x1f3ca 0x1f3fc 0x200d 0x2642
+0x1f3ca 0x1f3fd
+0x1f3ca 0x1f3fd 0x200d 0x2640
+0x1f3ca 0x1f3fd 0x200d 0x2642
+0x1f3ca 0x1f3fe
+0x1f3ca 0x1f3fe 0x200d 0x2640
+0x1f3ca 0x1f3fe 0x200d 0x2642
+0x1f3ca 0x1f3ff
+0x1f3ca 0x1f3ff 0x200d 0x2640
+0x1f3ca 0x1f3ff 0x200d 0x2642
+0x1f3ca 0x200d 0x2640
+0x1f3ca 0x200d 0x2642
+0x1f3cb 0x1f3fb
+0x1f3cb 0x1f3fb 0x200d 0x2640
+0x1f3cb 0x1f3fb 0x200d 0x2642
+0x1f3cb 0x1f3fc
+0x1f3cb 0x1f3fc 0x200d 0x2640
+0x1f3cb 0x1f3fc 0x200d 0x2642
+0x1f3cb 0x1f3fd
+0x1f3cb 0x1f3fd 0x200d 0x2640
+0x1f3cb 0x1f3fd 0x200d 0x2642
+0x1f3cb 0x1f3fe
+0x1f3cb 0x1f3fe 0x200d 0x2640
+0x1f3cb 0x1f3fe 0x200d 0x2642
+0x1f3cb 0x1f3ff
+0x1f3cb 0x1f3ff 0x200d 0x2640
+0x1f3cb 0x1f3ff 0x200d 0x2642
+0x1f3cb 0x200d 0x2640
+0x1f3cb 0x200d 0x2642
+0x1f3cb 0xfe0f
+0x1f3cc 0x200d 0x2640
+0x1f3cc 0x200d 0x2642
+0x1f3cc 0xfe0f
+0x1f3cd 0xfe0f
+0x1f3ce 0xfe0f
+0x1f3cf
+0x1f3d0
+0x1f3d1
+0x1f3d2
+0x1f3d3
+0x1f3d4 0xfe0f
+0x1f3d5 0xfe0f
+0x1f3d6 0xfe0f
+0x1f3d7 0xfe0f
+0x1f3d8 0xfe0f
+0x1f3d9 0xfe0f
+0x1f3da 0xfe0f
+0x1f3db 0xfe0f
+0x1f3dc 0xfe0f
+0x1f3dd 0xfe0f
+0x1f3de 0xfe0f
+0x1f3df 0xfe0f
+0x1f3e0
+0x1f3e1
+0x1f3e2
+0x1f3e3
+0x1f3e4
+0x1f3e5
+0x1f3e6
+0x1f3e7
+0x1f3e8
+0x1f3e9
+0x1f3ea
+0x1f3eb
+0x1f3ec
+0x1f3ed
+0x1f3ee
+0x1f3ef
+0x1f3f0
+0x1f3f3 0x200d 0x1f308
+0x1f3f3 0xfe0f
+0x1f3f4
+0x1f3f5 0xfe0f
+0x1f3f7 0xfe0f
+0x1f3f8
+0x1f3f9
+0x1f3fa
+0x1f3fb
+0x1f3fc
+0x1f3fd
+0x1f3fe
+0x1f3ff
+0x1f400
+0x1f401
+0x1f402
+0x1f403
+0x1f404
+0x1f405
+0x1f406
+0x1f407
+0x1f408
+0x1f409
+0x1f40a
+0x1f40b
+0x1f40c
+0x1f40d
+0x1f40e
+0x1f40f
+0x1f410
+0x1f411
+0x1f412
+0x1f413
+0x1f414
+0x1f415
+0x1f416
+0x1f417
+0x1f418
+0x1f419
+0x1f41a
+0x1f41b
+0x1f41c
+0x1f41d
+0x1f41e
+0x1f41f
+0x1f420
+0x1f421
+0x1f422
+0x1f423
+0x1f424
+0x1f425
+0x1f426
+0x1f427
+0x1f428
+0x1f429
+0x1f42a
+0x1f42b
+0x1f42c
+0x1f42d
+0x1f42e
+0x1f42f
+0x1f430
+0x1f431
+0x1f432
+0x1f433
+0x1f434
+0x1f435
+0x1f436
+0x1f437
+0x1f438
+0x1f439
+0x1f43a
+0x1f43b
+0x1f43c
+0x1f43d
+0x1f43e
+0x1f43f 0xfe0f
+0x1f440
+0x1f441 0x200d 0x1f5e8
+0x1f441 0xfe0f
+0x1f442
+0x1f442 0x1f3fb
+0x1f442 0x1f3fc
+0x1f442 0x1f3fd
+0x1f442 0x1f3fe
+0x1f442 0x1f3ff
+0x1f443
+0x1f443 0x1f3fb
+0x1f443 0x1f3fc
+0x1f443 0x1f3fd
+0x1f443 0x1f3fe
+0x1f443 0x1f3ff
+0x1f444
+0x1f445
+0x1f446
+0x1f446 0x1f3fb
+0x1f446 0x1f3fc
+0x1f446 0x1f3fd
+0x1f446 0x1f3fe
+0x1f446 0x1f3ff
+0x1f447
+0x1f447 0x1f3fb
+0x1f447 0x1f3fc
+0x1f447 0x1f3fd
+0x1f447 0x1f3fe
+0x1f447 0x1f3ff
+0x1f448
+0x1f448 0x1f3fb
+0x1f448 0x1f3fc
+0x1f448 0x1f3fd
+0x1f448 0x1f3fe
+0x1f448 0x1f3ff
+0x1f449
+0x1f449 0x1f3fb
+0x1f449 0x1f3fc
+0x1f449 0x1f3fd
+0x1f449 0x1f3fe
+0x1f449 0x1f3ff
+0x1f44a
+0x1f44a 0x1f3fb
+0x1f44a 0x1f3fc
+0x1f44a 0x1f3fd
+0x1f44a 0x1f3fe
+0x1f44a 0x1f3ff
+0x1f44b
+0x1f44b 0x1f3fb
+0x1f44b 0x1f3fc
+0x1f44b 0x1f3fd
+0x1f44b 0x1f3fe
+0x1f44b 0x1f3ff
+0x1f44c
+0x1f44c 0x1f3fb
+0x1f44c 0x1f3fc
+0x1f44c 0x1f3fd
+0x1f44c 0x1f3fe
+0x1f44c 0x1f3ff
+0x1f44d
+0x1f44d 0x1f3fb
+0x1f44d 0x1f3fc
+0x1f44d 0x1f3fd
+0x1f44d 0x1f3fe
+0x1f44d 0x1f3ff
+0x1f44e
+0x1f44e 0x1f3fb
+0x1f44e 0x1f3fc
+0x1f44e 0x1f3fd
+0x1f44e 0x1f3fe
+0x1f44e 0x1f3ff
+0x1f44f
+0x1f44f 0x1f3fb
+0x1f44f 0x1f3fc
+0x1f44f 0x1f3fd
+0x1f44f 0x1f3fe
+0x1f44f 0x1f3ff
+0x1f450
+0x1f450 0x1f3fb
+0x1f450 0x1f3fc
+0x1f450 0x1f3fd
+0x1f450 0x1f3fe
+0x1f450 0x1f3ff
+0x1f451
+0x1f452
+0x1f453
+0x1f454
+0x1f455
+0x1f456
+0x1f457
+0x1f458
+0x1f459
+0x1f45a
+0x1f45b
+0x1f45c
+0x1f45d
+0x1f45e
+0x1f45f
+0x1f460
+0x1f461
+0x1f462
+0x1f463
+0x1f464
+0x1f465
+0x1f466
+0x1f466 0x1f3fb
+0x1f466 0x1f3fc
+0x1f466 0x1f3fd
+0x1f466 0x1f3fe
+0x1f466 0x1f3ff
+0x1f467
+0x1f467 0x1f3fb
+0x1f467 0x1f3fc
+0x1f467 0x1f3fd
+0x1f467 0x1f3fe
+0x1f467 0x1f3ff
+0x1f468
+0x1f468 0x1f3fb
+0x1f468 0x1f3fb 0x200d 0x1f33e
+0x1f468 0x1f3fb 0x200d 0x1f373
+0x1f468 0x1f3fb 0x200d 0x1f393
+0x1f468 0x1f3fb 0x200d 0x1f3a4
+0x1f468 0x1f3fb 0x200d 0x1f3eb
+0x1f468 0x1f3fb 0x200d 0x1f3ed
+0x1f468 0x1f3fb 0x200d 0x1f4bb
+0x1f468 0x1f3fb 0x200d 0x1f4bc
+0x1f468 0x1f3fb 0x200d 0x1f527
+0x1f468 0x1f3fb 0x200d 0x1f52c
+0x1f468 0x1f3fb 0x200d 0x2695
+0x1f468 0x1f3fc
+0x1f468 0x1f3fc 0x200d 0x1f33e
+0x1f468 0x1f3fc 0x200d 0x1f373
+0x1f468 0x1f3fc 0x200d 0x1f393
+0x1f468 0x1f3fc 0x200d 0x1f3a4
+0x1f468 0x1f3fc 0x200d 0x1f3eb
+0x1f468 0x1f3fc 0x200d 0x1f3ed
+0x1f468 0x1f3fc 0x200d 0x1f4bb
+0x1f468 0x1f3fc 0x200d 0x1f4bc
+0x1f468 0x1f3fc 0x200d 0x1f527
+0x1f468 0x1f3fc 0x200d 0x1f52c
+0x1f468 0x1f3fc 0x200d 0x2695
+0x1f468 0x1f3fd
+0x1f468 0x1f3fd 0x200d 0x1f33e
+0x1f468 0x1f3fd 0x200d 0x1f373
+0x1f468 0x1f3fd 0x200d 0x1f393
+0x1f468 0x1f3fd 0x200d 0x1f3a4
+0x1f468 0x1f3fd 0x200d 0x1f3eb
+0x1f468 0x1f3fd 0x200d 0x1f3ed
+0x1f468 0x1f3fd 0x200d 0x1f4bb
+0x1f468 0x1f3fd 0x200d 0x1f4bc
+0x1f468 0x1f3fd 0x200d 0x1f527
+0x1f468 0x1f3fd 0x200d 0x1f52c
+0x1f468 0x1f3fd 0x200d 0x2695
+0x1f468 0x1f3fe
+0x1f468 0x1f3fe 0x200d 0x1f33e
+0x1f468 0x1f3fe 0x200d 0x1f373
+0x1f468 0x1f3fe 0x200d 0x1f393
+0x1f468 0x1f3fe 0x200d 0x1f3a4
+0x1f468 0x1f3fe 0x200d 0x1f3eb
+0x1f468 0x1f3fe 0x200d 0x1f3ed
+0x1f468 0x1f3fe 0x200d 0x1f4bb
+0x1f468 0x1f3fe 0x200d 0x1f4bc
+0x1f468 0x1f3fe 0x200d 0x1f527
+0x1f468 0x1f3fe 0x200d 0x1f52c
+0x1f468 0x1f3fe 0x200d 0x2695
+0x1f468 0x1f3ff
+0x1f468 0x1f3ff 0x200d 0x1f33e
+0x1f468 0x1f3ff 0x200d 0x1f373
+0x1f468 0x1f3ff 0x200d 0x1f393
+0x1f468 0x1f3ff 0x200d 0x1f3a4
+0x1f468 0x1f3ff 0x200d 0x1f3eb
+0x1f468 0x1f3ff 0x200d 0x1f3ed
+0x1f468 0x1f3ff 0x200d 0x1f4bb
+0x1f468 0x1f3ff 0x200d 0x1f4bc
+0x1f468 0x1f3ff 0x200d 0x1f527
+0x1f468 0x1f3ff 0x200d 0x1f52c
+0x1f468 0x1f3ff 0x200d 0x2695
+0x1f468 0x200d 0x1f33e
+0x1f468 0x200d 0x1f373
+0x1f468 0x200d 0x1f393
+0x1f468 0x200d 0x1f3a4
+0x1f468 0x200d 0x1f3a8
+0x1f468 0x200d 0x1f3eb
+0x1f468 0x200d 0x1f3ed
+0x1f468 0x200d 0x1f466
+0x1f468 0x200d 0x1f466 0x200d 0x1f466
+0x1f468 0x200d 0x1f467
+0x1f468 0x200d 0x1f467 0x200d 0x1f466
+0x1f468 0x200d 0x1f467 0x200d 0x1f467
+0x1f468 0x200d 0x1f468 0x200d 0x1f466
+0x1f468 0x200d 0x1f468 0x200d 0x1f466 0x200d 0x1f466
+0x1f468 0x200d 0x1f468 0x200d 0x1f467
+0x1f468 0x200d 0x1f468 0x200d 0x1f467 0x200d 0x1f466
+0x1f468 0x200d 0x1f468 0x200d 0x1f467 0x200d 0x1f467
+0x1f468 0x200d 0x1f469 0x200d 0x1f466
+0x1f468 0x200d 0x1f469 0x200d 0x1f466 0x200d 0x1f466
+0x1f468 0x200d 0x1f469 0x200d 0x1f467
+0x1f468 0x200d 0x1f469 0x200d 0x1f467 0x200d 0x1f466
+0x1f468 0x200d 0x1f469 0x200d 0x1f467 0x200d 0x1f467
+0x1f468 0x200d 0x1f4bb
+0x1f468 0x200d 0x1f4bc
+0x1f468 0x200d 0x1f527
+0x1f468 0x200d 0x1f52c
+0x1f468 0x200d 0x1f680
+0x1f468 0x200d 0x1f692
+0x1f468 0x200d 0x2695
+0x1f468 0x200d 0x2696
+0x1f468 0x200d 0x2708
+0x1f468 0x200d 0x2764 0x200d 0x1f468
+0x1f468 0x200d 0x2764 0x200d 0x1f48b 0x200d 0x1f468
+0x1f469
+0x1f469 0x1f3fb
+0x1f469 0x1f3fb 0x200d 0x1f33e
+0x1f469 0x1f3fb 0x200d 0x1f373
+0x1f469 0x1f3fb 0x200d 0x1f393
+0x1f469 0x1f3fb 0x200d 0x1f3a4
+0x1f469 0x1f3fb 0x200d 0x1f3eb
+0x1f469 0x1f3fb 0x200d 0x1f3ed
+0x1f469 0x1f3fb 0x200d 0x1f4bb
+0x1f469 0x1f3fb 0x200d 0x1f4bc
+0x1f469 0x1f3fb 0x200d 0x1f527
+0x1f469 0x1f3fb 0x200d 0x1f52c
+0x1f469 0x1f3fb 0x200d 0x2695
+0x1f469 0x1f3fc
+0x1f469 0x1f3fc 0x200d 0x1f33e
+0x1f469 0x1f3fc 0x200d 0x1f373
+0x1f469 0x1f3fc 0x200d 0x1f393
+0x1f469 0x1f3fc 0x200d 0x1f3a4
+0x1f469 0x1f3fc 0x200d 0x1f3eb
+0x1f469 0x1f3fc 0x200d 0x1f3ed
+0x1f469 0x1f3fc 0x200d 0x1f4bb
+0x1f469 0x1f3fc 0x200d 0x1f4bc
+0x1f469 0x1f3fc 0x200d 0x1f527
+0x1f469 0x1f3fc 0x200d 0x1f52c
+0x1f469 0x1f3fc 0x200d 0x2695
+0x1f469 0x1f3fd
+0x1f469 0x1f3fd 0x200d 0x1f33e
+0x1f469 0x1f3fd 0x200d 0x1f373
+0x1f469 0x1f3fd 0x200d 0x1f393
+0x1f469 0x1f3fd 0x200d 0x1f3a4
+0x1f469 0x1f3fd 0x200d 0x1f3eb
+0x1f469 0x1f3fd 0x200d 0x1f3ed
+0x1f469 0x1f3fd 0x200d 0x1f4bb
+0x1f469 0x1f3fd 0x200d 0x1f4bc
+0x1f469 0x1f3fd 0x200d 0x1f527
+0x1f469 0x1f3fd 0x200d 0x1f52c
+0x1f469 0x1f3fd 0x200d 0x2695
+0x1f469 0x1f3fe
+0x1f469 0x1f3fe 0x200d 0x1f33e
+0x1f469 0x1f3fe 0x200d 0x1f373
+0x1f469 0x1f3fe 0x200d 0x1f393
+0x1f469 0x1f3fe 0x200d 0x1f3a4
+0x1f469 0x1f3fe 0x200d 0x1f3eb
+0x1f469 0x1f3fe 0x200d 0x1f3ed
+0x1f469 0x1f3fe 0x200d 0x1f4bb
+0x1f469 0x1f3fe 0x200d 0x1f4bc
+0x1f469 0x1f3fe 0x200d 0x1f527
+0x1f469 0x1f3fe 0x200d 0x1f52c
+0x1f469 0x1f3fe 0x200d 0x2695
+0x1f469 0x1f3ff
+0x1f469 0x1f3ff 0x200d 0x1f33e
+0x1f469 0x1f3ff 0x200d 0x1f373
+0x1f469 0x1f3ff 0x200d 0x1f393
+0x1f469 0x1f3ff 0x200d 0x1f3a4
+0x1f469 0x1f3ff 0x200d 0x1f3eb
+0x1f469 0x1f3ff 0x200d 0x1f3ed
+0x1f469 0x1f3ff 0x200d 0x1f4bb
+0x1f469 0x1f3ff 0x200d 0x1f4bc
+0x1f469 0x1f3ff 0x200d 0x1f527
+0x1f469 0x1f3ff 0x200d 0x1f52c
+0x1f469 0x1f3ff 0x200d 0x2695
+0x1f469 0x200d 0x1f33e
+0x1f469 0x200d 0x1f373
+0x1f469 0x200d 0x1f393
+0x1f469 0x200d 0x1f3a4
+0x1f469 0x200d 0x1f3a8
+0x1f469 0x200d 0x1f3eb
+0x1f469 0x200d 0x1f3ed
+0x1f469 0x200d 0x1f466
+0x1f469 0x200d 0x1f466 0x200d 0x1f466
+0x1f469 0x200d 0x1f467
+0x1f469 0x200d 0x1f467 0x200d 0x1f466
+0x1f469 0x200d 0x1f467 0x200d 0x1f467
+0x1f469 0x200d 0x1f469 0x200d 0x1f466
+0x1f469 0x200d 0x1f469 0x200d 0x1f466 0x200d 0x1f466
+0x1f469 0x200d 0x1f469 0x200d 0x1f467
+0x1f469 0x200d 0x1f469 0x200d 0x1f467 0x200d 0x1f466
+0x1f469 0x200d 0x1f469 0x200d 0x1f467 0x200d 0x1f467
+0x1f469 0x200d 0x1f4bb
+0x1f469 0x200d 0x1f4bc
+0x1f469 0x200d 0x1f527
+0x1f469 0x200d 0x1f52c
+0x1f469 0x200d 0x1f680
+0x1f469 0x200d 0x1f692
+0x1f469 0x200d 0x2695
+0x1f469 0x200d 0x2696
+0x1f469 0x200d 0x2708
+0x1f469 0x200d 0x2764 0x200d 0x1f468
+0x1f469 0x200d 0x2764 0x200d 0x1f469
+0x1f469 0x200d 0x2764 0x200d 0x1f48b 0x200d 0x1f468
+0x1f469 0x200d 0x2764 0x200d 0x1f48b 0x200d 0x1f469
+0x1f46a
+0x1f46b
+0x1f46c
+0x1f46d
+0x1f46e
+0x1f46e 0x1f3fb
+0x1f46e 0x1f3fb 0x200d 0x2640
+0x1f46e 0x1f3fb 0x200d 0x2642
+0x1f46e 0x1f3fc
+0x1f46e 0x1f3fc 0x200d 0x2640
+0x1f46e 0x1f3fc 0x200d 0x2642
+0x1f46e 0x1f3fd
+0x1f46e 0x1f3fd 0x200d 0x2640
+0x1f46e 0x1f3fd 0x200d 0x2642
+0x1f46e 0x1f3fe
+0x1f46e 0x1f3fe 0x200d 0x2640
+0x1f46e 0x1f3fe 0x200d 0x2642
+0x1f46e 0x1f3ff
+0x1f46e 0x1f3ff 0x200d 0x2640
+0x1f46e 0x1f3ff 0x200d 0x2642
+0x1f46e 0x200d 0x2640
+0x1f46e 0x200d 0x2642
+0x1f46f
+0x1f46f 0x200d 0x2640
+0x1f46f 0x200d 0x2642
+0x1f470
+0x1f470 0x1f3fb
+0x1f470 0x1f3fc
+0x1f470 0x1f3fd
+0x1f470 0x1f3fe
+0x1f470 0x1f3ff
+0x1f471
+0x1f471 0x1f3fb
+0x1f471 0x1f3fb 0x200d 0x2640
+0x1f471 0x1f3fb 0x200d 0x2642
+0x1f471 0x1f3fc
+0x1f471 0x1f3fc 0x200d 0x2640
+0x1f471 0x1f3fc 0x200d 0x2642
+0x1f471 0x1f3fd
+0x1f471 0x1f3fd 0x200d 0x2640
+0x1f471 0x1f3fd 0x200d 0x2642
+0x1f471 0x1f3fe
+0x1f471 0x1f3fe 0x200d 0x2640
+0x1f471 0x1f3fe 0x200d 0x2642
+0x1f471 0x1f3ff
+0x1f471 0x1f3ff 0x200d 0x2640
+0x1f471 0x1f3ff 0x200d 0x2642
+0x1f471 0x200d 0x2640
+0x1f471 0x200d 0x2642
+0x1f472
+0x1f472 0x1f3fb
+0x1f472 0x1f3fc
+0x1f472 0x1f3fd
+0x1f472 0x1f3fe
+0x1f472 0x1f3ff
+0x1f473
+0x1f473 0x1f3fb
+0x1f473 0x1f3fb 0x200d 0x2640
+0x1f473 0x1f3fb 0x200d 0x2642
+0x1f473 0x1f3fc
+0x1f473 0x1f3fc 0x200d 0x2640
+0x1f473 0x1f3fc 0x200d 0x2642
+0x1f473 0x1f3fd
+0x1f473 0x1f3fd 0x200d 0x2640
+0x1f473 0x1f3fd 0x200d 0x2642
+0x1f473 0x1f3fe
+0x1f473 0x1f3fe 0x200d 0x2640
+0x1f473 0x1f3fe 0x200d 0x2642
+0x1f473 0x1f3ff
+0x1f473 0x1f3ff 0x200d 0x2640
+0x1f473 0x1f3ff 0x200d 0x2642
+0x1f473 0x200d 0x2640
+0x1f473 0x200d 0x2642
+0x1f474
+0x1f474 0x1f3fb
+0x1f474 0x1f3fc
+0x1f474 0x1f3fd
+0x1f474 0x1f3fe
+0x1f474 0x1f3ff
+0x1f475
+0x1f475 0x1f3fb
+0x1f475 0x1f3fc
+0x1f475 0x1f3fd
+0x1f475 0x1f3fe
+0x1f475 0x1f3ff
+0x1f476
+0x1f476 0x1f3fb
+0x1f476 0x1f3fc
+0x1f476 0x1f3fd
+0x1f476 0x1f3fe
+0x1f476 0x1f3ff
+0x1f477
+0x1f477 0x1f3fb
+0x1f477 0x1f3fb 0x200d 0x2640
+0x1f477 0x1f3fb 0x200d 0x2642
+0x1f477 0x1f3fc
+0x1f477 0x1f3fc 0x200d 0x2640
+0x1f477 0x1f3fc 0x200d 0x2642
+0x1f477 0x1f3fd
+0x1f477 0x1f3fd 0x200d 0x2640
+0x1f477 0x1f3fd 0x200d 0x2642
+0x1f477 0x1f3fe
+0x1f477 0x1f3fe 0x200d 0x2640
+0x1f477 0x1f3fe 0x200d 0x2642
+0x1f477 0x1f3ff
+0x1f477 0x1f3ff 0x200d 0x2640
+0x1f477 0x1f3ff 0x200d 0x2642
+0x1f477 0x200d 0x2640
+0x1f477 0x200d 0x2642
+0x1f478
+0x1f478 0x1f3fb
+0x1f478 0x1f3fc
+0x1f478 0x1f3fd
+0x1f478 0x1f3fe
+0x1f478 0x1f3ff
+0x1f479
+0x1f47a
+0x1f47b
+0x1f47c
+0x1f47c 0x1f3fb
+0x1f47c 0x1f3fc
+0x1f47c 0x1f3fd
+0x1f47c 0x1f3fe
+0x1f47c 0x1f3ff
+0x1f47d
+0x1f47e
+0x1f47f
+0x1f480
+0x1f481
+0x1f481 0x1f3fb
+0x1f481 0x1f3fb 0x200d 0x2640
+0x1f481 0x1f3fb 0x200d 0x2642
+0x1f481 0x1f3fc
+0x1f481 0x1f3fc 0x200d 0x2640
+0x1f481 0x1f3fc 0x200d 0x2642
+0x1f481 0x1f3fd
+0x1f481 0x1f3fd 0x200d 0x2640
+0x1f481 0x1f3fd 0x200d 0x2642
+0x1f481 0x1f3fe
+0x1f481 0x1f3fe 0x200d 0x2640
+0x1f481 0x1f3fe 0x200d 0x2642
+0x1f481 0x1f3ff
+0x1f481 0x1f3ff 0x200d 0x2640
+0x1f481 0x1f3ff 0x200d 0x2642
+0x1f481 0x200d 0x2640
+0x1f481 0x200d 0x2642
+0x1f482
+0x1f482 0x1f3fb
+0x1f482 0x1f3fb 0x200d 0x2640
+0x1f482 0x1f3fb 0x200d 0x2642
+0x1f482 0x1f3fc
+0x1f482 0x1f3fc 0x200d 0x2640
+0x1f482 0x1f3fc 0x200d 0x2642
+0x1f482 0x1f3fd
+0x1f482 0x1f3fd 0x200d 0x2640
+0x1f482 0x1f3fd 0x200d 0x2642
+0x1f482 0x1f3fe
+0x1f482 0x1f3fe 0x200d 0x2640
+0x1f482 0x1f3fe 0x200d 0x2642
+0x1f482 0x1f3ff
+0x1f482 0x1f3ff 0x200d 0x2640
+0x1f482 0x1f3ff 0x200d 0x2642
+0x1f482 0x200d 0x2640
+0x1f482 0x200d 0x2642
+0x1f483
+0x1f483 0x1f3fb
+0x1f483 0x1f3fc
+0x1f483 0x1f3fd
+0x1f483 0x1f3fe
+0x1f483 0x1f3ff
+0x1f484
+0x1f485
+0x1f485 0x1f3fb
+0x1f485 0x1f3fc
+0x1f485 0x1f3fd
+0x1f485 0x1f3fe
+0x1f485 0x1f3ff
+0x1f486
+0x1f486 0x1f3fb
+0x1f486 0x1f3fb 0x200d 0x2640
+0x1f486 0x1f3fb 0x200d 0x2642
+0x1f486 0x1f3fc
+0x1f486 0x1f3fc 0x200d 0x2640
+0x1f486 0x1f3fc 0x200d 0x2642
+0x1f486 0x1f3fd
+0x1f486 0x1f3fd 0x200d 0x2640
+0x1f486 0x1f3fd 0x200d 0x2642
+0x1f486 0x1f3fe
+0x1f486 0x1f3fe 0x200d 0x2640
+0x1f486 0x1f3fe 0x200d 0x2642
+0x1f486 0x1f3ff
+0x1f486 0x1f3ff 0x200d 0x2640
+0x1f486 0x1f3ff 0x200d 0x2642
+0x1f486 0x200d 0x2640
+0x1f486 0x200d 0x2642
+0x1f487
+0x1f487 0x1f3fb
+0x1f487 0x1f3fb 0x200d 0x2640
+0x1f487 0x1f3fb 0x200d 0x2642
+0x1f487 0x1f3fc
+0x1f487 0x1f3fc 0x200d 0x2640
+0x1f487 0x1f3fc 0x200d 0x2642
+0x1f487 0x1f3fd
+0x1f487 0x1f3fd 0x200d 0x2640
+0x1f487 0x1f3fd 0x200d 0x2642
+0x1f487 0x1f3fe
+0x1f487 0x1f3fe 0x200d 0x2640
+0x1f487 0x1f3fe 0x200d 0x2642
+0x1f487 0x1f3ff
+0x1f487 0x1f3ff 0x200d 0x2640
+0x1f487 0x1f3ff 0x200d 0x2642
+0x1f487 0x200d 0x2640
+0x1f487 0x200d 0x2642
+0x1f488
+0x1f489
+0x1f48a
+0x1f48b
+0x1f48c
+0x1f48d
+0x1f48e
+0x1f48f
+0x1f490
+0x1f491
+0x1f492
+0x1f493
+0x1f494
+0x1f495
+0x1f496
+0x1f497
+0x1f498
+0x1f499
+0x1f49a
+0x1f49b
+0x1f49c
+0x1f49d
+0x1f49e
+0x1f49f
+0x1f4a0
+0x1f4a1
+0x1f4a2
+0x1f4a3
+0x1f4a4
+0x1f4a5
+0x1f4a6
+0x1f4a7
+0x1f4a8
+0x1f4a9
+0x1f4aa
+0x1f4aa 0x1f3fb
+0x1f4aa 0x1f3fc
+0x1f4aa 0x1f3fd
+0x1f4aa 0x1f3fe
+0x1f4aa 0x1f3ff
+0x1f4ab
+0x1f4ac
+0x1f4ad
+0x1f4ae
+0x1f4af
+0x1f4b0
+0x1f4b1
+0x1f4b2
+0x1f4b3
+0x1f4b4
+0x1f4b5
+0x1f4b6
+0x1f4b7
+0x1f4b8
+0x1f4b9
+0x1f4ba
+0x1f4bb
+0x1f4bc
+0x1f4bd
+0x1f4be
+0x1f4bf
+0x1f4c0
+0x1f4c1
+0x1f4c2
+0x1f4c3
+0x1f4c4
+0x1f4c5
+0x1f4c6
+0x1f4c7
+0x1f4c8
+0x1f4c9
+0x1f4ca
+0x1f4cb
+0x1f4cc
+0x1f4cd
+0x1f4ce
+0x1f4cf
+0x1f4d0
+0x1f4d1
+0x1f4d2
+0x1f4d3
+0x1f4d4
+0x1f4d5
+0x1f4d6
+0x1f4d7
+0x1f4d8
+0x1f4d9
+0x1f4da
+0x1f4db
+0x1f4dc
+0x1f4dd
+0x1f4de
+0x1f4df
+0x1f4e0
+0x1f4e1
+0x1f4e2
+0x1f4e3
+0x1f4e4
+0x1f4e5
+0x1f4e6
+0x1f4e7
+0x1f4e8
+0x1f4e9
+0x1f4ea
+0x1f4eb
+0x1f4ec
+0x1f4ed
+0x1f4ee
+0x1f4ef
+0x1f4f0
+0x1f4f1
+0x1f4f2
+0x1f4f3
+0x1f4f4
+0x1f4f5
+0x1f4f6
+0x1f4f7
+0x1f4f8
+0x1f4f9
+0x1f4fa
+0x1f4fb
+0x1f4fc
+0x1f4fd 0xfe0f
+0x1f4ff
+0x1f500
+0x1f501
+0x1f502
+0x1f503
+0x1f504
+0x1f505
+0x1f506
+0x1f507
+0x1f508
+0x1f509
+0x1f50a
+0x1f50b
+0x1f50c
+0x1f50d
+0x1f50e
+0x1f50f
+0x1f510
+0x1f511
+0x1f512
+0x1f513
+0x1f514
+0x1f515
+0x1f516
+0x1f517
+0x1f518
+0x1f519
+0x1f51a
+0x1f51b
+0x1f51c
+0x1f51d
+0x1f51e
+0x1f51f
+0x1f520
+0x1f521
+0x1f522
+0x1f523
+0x1f524
+0x1f525
+0x1f526
+0x1f527
+0x1f528
+0x1f529
+0x1f52a
+0x1f52b
+0x1f52c
+0x1f52d
+0x1f52e
+0x1f52f
+0x1f530
+0x1f531
+0x1f532
+0x1f533
+0x1f534
+0x1f535
+0x1f536
+0x1f537
+0x1f538
+0x1f539
+0x1f53a
+0x1f53b
+0x1f53c
+0x1f53d
+0x1f549 0xfe0f
+0x1f54a 0xfe0f
+0x1f54b
+0x1f54c
+0x1f54d
+0x1f54e
+0x1f550
+0x1f551
+0x1f552
+0x1f553
+0x1f554
+0x1f555
+0x1f556
+0x1f557
+0x1f558
+0x1f559
+0x1f55a
+0x1f55b
+0x1f55c
+0x1f55d
+0x1f55e
+0x1f55f
+0x1f560
+0x1f561
+0x1f562
+0x1f563
+0x1f564
+0x1f565
+0x1f566
+0x1f567
+0x1f56f 0xfe0f
+0x1f570 0xfe0f
+0x1f573 0xfe0f
+0x1f574 0xfe0f
+0x1f575 0x1f3fb
+0x1f575 0x1f3fb 0x200d 0x2640
+0x1f575 0x1f3fb 0x200d 0x2642
+0x1f575 0x1f3fc
+0x1f575 0x1f3fc 0x200d 0x2640
+0x1f575 0x1f3fc 0x200d 0x2642
+0x1f575 0x1f3fd
+0x1f575 0x1f3fd 0x200d 0x2640
+0x1f575 0x1f3fd 0x200d 0x2642
+0x1f575 0x1f3fe
+0x1f575 0x1f3fe 0x200d 0x2640
+0x1f575 0x1f3fe 0x200d 0x2642
+0x1f575 0x1f3ff
+0x1f575 0x1f3ff 0x200d 0x2640
+0x1f575 0x1f3ff 0x200d 0x2642
+0x1f575 0x200d 0x2640
+0x1f575 0x200d 0x2642
+0x1f575 0xfe0f
+0x1f576 0xfe0f
+0x1f577 0xfe0f
+0x1f578 0xfe0f
+0x1f579 0xfe0f
+0x1f57a
+0x1f57a 0x1f3fb
+0x1f57a 0x1f3fc
+0x1f57a 0x1f3fd
+0x1f57a 0x1f3fe
+0x1f57a 0x1f3ff
+0x1f587 0xfe0f
+0x1f58a 0xfe0f
+0x1f58b 0xfe0f
+0x1f58c 0xfe0f
+0x1f58d 0xfe0f
+0x1f590 0x1f3fb
+0x1f590 0x1f3fc
+0x1f590 0x1f3fd
+0x1f590 0x1f3fe
+0x1f590 0x1f3ff
+0x1f590 0xfe0f
+0x1f595
+0x1f595 0x1f3fb
+0x1f595 0x1f3fc
+0x1f595 0x1f3fd
+0x1f595 0x1f3fe
+0x1f595 0x1f3ff
+0x1f596
+0x1f596 0x1f3fb
+0x1f596 0x1f3fc
+0x1f596 0x1f3fd
+0x1f596 0x1f3fe
+0x1f596 0x1f3ff
+0x1f5a4
+0x1f5a5 0xfe0f
+0x1f5a8 0xfe0f
+0x1f5b1 0xfe0f
+0x1f5b2 0xfe0f
+0x1f5bc 0xfe0f
+0x1f5c2 0xfe0f
+0x1f5c3 0xfe0f
+0x1f5c4 0xfe0f
+0x1f5d1 0xfe0f
+0x1f5d2 0xfe0f
+0x1f5d3 0xfe0f
+0x1f5dc 0xfe0f
+0x1f5dd 0xfe0f
+0x1f5de 0xfe0f
+0x1f5e1 0xfe0f
+0x1f5e3 0xfe0f
+0x1f5e8 0xfe0f
+0x1f5ef 0xfe0f
+0x1f5f3 0xfe0f
+0x1f5fa 0xfe0f
+0x1f5fb
+0x1f5fc
+0x1f5fd
+0x1f5fe
+0x1f5ff
+0x1f600
+0x1f601
+0x1f602
+0x1f603
+0x1f604
+0x1f605
+0x1f606
+0x1f607
+0x1f608
+0x1f609
+0x1f60a
+0x1f60b
+0x1f60c
+0x1f60d
+0x1f60e
+0x1f60f
+0x1f610
+0x1f611
+0x1f612
+0x1f613
+0x1f614
+0x1f615
+0x1f616
+0x1f617
+0x1f618
+0x1f619
+0x1f61a
+0x1f61b
+0x1f61c
+0x1f61d
+0x1f61e
+0x1f61f
+0x1f620
+0x1f621
+0x1f622
+0x1f623
+0x1f624
+0x1f625
+0x1f626
+0x1f627
+0x1f628
+0x1f629
+0x1f62a
+0x1f62b
+0x1f62c
+0x1f62d
+0x1f62e
+0x1f62f
+0x1f630
+0x1f631
+0x1f632
+0x1f633
+0x1f634
+0x1f635
+0x1f636
+0x1f637
+0x1f638
+0x1f639
+0x1f63a
+0x1f63b
+0x1f63c
+0x1f63d
+0x1f63e
+0x1f63f
+0x1f640
+0x1f641
+0x1f642
+0x1f643
+0x1f644
+0x1f645
+0x1f645 0x1f3fb
+0x1f645 0x1f3fb 0x200d 0x2640
+0x1f645 0x1f3fb 0x200d 0x2642
+0x1f645 0x1f3fc
+0x1f645 0x1f3fc 0x200d 0x2640
+0x1f645 0x1f3fc 0x200d 0x2642
+0x1f645 0x1f3fd
+0x1f645 0x1f3fd 0x200d 0x2640
+0x1f645 0x1f3fd 0x200d 0x2642
+0x1f645 0x1f3fe
+0x1f645 0x1f3fe 0x200d 0x2640
+0x1f645 0x1f3fe 0x200d 0x2642
+0x1f645 0x1f3ff
+0x1f645 0x1f3ff 0x200d 0x2640
+0x1f645 0x1f3ff 0x200d 0x2642
+0x1f645 0x200d 0x2640
+0x1f645 0x200d 0x2642
+0x1f646
+0x1f646 0x1f3fb
+0x1f646 0x1f3fb 0x200d 0x2640
+0x1f646 0x1f3fb 0x200d 0x2642
+0x1f646 0x1f3fc
+0x1f646 0x1f3fc 0x200d 0x2640
+0x1f646 0x1f3fc 0x200d 0x2642
+0x1f646 0x1f3fd
+0x1f646 0x1f3fd 0x200d 0x2640
+0x1f646 0x1f3fd 0x200d 0x2642
+0x1f646 0x1f3fe
+0x1f646 0x1f3fe 0x200d 0x2640
+0x1f646 0x1f3fe 0x200d 0x2642
+0x1f646 0x1f3ff
+0x1f646 0x1f3ff 0x200d 0x2640
+0x1f646 0x1f3ff 0x200d 0x2642
+0x1f646 0x200d 0x2640
+0x1f646 0x200d 0x2642
+0x1f647
+0x1f647 0x1f3fb
+0x1f647 0x1f3fb 0x200d 0x2640
+0x1f647 0x1f3fb 0x200d 0x2642
+0x1f647 0x1f3fc
+0x1f647 0x1f3fc 0x200d 0x2640
+0x1f647 0x1f3fc 0x200d 0x2642
+0x1f647 0x1f3fd
+0x1f647 0x1f3fd 0x200d 0x2640
+0x1f647 0x1f3fd 0x200d 0x2642
+0x1f647 0x1f3fe
+0x1f647 0x1f3fe 0x200d 0x2640
+0x1f647 0x1f3fe 0x200d 0x2642
+0x1f647 0x1f3ff
+0x1f647 0x1f3ff 0x200d 0x2640
+0x1f647 0x1f3ff 0x200d 0x2642
+0x1f647 0x200d 0x2640
+0x1f647 0x200d 0x2642
+0x1f648
+0x1f649
+0x1f64a
+0x1f64b
+0x1f64b 0x1f3fb
+0x1f64b 0x1f3fb 0x200d 0x2640
+0x1f64b 0x1f3fb 0x200d 0x2642
+0x1f64b 0x1f3fc
+0x1f64b 0x1f3fc 0x200d 0x2640
+0x1f64b 0x1f3fc 0x200d 0x2642
+0x1f64b 0x1f3fd
+0x1f64b 0x1f3fd 0x200d 0x2640
+0x1f64b 0x1f3fd 0x200d 0x2642
+0x1f64b 0x1f3fe
+0x1f64b 0x1f3fe 0x200d 0x2640
+0x1f64b 0x1f3fe 0x200d 0x2642
+0x1f64b 0x1f3ff
+0x1f64b 0x1f3ff 0x200d 0x2640
+0x1f64b 0x1f3ff 0x200d 0x2642
+0x1f64b 0x200d 0x2640
+0x1f64b 0x200d 0x2642
+0x1f64c
+0x1f64c 0x1f3fb
+0x1f64c 0x1f3fc
+0x1f64c 0x1f3fd
+0x1f64c 0x1f3fe
+0x1f64c 0x1f3ff
+0x1f64d
+0x1f64d 0x1f3fb
+0x1f64d 0x1f3fb 0x200d 0x2640
+0x1f64d 0x1f3fb 0x200d 0x2642
+0x1f64d 0x1f3fc
+0x1f64d 0x1f3fc 0x200d 0x2640
+0x1f64d 0x1f3fc 0x200d 0x2642
+0x1f64d 0x1f3fd
+0x1f64d 0x1f3fd 0x200d 0x2640
+0x1f64d 0x1f3fd 0x200d 0x2642
+0x1f64d 0x1f3fe
+0x1f64d 0x1f3fe 0x200d 0x2640
+0x1f64d 0x1f3fe 0x200d 0x2642
+0x1f64d 0x1f3ff
+0x1f64d 0x1f3ff 0x200d 0x2640
+0x1f64d 0x1f3ff 0x200d 0x2642
+0x1f64d 0x200d 0x2640
+0x1f64d 0x200d 0x2642
+0x1f64e
+0x1f64e 0x1f3fb
+0x1f64e 0x1f3fb 0x200d 0x2640
+0x1f64e 0x1f3fb 0x200d 0x2642
+0x1f64e 0x1f3fc
+0x1f64e 0x1f3fc 0x200d 0x2640
+0x1f64e 0x1f3fc 0x200d 0x2642
+0x1f64e 0x1f3fd
+0x1f64e 0x1f3fd 0x200d 0x2640
+0x1f64e 0x1f3fd 0x200d 0x2642
+0x1f64e 0x1f3fe
+0x1f64e 0x1f3fe 0x200d 0x2640
+0x1f64e 0x1f3fe 0x200d 0x2642
+0x1f64e 0x1f3ff
+0x1f64e 0x1f3ff 0x200d 0x2640
+0x1f64e 0x1f3ff 0x200d 0x2642
+0x1f64e 0x200d 0x2640
+0x1f64e 0x200d 0x2642
+0x1f64f
+0x1f64f 0x1f3fb
+0x1f64f 0x1f3fc
+0x1f64f 0x1f3fd
+0x1f64f 0x1f3fe
+0x1f64f 0x1f3ff
+0x1f680
+0x1f681
+0x1f682
+0x1f683
+0x1f684
+0x1f685
+0x1f686
+0x1f687
+0x1f688
+0x1f689
+0x1f68a
+0x1f68b
+0x1f68c
+0x1f68d
+0x1f68e
+0x1f68f
+0x1f690
+0x1f691
+0x1f692
+0x1f693
+0x1f694
+0x1f695
+0x1f696
+0x1f697
+0x1f698
+0x1f699
+0x1f69a
+0x1f69b
+0x1f69c
+0x1f69d
+0x1f69e
+0x1f69f
+0x1f6a0
+0x1f6a1
+0x1f6a2
+0x1f6a3
+0x1f6a3 0x1f3fb
+0x1f6a3 0x1f3fb 0x200d 0x2640
+0x1f6a3 0x1f3fb 0x200d 0x2642
+0x1f6a3 0x1f3fc
+0x1f6a3 0x1f3fc 0x200d 0x2640
+0x1f6a3 0x1f3fc 0x200d 0x2642
+0x1f6a3 0x1f3fd
+0x1f6a3 0x1f3fd 0x200d 0x2640
+0x1f6a3 0x1f3fd 0x200d 0x2642
+0x1f6a3 0x1f3fe
+0x1f6a3 0x1f3fe 0x200d 0x2640
+0x1f6a3 0x1f3fe 0x200d 0x2642
+0x1f6a3 0x1f3ff
+0x1f6a3 0x1f3ff 0x200d 0x2640
+0x1f6a3 0x1f3ff 0x200d 0x2642
+0x1f6a3 0x200d 0x2640
+0x1f6a3 0x200d 0x2642
+0x1f6a4
+0x1f6a5
+0x1f6a6
+0x1f6a7
+0x1f6a8
+0x1f6a9
+0x1f6aa
+0x1f6ab
+0x1f6ac
+0x1f6ad
+0x1f6ae
+0x1f6af
+0x1f6b0
+0x1f6b1
+0x1f6b2
+0x1f6b3
+0x1f6b4
+0x1f6b4 0x1f3fb
+0x1f6b4 0x1f3fb 0x200d 0x2640
+0x1f6b4 0x1f3fb 0x200d 0x2642
+0x1f6b4 0x1f3fc
+0x1f6b4 0x1f3fc 0x200d 0x2640
+0x1f6b4 0x1f3fc 0x200d 0x2642
+0x1f6b4 0x1f3fd
+0x1f6b4 0x1f3fd 0x200d 0x2640
+0x1f6b4 0x1f3fd 0x200d 0x2642
+0x1f6b4 0x1f3fe
+0x1f6b4 0x1f3fe 0x200d 0x2640
+0x1f6b4 0x1f3fe 0x200d 0x2642
+0x1f6b4 0x1f3ff
+0x1f6b4 0x1f3ff 0x200d 0x2640
+0x1f6b4 0x1f3ff 0x200d 0x2642
+0x1f6b4 0x200d 0x2640
+0x1f6b4 0x200d 0x2642
+0x1f6b5
+0x1f6b5 0x1f3fb
+0x1f6b5 0x1f3fb 0x200d 0x2640
+0x1f6b5 0x1f3fb 0x200d 0x2642
+0x1f6b5 0x1f3fc
+0x1f6b5 0x1f3fc 0x200d 0x2640
+0x1f6b5 0x1f3fc 0x200d 0x2642
+0x1f6b5 0x1f3fd
+0x1f6b5 0x1f3fd 0x200d 0x2640
+0x1f6b5 0x1f3fd 0x200d 0x2642
+0x1f6b5 0x1f3fe
+0x1f6b5 0x1f3fe 0x200d 0x2640
+0x1f6b5 0x1f3fe 0x200d 0x2642
+0x1f6b5 0x1f3ff
+0x1f6b5 0x1f3ff 0x200d 0x2640
+0x1f6b5 0x1f3ff 0x200d 0x2642
+0x1f6b5 0x200d 0x2640
+0x1f6b5 0x200d 0x2642
+0x1f6b6
+0x1f6b6 0x1f3fb
+0x1f6b6 0x1f3fb 0x200d 0x2640
+0x1f6b6 0x1f3fb 0x200d 0x2642
+0x1f6b6 0x1f3fc
+0x1f6b6 0x1f3fc 0x200d 0x2640
+0x1f6b6 0x1f3fc 0x200d 0x2642
+0x1f6b6 0x1f3fd
+0x1f6b6 0x1f3fd 0x200d 0x2640
+0x1f6b6 0x1f3fd 0x200d 0x2642
+0x1f6b6 0x1f3fe
+0x1f6b6 0x1f3fe 0x200d 0x2640
+0x1f6b6 0x1f3fe 0x200d 0x2642
+0x1f6b6 0x1f3ff
+0x1f6b6 0x1f3ff 0x200d 0x2640
+0x1f6b6 0x1f3ff 0x200d 0x2642
+0x1f6b6 0x200d 0x2640
+0x1f6b6 0x200d 0x2642
+0x1f6b7
+0x1f6b8
+0x1f6b9
+0x1f6ba
+0x1f6bb
+0x1f6bc
+0x1f6bd
+0x1f6be
+0x1f6bf
+0x1f6c0
+0x1f6c0 0x1f3fb
+0x1f6c0 0x1f3fc
+0x1f6c0 0x1f3fd
+0x1f6c0 0x1f3fe
+0x1f6c0 0x1f3ff
+0x1f6c1
+0x1f6c2
+0x1f6c3
+0x1f6c4
+0x1f6c5
+0x1f6cb 0xfe0f
+0x1f6cc
+0x1f6cd 0xfe0f
+0x1f6ce 0xfe0f
+0x1f6cf 0xfe0f
+0x1f6d0
+0x1f6d1
+0x1f6d2
+0x1f6e0 0xfe0f
+0x1f6e1 0xfe0f
+0x1f6e2 0xfe0f
+0x1f6e3 0xfe0f
+0x1f6e4 0xfe0f
+0x1f6e5 0xfe0f
+0x1f6e9 0xfe0f
+0x1f6eb
+0x1f6ec
+0x1f6f0 0xfe0f
+0x1f6f3 0xfe0f
+0x1f6f4
+0x1f6f5
+0x1f6f6
+0x1f910
+0x1f911
+0x1f912
+0x1f913
+0x1f914
+0x1f915
+0x1f916
+0x1f917
+0x1f918
+0x1f918 0x1f3fb
+0x1f918 0x1f3fc
+0x1f918 0x1f3fd
+0x1f918 0x1f3fe
+0x1f918 0x1f3ff
+0x1f919
+0x1f919 0x1f3fb
+0x1f919 0x1f3fc
+0x1f919 0x1f3fd
+0x1f919 0x1f3fe
+0x1f919 0x1f3ff
+0x1f91a
+0x1f91a 0x1f3fb
+0x1f91a 0x1f3fc
+0x1f91a 0x1f3fd
+0x1f91a 0x1f3fe
+0x1f91a 0x1f3ff
+0x1f91b
+0x1f91b 0x1f3fb
+0x1f91b 0x1f3fc
+0x1f91b 0x1f3fd
+0x1f91b 0x1f3fe
+0x1f91b 0x1f3ff
+0x1f91c
+0x1f91c 0x1f3fb
+0x1f91c 0x1f3fc
+0x1f91c 0x1f3fd
+0x1f91c 0x1f3fe
+0x1f91c 0x1f3ff
+0x1f91d
+0x1f91d 0x1f3fb
+0x1f91d 0x1f3fc
+0x1f91d 0x1f3fd
+0x1f91d 0x1f3fe
+0x1f91d 0x1f3ff
+0x1f91e
+0x1f91e 0x1f3fb
+0x1f91e 0x1f3fc
+0x1f91e 0x1f3fd
+0x1f91e 0x1f3fe
+0x1f91e 0x1f3ff
+0x1f920
+0x1f921
+0x1f922
+0x1f923
+0x1f924
+0x1f925
+0x1f926
+0x1f926 0x1f3fb
+0x1f926 0x1f3fb 0x200d 0x2640
+0x1f926 0x1f3fb 0x200d 0x2642
+0x1f926 0x1f3fc
+0x1f926 0x1f3fc 0x200d 0x2640
+0x1f926 0x1f3fc 0x200d 0x2642
+0x1f926 0x1f3fd
+0x1f926 0x1f3fd 0x200d 0x2640
+0x1f926 0x1f3fd 0x200d 0x2642
+0x1f926 0x1f3fe
+0x1f926 0x1f3fe 0x200d 0x2640
+0x1f926 0x1f3fe 0x200d 0x2642
+0x1f926 0x1f3ff
+0x1f926 0x1f3ff 0x200d 0x2640
+0x1f926 0x1f3ff 0x200d 0x2642
+0x1f926 0x200d 0x2640
+0x1f926 0x200d 0x2642
+0x1f927
+0x1f930
+0x1f930 0x1f3fb
+0x1f930 0x1f3fc
+0x1f930 0x1f3fd
+0x1f930 0x1f3fe
+0x1f930 0x1f3ff
+0x1f933
+0x1f933 0x1f3fb
+0x1f933 0x1f3fc
+0x1f933 0x1f3fd
+0x1f933 0x1f3fe
+0x1f933 0x1f3ff
+0x1f934
+0x1f934 0x1f3fb
+0x1f934 0x1f3fc
+0x1f934 0x1f3fd
+0x1f934 0x1f3fe
+0x1f934 0x1f3ff
+0x1f935
+0x1f935 0x1f3fb
+0x1f935 0x1f3fc
+0x1f935 0x1f3fd
+0x1f935 0x1f3fe
+0x1f935 0x1f3ff
+0x1f936
+0x1f936 0x1f3fb
+0x1f936 0x1f3fc
+0x1f936 0x1f3fd
+0x1f936 0x1f3fe
+0x1f936 0x1f3ff
+0x1f937
+0x1f937 0x1f3fb
+0x1f937 0x1f3fb 0x200d 0x2640
+0x1f937 0x1f3fb 0x200d 0x2642
+0x1f937 0x1f3fc
+0x1f937 0x1f3fc 0x200d 0x2640
+0x1f937 0x1f3fc 0x200d 0x2642
+0x1f937 0x1f3fd
+0x1f937 0x1f3fd 0x200d 0x2640
+0x1f937 0x1f3fd 0x200d 0x2642
+0x1f937 0x1f3fe
+0x1f937 0x1f3fe 0x200d 0x2640
+0x1f937 0x1f3fe 0x200d 0x2642
+0x1f937 0x1f3ff
+0x1f937 0x1f3ff 0x200d 0x2640
+0x1f937 0x1f3ff 0x200d 0x2642
+0x1f937 0x200d 0x2640
+0x1f937 0x200d 0x2642
+0x1f938
+0x1f938 0x1f3fb
+0x1f938 0x1f3fb 0x200d 0x2640
+0x1f938 0x1f3fb 0x200d 0x2642
+0x1f938 0x1f3fc
+0x1f938 0x1f3fc 0x200d 0x2640
+0x1f938 0x1f3fc 0x200d 0x2642
+0x1f938 0x1f3fd
+0x1f938 0x1f3fd 0x200d 0x2640
+0x1f938 0x1f3fd 0x200d 0x2642
+0x1f938 0x1f3fe
+0x1f938 0x1f3fe 0x200d 0x2640
+0x1f938 0x1f3fe 0x200d 0x2642
+0x1f938 0x1f3ff
+0x1f938 0x1f3ff 0x200d 0x2640
+0x1f938 0x1f3ff 0x200d 0x2642
+0x1f938 0x200d 0x2640
+0x1f938 0x200d 0x2642
+0x1f939
+0x1f939 0x1f3fb
+0x1f939 0x1f3fb 0x200d 0x2640
+0x1f939 0x1f3fb 0x200d 0x2642
+0x1f939 0x1f3fc
+0x1f939 0x1f3fc 0x200d 0x2640
+0x1f939 0x1f3fc 0x200d 0x2642
+0x1f939 0x1f3fd
+0x1f939 0x1f3fd 0x200d 0x2640
+0x1f939 0x1f3fd 0x200d 0x2642
+0x1f939 0x1f3fe
+0x1f939 0x1f3fe 0x200d 0x2640
+0x1f939 0x1f3fe 0x200d 0x2642
+0x1f939 0x1f3ff
+0x1f939 0x1f3ff 0x200d 0x2640
+0x1f939 0x1f3ff 0x200d 0x2642
+0x1f939 0x200d 0x2640
+0x1f939 0x200d 0x2642
+0x1f93a
+0x1f93c
+0x1f93c 0x1f3fb
+0x1f93c 0x1f3fb 0x200d 0x2640
+0x1f93c 0x1f3fb 0x200d 0x2642
+0x1f93c 0x1f3fc
+0x1f93c 0x1f3fc 0x200d 0x2640
+0x1f93c 0x1f3fc 0x200d 0x2642
+0x1f93c 0x1f3fd
+0x1f93c 0x1f3fd 0x200d 0x2640
+0x1f93c 0x1f3fd 0x200d 0x2642
+0x1f93c 0x1f3fe
+0x1f93c 0x1f3fe 0x200d 0x2640
+0x1f93c 0x1f3fe 0x200d 0x2642
+0x1f93c 0x1f3ff
+0x1f93c 0x1f3ff 0x200d 0x2640
+0x1f93c 0x1f3ff 0x200d 0x2642
+0x1f93c 0x200d 0x2640
+0x1f93c 0x200d 0x2642
+0x1f93d
+0x1f93d 0x1f3fb
+0x1f93d 0x1f3fb 0x200d 0x2640
+0x1f93d 0x1f3fb 0x200d 0x2642
+0x1f93d 0x1f3fc
+0x1f93d 0x1f3fc 0x200d 0x2640
+0x1f93d 0x1f3fc 0x200d 0x2642
+0x1f93d 0x1f3fd
+0x1f93d 0x1f3fd 0x200d 0x2640
+0x1f93d 0x1f3fd 0x200d 0x2642
+0x1f93d 0x1f3fe
+0x1f93d 0x1f3fe 0x200d 0x2640
+0x1f93d 0x1f3fe 0x200d 0x2642
+0x1f93d 0x1f3ff
+0x1f93d 0x1f3ff 0x200d 0x2640
+0x1f93d 0x1f3ff 0x200d 0x2642
+0x1f93d 0x200d 0x2640
+0x1f93d 0x200d 0x2642
+0x1f93e
+0x1f93e 0x1f3fb
+0x1f93e 0x1f3fb 0x200d 0x2640
+0x1f93e 0x1f3fb 0x200d 0x2642
+0x1f93e 0x1f3fc
+0x1f93e 0x1f3fc 0x200d 0x2640
+0x1f93e 0x1f3fc 0x200d 0x2642
+0x1f93e 0x1f3fd
+0x1f93e 0x1f3fd 0x200d 0x2640
+0x1f93e 0x1f3fd 0x200d 0x2642
+0x1f93e 0x1f3fe
+0x1f93e 0x1f3fe 0x200d 0x2640
+0x1f93e 0x1f3fe 0x200d 0x2642
+0x1f93e 0x1f3ff
+0x1f93e 0x1f3ff 0x200d 0x2640
+0x1f93e 0x1f3ff 0x200d 0x2642
+0x1f93e 0x200d 0x2640
+0x1f93e 0x200d 0x2642
+0x1f940
+0x1f941
+0x1f942
+0x1f943
+0x1f944
+0x1f945
+0x1f947
+0x1f948
+0x1f949
+0x1f94a
+0x1f94b
+0x1f950
+0x1f951
+0x1f952
+0x1f953
+0x1f954
+0x1f955
+0x1f956
+0x1f957
+0x1f958
+0x1f959
+0x1f95a
+0x1f95b
+0x1f95c
+0x1f95d
+0x1f95e
+0x1f980
+0x1f981
+0x1f982
+0x1f983
+0x1f984
+0x1f985
+0x1f986
+0x1f987
+0x1f988
+0x1f989
+0x1f98a
+0x1f98b
+0x1f98c
+0x1f98d
+0x1f98e
+0x1f98f
+0x1f990
+0x1f991
+0x1f9c0
+0x203c 0xfe0f
+0x2049 0xfe0f
+0x2122 0xfe0f
+0x2139 0xfe0f
+0x2194 0xfe0f
+0x2195 0xfe0f
+0x2196 0xfe0f
+0x2197 0xfe0f
+0x2198 0xfe0f
+0x2199 0xfe0f
+0x21a9 0xfe0f
+0x21aa 0xfe0f
+0x23 0x20e3
+0x23 0xfe0f
+0x231a
+0x231a 0xfe0f
+0x231b
+0x231b 0xfe0f
+0x2328 0xfe0f
+0x23cf 0xfe0f
+0x23e9
+0x23ea
+0x23eb
+0x23ec
+0x23ed 0xfe0f
+0x23ee 0xfe0f
+0x23ef 0xfe0f
+0x23f0
+0x23f1 0xfe0f
+0x23f2 0xfe0f
+0x23f3
+0x23f8 0xfe0f
+0x23f9 0xfe0f
+0x23fa 0xfe0f
+0x24c2 0xfe0f
+0x25aa 0xfe0f
+0x25ab 0xfe0f
+0x25b6 0xfe0f
+0x25c0 0xfe0f
+0x25fb 0xfe0f
+0x25fc 0xfe0f
+0x25fd
+0x25fd 0xfe0f
+0x25fe
+0x25fe 0xfe0f
+0x2600 0xfe0f
+0x2601 0xfe0f
+0x2602 0xfe0f
+0x2603 0xfe0f
+0x2604 0xfe0f
+0x260e 0xfe0f
+0x2611 0xfe0f
+0x2614
+0x2614 0xfe0f
+0x2615
+0x2615 0xfe0f
+0x2618 0xfe0f
+0x261d 0x1f3fb
+0x261d 0x1f3fc
+0x261d 0x1f3fd
+0x261d 0x1f3fe
+0x261d 0x1f3ff
+0x261d 0xfe0f
+0x2620 0xfe0f
+0x2622 0xfe0f
+0x2623 0xfe0f
+0x2626 0xfe0f
+0x262a 0xfe0f
+0x262e 0xfe0f
+0x262f 0xfe0f
+0x2638 0xfe0f
+0x2639 0xfe0f
+0x263a 0xfe0f
+0x2640 0xfe0f
+0x2642 0xfe0f
+0x2648
+0x2648 0xfe0f
+0x2649
+0x2649 0xfe0f
+0x264a
+0x264a 0xfe0f
+0x264b
+0x264b 0xfe0f
+0x264c
+0x264c 0xfe0f
+0x264d
+0x264d 0xfe0f
+0x264e
+0x264e 0xfe0f
+0x264f
+0x264f 0xfe0f
+0x2650
+0x2650 0xfe0f
+0x2651
+0x2651 0xfe0f
+0x2652
+0x2652 0xfe0f
+0x2653
+0x2653 0xfe0f
+0x2660 0xfe0f
+0x2663 0xfe0f
+0x2665 0xfe0f
+0x2666 0xfe0f
+0x2668 0xfe0f
+0x267b 0xfe0f
+0x267f
+0x267f 0xfe0f
+0x2692 0xfe0f
+0x2693
+0x2693 0xfe0f
+0x2694 0xfe0f
+0x2695 0xfe0f
+0x2696 0xfe0f
+0x2697 0xfe0f
+0x2699 0xfe0f
+0x269b 0xfe0f
+0x269c 0xfe0f
+0x26a0 0xfe0f
+0x26a1
+0x26a1 0xfe0f
+0x26aa
+0x26aa 0xfe0f
+0x26ab
+0x26ab 0xfe0f
+0x26b0 0xfe0f
+0x26b1 0xfe0f
+0x26bd
+0x26bd 0xfe0f
+0x26be
+0x26be 0xfe0f
+0x26c4
+0x26c4 0xfe0f
+0x26c5
+0x26c5 0xfe0f
+0x26c8 0xfe0f
+0x26ce
+0x26cf 0xfe0f
+0x26d1 0xfe0f
+0x26d3 0xfe0f
+0x26d4
+0x26d4 0xfe0f
+0x26e9 0xfe0f
+0x26ea
+0x26ea 0xfe0f
+0x26f0 0xfe0f
+0x26f1 0xfe0f
+0x26f2
+0x26f2 0xfe0f
+0x26f3
+0x26f3 0xfe0f
+0x26f4 0xfe0f
+0x26f5
+0x26f5 0xfe0f
+0x26f7 0xfe0f
+0x26f8 0xfe0f
+0x26f9 0x1f3fb
+0x26f9 0x1f3fb 0x200d 0x2640
+0x26f9 0x1f3fb 0x200d 0x2642
+0x26f9 0x1f3fc
+0x26f9 0x1f3fc 0x200d 0x2640
+0x26f9 0x1f3fc 0x200d 0x2642
+0x26f9 0x1f3fd
+0x26f9 0x1f3fd 0x200d 0x2640
+0x26f9 0x1f3fd 0x200d 0x2642
+0x26f9 0x1f3fe
+0x26f9 0x1f3fe 0x200d 0x2640
+0x26f9 0x1f3fe 0x200d 0x2642
+0x26f9 0x1f3ff
+0x26f9 0x1f3ff 0x200d 0x2640
+0x26f9 0x1f3ff 0x200d 0x2642
+0x26f9 0x200d 0x2640
+0x26f9 0x200d 0x2642
+0x26f9 0xfe0f
+0x26fa
+0x26fa 0xfe0f
+0x26fd
+0x26fd 0xfe0f
+0x2702 0xfe0f
+0x2705
+0x2708 0xfe0f
+0x2709 0xfe0f
+0x270a
+0x270a 0x1f3fb
+0x270a 0x1f3fc
+0x270a 0x1f3fd
+0x270a 0x1f3fe
+0x270a 0x1f3ff
+0x270b
+0x270b 0x1f3fb
+0x270b 0x1f3fc
+0x270b 0x1f3fd
+0x270b 0x1f3fe
+0x270b 0x1f3ff
+0x270c 0x1f3fb
+0x270c 0x1f3fc
+0x270c 0x1f3fd
+0x270c 0x1f3fe
+0x270c 0x1f3ff
+0x270c 0xfe0f
+0x270d 0x1f3fb
+0x270d 0x1f3fc
+0x270d 0x1f3fd
+0x270d 0x1f3fe
+0x270d 0x1f3ff
+0x270d 0xfe0f
+0x270f 0xfe0f
+0x2712 0xfe0f
+0x2714 0xfe0f
+0x2716 0xfe0f
+0x271d 0xfe0f
+0x2721 0xfe0f
+0x2728
+0x2733 0xfe0f
+0x2734 0xfe0f
+0x2744 0xfe0f
+0x2747 0xfe0f
+0x274c
+0x274e
+0x2753
+0x2754
+0x2755
+0x2757
+0x2757 0xfe0f
+0x2763 0xfe0f
+0x2764 0xfe0f
+0x2795
+0x2796
+0x2797
+0x27a1 0xfe0f
+0x27b0
+0x27bf
+0x2934 0xfe0f
+0x2935 0xfe0f
+0x2a 0x20e3
+0x2a 0xfe0f
+0x2b05 0xfe0f
+0x2b06 0xfe0f
+0x2b07 0xfe0f
+0x2b1b
+0x2b1b 0xfe0f
+0x2b1c
+0x2b1c 0xfe0f
+0x2b50
+0x2b50 0xfe0f
+0x2b55
+0x2b55 0xfe0f
+0x30 0x20e3
+0x30 0xfe0f
+0x3030 0xfe0f
+0x303d 0xfe0f
+0x31 0x20e3
+0x31 0xfe0f
+0x32 0x20e3
+0x32 0xfe0f
+0x3297 0xfe0f
+0x3299 0xfe0f
+0x33 0x20e3
+0x33 0xfe0f
+0x34 0x20e3
+0x34 0xfe0f
+0x35 0x20e3
+0x35 0xfe0f
+0x36 0x20e3
+0x36 0xfe0f
+0x37 0x20e3
+0x37 0xfe0f
+0x38 0x20e3
+0x38 0xfe0f
+0x39 0x20e3
+0x39 0xfe0f
+0xa9 0xfe0f
+0xae 0xfe0f
\ No newline at end of file
diff --git a/emoji/core/third_party/flatbuffers/FLATBUFFERS_LICENSE.txt b/emoji/core/third_party/flatbuffers/FLATBUFFERS_LICENSE.txt
new file mode 100644
index 0000000..6c4f91c
--- /dev/null
+++ b/emoji/core/third_party/flatbuffers/FLATBUFFERS_LICENSE.txt
@@ -0,0 +1,202 @@
+
+ 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 2014 Google Inc.
+
+ 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.
\ No newline at end of file
diff --git a/emoji/core/third_party/flatbuffers/flatbuffers-java-1.6.0.jar b/emoji/core/third_party/flatbuffers/flatbuffers-java-1.6.0.jar
new file mode 100644
index 0000000..65cd337
--- /dev/null
+++ b/emoji/core/third_party/flatbuffers/flatbuffers-java-1.6.0.jar
Binary files differ
diff --git a/exifinterface/src/android/support/media/ExifInterface.java b/exifinterface/src/android/support/media/ExifInterface.java
index c4d602d..ec59c63 100644
--- a/exifinterface/src/android/support/media/ExifInterface.java
+++ b/exifinterface/src/android/support/media/ExifInterface.java
@@ -50,7 +50,6 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
-import java.util.Set;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -1185,14 +1184,19 @@
new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, 514, IFD_FORMAT_ULONG);
// Mappings from tag number to tag name and each item represents one IFD tag group.
- private static final HashMap[] sExifTagMapsForReading = new HashMap[EXIF_TAGS.length];
+ @SuppressWarnings("unchecked")
+ private static final HashMap<Integer, ExifTag>[] sExifTagMapsForReading =
+ new HashMap[EXIF_TAGS.length];
// Mappings from tag name to tag number and each item represents one IFD tag group.
- private static final HashMap[] sExifTagMapsForWriting = new HashMap[EXIF_TAGS.length];
+ @SuppressWarnings("unchecked")
+ private static final HashMap<String, ExifTag>[] sExifTagMapsForWriting =
+ new HashMap[EXIF_TAGS.length];
private static final HashSet<String> sTagSetForCompatibility = new HashSet<>(Arrays.asList(
TAG_F_NUMBER, TAG_DIGITAL_ZOOM_RATIO, TAG_EXPOSURE_TIME, TAG_SUBJECT_DISTANCE,
TAG_GPS_TIMESTAMP));
// Mappings from tag number to IFD type for pointer tags.
- private static final HashMap sExifPointerTagMap = new HashMap();
+ @SuppressWarnings("unchecked")
+ private static final HashMap<Integer, Integer> sExifPointerTagMap = new HashMap();
// See JPEG File Interchange Format Version 1.02.
// The following values are defined for handling JPEG streams. In this implementation, we are
@@ -1245,8 +1249,8 @@
// Build up the hash tables to look up Exif tags for reading Exif tags.
for (int ifdType = 0; ifdType < EXIF_TAGS.length; ++ifdType) {
- sExifTagMapsForReading[ifdType] = new HashMap();
- sExifTagMapsForWriting[ifdType] = new HashMap();
+ sExifTagMapsForReading[ifdType] = new HashMap<>();
+ sExifTagMapsForWriting[ifdType] = new HashMap<>();
for (ExifTag tag : EXIF_TAGS[ifdType]) {
sExifTagMapsForReading[ifdType].put(tag.number, tag);
sExifTagMapsForWriting[ifdType].put(tag.name, tag);
@@ -1265,7 +1269,8 @@
private final String mFilename;
private final AssetManager.AssetInputStream mAssetInputStream;
private int mMimeType;
- private final HashMap[] mAttributes = new HashMap[EXIF_TAGS.length];
+ @SuppressWarnings("unchecked")
+ private final HashMap<String, ExifAttribute>[] mAttributes = new HashMap[EXIF_TAGS.length];
private ByteOrder mExifByteOrder = ByteOrder.BIG_ENDIAN;
private boolean mHasThumbnail;
// The following values used for indicating a thumbnail position.
@@ -1333,9 +1338,9 @@
// Retrieves all tag groups. The value from primary image tag group has a higher priority
// than the value from the thumbnail tag group if there are more than one candidates.
for (int i = 0; i < EXIF_TAGS.length; ++i) {
- Object value = mAttributes[i].get(tag);
+ ExifAttribute value = mAttributes[i].get(tag);
if (value != null) {
- return (ExifAttribute) value;
+ return value;
}
}
return null;
@@ -1453,13 +1458,12 @@
if (i == IFD_TYPE_THUMBNAIL && !mHasThumbnail) {
continue;
}
- final Object obj = sExifTagMapsForWriting[i].get(tag);
- if (obj != null) {
+ final ExifTag exifTag = sExifTagMapsForWriting[i].get(tag);
+ if (exifTag != null) {
if (value == null) {
mAttributes[i].remove(tag);
continue;
}
- final ExifTag exifTag = (ExifTag) obj;
Pair<Integer, Integer> guess = guessDataFormat(value);
int dataFormat;
if (exifTag.primaryFormat == guess.first || exifTag.primaryFormat == guess.second) {
@@ -1600,7 +1604,7 @@
try {
// Initialize mAttributes.
for (int i = 0; i < EXIF_TAGS.length; ++i) {
- mAttributes[i] = new HashMap();
+ mAttributes[i] = new HashMap<>();
}
// Check file type
@@ -1667,8 +1671,8 @@
private void printAttributes() {
for (int i = 0; i < mAttributes.length; ++i) {
Log.d(TAG, "The size of tag group[" + i + "]: " + mAttributes[i].size());
- for (Map.Entry entry : (Set<Map.Entry>) mAttributes[i].entrySet()) {
- final ExifAttribute tagValue = (ExifAttribute) entry.getValue();
+ for (Map.Entry<String, ExifAttribute> entry : mAttributes[i].entrySet()) {
+ final ExifAttribute tagValue = entry.getValue();
Log.d(TAG, "tagName: " + entry.getKey() + ", tagType: " + tagValue.toString()
+ ", tagValue: '" + tagValue.getStringValue(mExifByteOrder) + "'");
}
@@ -2076,7 +2080,7 @@
* http://fileformats.archiveteam.org/wiki/Fujifilm_RAF
*/
private boolean isRafFormat(byte[] signatureCheckBytes) throws IOException {
- byte[] rafSignatureBytes = RAF_SIGNATURE.getBytes();
+ byte[] rafSignatureBytes = RAF_SIGNATURE.getBytes(Charset.defaultCharset());
for (int i = 0; i < rafSignatureBytes.length; i++) {
if (signatureCheckBytes[i] != rafSignatureBytes[i]) {
return false;
@@ -2734,11 +2738,11 @@
Log.d(TAG, "seek to data offset: " + offset);
}
if (mMimeType == IMAGE_TYPE_ORF) {
- if (tag.name == TAG_MAKER_NOTE) {
+ if (TAG_MAKER_NOTE.equals(tag.name)) {
// Save offset value for reading thumbnail
mOrfMakerNoteOffset = offset;
} else if (ifdType == IFD_TYPE_ORF_MAKER_NOTE
- && tag.name == TAG_ORF_THUMBNAIL_IMAGE) {
+ && TAG_ORF_THUMBNAIL_IMAGE.equals(tag.name)) {
// Retrieve & update values for thumbnail offset and length values for ORF
mOrfThumbnailOffset = offset;
mOrfThumbnailLength = numberOfComponents;
@@ -2757,7 +2761,7 @@
jpegInterchangeFormatLengthAttribute);
}
} else if (mMimeType == IMAGE_TYPE_RW2) {
- if (tag.name == TAG_RW2_JPG_FROM_RAW) {
+ if (TAG_RW2_JPG_FROM_RAW.equals(tag.name)) {
mRw2JpgFromRawOffset = offset;
}
}
@@ -2772,7 +2776,7 @@
}
// Recursively parse IFD when a IFD pointer tag appears.
- Object nextIfdType = sExifPointerTagMap.get(tagNumber);
+ Integer nextIfdType = sExifPointerTagMap.get(tagNumber);
if (DEBUG) {
Log.d(TAG, "nextIfdType: " + nextIfdType + " byteCount: " + byteCount);
}
@@ -2808,7 +2812,7 @@
}
if (offset > 0L && offset < dataInputStream.mLength) {
dataInputStream.seek(offset);
- readImageFileDirectory(dataInputStream, (int) nextIfdType);
+ readImageFileDirectory(dataInputStream, nextIfdType);
} else {
Log.w(TAG, "Skip jump into the IFD since its offset is invalid: " + offset);
}
@@ -2825,16 +2829,16 @@
// DNG files have a DNG Version tag specifying the version of specifications that the
// image file is following.
// See http://fileformats.archiveteam.org/wiki/DNG
- if (tag.name == TAG_DNG_VERSION) {
+ if (TAG_DNG_VERSION.equals(tag.name)) {
mMimeType = IMAGE_TYPE_DNG;
}
// PEF files have a Make or Model tag that begins with "PENTAX" or a compression tag
// that is 65535.
// See http://fileformats.archiveteam.org/wiki/Pentax_PEF
- if (((tag.name == TAG_MAKE || tag.name == TAG_MODEL)
+ if (((TAG_MAKE.equals(tag.name) || TAG_MODEL.equals(tag.name))
&& attribute.getStringValue(mExifByteOrder).contains(PEF_SIGNATURE))
- || (tag.name == TAG_COMPRESSION
+ || (TAG_COMPRESSION.equals(tag.name)
&& attribute.getIntValue(mExifByteOrder) == 65535)) {
mMimeType = IMAGE_TYPE_PEF;
}
@@ -3098,7 +3102,7 @@
if (mAttributes[IFD_TYPE_THUMBNAIL].isEmpty()) {
if (isThumbnail(mAttributes[IFD_TYPE_PREVIEW])) {
mAttributes[IFD_TYPE_THUMBNAIL] = mAttributes[IFD_TYPE_PREVIEW];
- mAttributes[IFD_TYPE_PREVIEW] = new HashMap();
+ mAttributes[IFD_TYPE_PREVIEW] = new HashMap<>();
}
}
@@ -3235,8 +3239,8 @@
// value which has a bigger size than 4 bytes.
for (int i = 0; i < EXIF_TAGS.length; ++i) {
int sum = 0;
- for (Map.Entry entry : (Set<Map.Entry>) mAttributes[i].entrySet()) {
- final ExifAttribute exifAttribute = (ExifAttribute) entry.getValue();
+ for (Map.Entry<String, ExifAttribute> entry : mAttributes[i].entrySet()) {
+ final ExifAttribute exifAttribute = entry.getValue();
final int size = exifAttribute.size();
if (size > 4) {
sum += size;
@@ -3303,12 +3307,11 @@
// Write entry info
int dataOffset = ifdOffsets[ifdType] + 2 + mAttributes[ifdType].size() * 12 + 4;
- for (Map.Entry entry : (Set<Map.Entry>) mAttributes[ifdType].entrySet()) {
+ for (Map.Entry<String, ExifAttribute> entry : mAttributes[ifdType].entrySet()) {
// Convert tag name to tag number.
- final ExifTag tag =
- (ExifTag) sExifTagMapsForWriting[ifdType].get(entry.getKey());
+ final ExifTag tag = sExifTagMapsForWriting[ifdType].get(entry.getKey());
final int tagNumber = tag.number;
- final ExifAttribute attribute = (ExifAttribute) entry.getValue();
+ final ExifAttribute attribute = entry.getValue();
final int size = attribute.size();
dataOutputStream.writeUnsignedShort(tagNumber);
@@ -3338,8 +3341,8 @@
}
// Write values of data field exceeding 4 bytes after the next offset.
- for (Map.Entry entry : (Set<Map.Entry>) mAttributes[ifdType].entrySet()) {
- ExifAttribute attribute = (ExifAttribute) entry.getValue();
+ for (Map.Entry<String, ExifAttribute> entry : mAttributes[ifdType].entrySet()) {
+ ExifAttribute attribute = entry.getValue();
if (attribute.bytes.length > 4) {
dataOutputStream.write(attribute.bytes, 0, attribute.bytes.length);
@@ -3378,12 +3381,12 @@
for (int i = 1; i < entryValues.length; ++i) {
final Pair<Integer, Integer> guessDataFormat = guessDataFormat(entryValues[i]);
int first = -1, second = -1;
- if (guessDataFormat.first == dataFormat.first
- || guessDataFormat.second == dataFormat.first) {
+ if (guessDataFormat.first.equals(dataFormat.first)
+ || guessDataFormat.second.equals(dataFormat.first)) {
first = dataFormat.first;
}
- if (dataFormat.second != -1 && (guessDataFormat.first == dataFormat.second
- || guessDataFormat.second == dataFormat.second)) {
+ if (dataFormat.second != -1 && (guessDataFormat.first.equals(dataFormat.second)
+ || guessDataFormat.second.equals(dataFormat.second))) {
second = dataFormat.second;
}
if (first == -1 && second == -1) {
@@ -3448,13 +3451,11 @@
private static final ByteOrder BIG_ENDIAN = ByteOrder.BIG_ENDIAN;
private DataInputStream mDataInputStream;
- private InputStream mInputStream;
private ByteOrder mByteOrder = ByteOrder.BIG_ENDIAN;
private final int mLength;
private int mPosition;
public ByteOrderedDataInputStream(InputStream in) throws IOException {
- mInputStream = in;
mDataInputStream = new DataInputStream(in);
mLength = mDataInputStream.available();
mPosition = 0;
@@ -3499,6 +3500,13 @@
}
@Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ int bytesRead = mDataInputStream.read(b, off, len);
+ mPosition += bytesRead;
+ return bytesRead;
+ }
+
+ @Override
public int readUnsignedByte() throws IOException {
++mPosition;
return mDataInputStream.readUnsignedByte();
@@ -3775,7 +3783,7 @@
if (firstImageLengthValue < secondImageLengthValue &&
firstImageWidthValue < secondImageWidthValue) {
- HashMap tempMap = mAttributes[firstIfdType];
+ HashMap<String, ExifAttribute> tempMap = mAttributes[firstIfdType];
mAttributes[firstIfdType] = mAttributes[secondIfdType];
mAttributes[secondIfdType] = tempMap;
}
diff --git a/fragment/java/android/support/v4/app/FragmentHostCallback.java b/fragment/java/android/support/v4/app/FragmentHostCallback.java
index fa51ccd..7dc9f59 100644
--- a/fragment/java/android/support/v4/app/FragmentHostCallback.java
+++ b/fragment/java/android/support/v4/app/FragmentHostCallback.java
@@ -308,6 +308,8 @@
if (lm == null && create) {
lm = new LoaderManagerImpl(who, this, started);
mAllLoaderManagers.put(who, lm);
+ } else if (started && lm != null && !lm.mStarted) {
+ lm.doStart();
}
return lm;
}
diff --git a/fragment/java/android/support/v4/app/FragmentManager.java b/fragment/java/android/support/v4/app/FragmentManager.java
index 0d311c0..8302203 100644
--- a/fragment/java/android/support/v4/app/FragmentManager.java
+++ b/fragment/java/android/support/v4/app/FragmentManager.java
@@ -3160,7 +3160,7 @@
if (mLifecycleCallbacks == null) {
mLifecycleCallbacks = new CopyOnWriteArrayList<>();
}
- mLifecycleCallbacks.add(new Pair(cb, recursive));
+ mLifecycleCallbacks.add(new Pair<>(cb, recursive));
}
@Override
diff --git a/fragment/java/android/support/v4/app/LoaderManager.java b/fragment/java/android/support/v4/app/LoaderManager.java
index 72718ae..521b218 100644
--- a/fragment/java/android/support/v4/app/LoaderManager.java
+++ b/fragment/java/android/support/v4/app/LoaderManager.java
@@ -839,6 +839,7 @@
mInactiveLoaders.valueAt(i).destroy();
}
mInactiveLoaders.clear();
+ mHost = null;
}
@Override
diff --git a/fragment/tests/AndroidManifest.xml b/fragment/tests/AndroidManifest.xml
index d983969..fb45ecf 100644
--- a/fragment/tests/AndroidManifest.xml
+++ b/fragment/tests/AndroidManifest.xml
@@ -36,6 +36,8 @@
<activity android:name="android.support.v4.app.test.EmptyFragmentTestActivity" />
<activity android:name="android.support.v4.app.test.FragmentResultActivity" />
+
+ <activity android:name="android.support.v4.app.test.LoaderActivity" />
</application>
</manifest>
diff --git a/fragment/tests/java/android/support/v4/app/FragmentTestUtil.java b/fragment/tests/java/android/support/v4/app/FragmentTestUtil.java
index a37b82e..7c7ea39 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentTestUtil.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentTestUtil.java
@@ -19,6 +19,7 @@
import android.app.Activity;
import android.app.Instrumentation;
+import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Parcelable;
@@ -30,6 +31,9 @@
import android.view.ViewGroup;
import android.view.animation.Animation;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
public class FragmentTestUtil {
private static final Runnable DO_NOTHING = new Runnable() {
@Override
@@ -64,14 +68,18 @@
}
public static boolean executePendingTransactions(
- final ActivityTestRule<FragmentTestActivity> rule) {
- Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ final ActivityTestRule<? extends FragmentActivity> rule) {
+ FragmentManager fragmentManager = rule.getActivity().getSupportFragmentManager();
+ return executePendingTransactions(rule, fragmentManager);
+ }
+
+ public static boolean executePendingTransactions(
+ final ActivityTestRule<? extends Activity> rule, final FragmentManager fm) {
final boolean[] ret = new boolean[1];
- instrumentation.runOnMainSync(new Runnable() {
+ runOnUiThreadRethrow(rule, new Runnable() {
@Override
public void run() {
- ret[0] =
- rule.getActivity().getSupportFragmentManager().executePendingTransactions();
+ ret[0] = fm.executePendingTransactions();
}
});
return ret[0];
@@ -211,4 +219,27 @@
} while (!hasEnded[0] && SystemClock.uptimeMillis() < endTime);
return hasEnded[0];
}
+
+ /**
+ * Allocates until a garbage collection occurs.
+ */
+ public static void forceGC() {
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
+ // The following works on O+
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().runFinalization();
+ } else {
+ // The following works on older versions
+ for (int i = 0; i < 2; i++) {
+ // Use a random index in the list to detect the garbage collection each time because
+ // .get() may accidentally trigger a strong reference during collection.
+ ArrayList<WeakReference<byte[]>> leak = new ArrayList<>();
+ do {
+ WeakReference<byte[]> arr = new WeakReference<byte[]>(new byte[100]);
+ leak.add(arr);
+ } while (leak.get((int) (Math.random() * leak.size())).get() != null);
+ }
+ }
+ }
}
diff --git a/fragment/tests/java/android/support/v4/app/LoaderTest.java b/fragment/tests/java/android/support/v4/app/LoaderTest.java
new file mode 100644
index 0000000..fde9d63
--- /dev/null
+++ b/fragment/tests/java/android/support/v4/app/LoaderTest.java
@@ -0,0 +1,281 @@
+/*
+ * 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.v4.app;
+
+import static junit.framework.Assert.assertNull;
+import static junit.framework.TestCase.assertFalse;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.support.annotation.Nullable;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v4.app.test.LoaderActivity;
+import android.support.v4.content.AsyncTaskLoader;
+import android.support.v4.content.Loader;
+
+import junit.framework.Assert;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.ref.WeakReference;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class LoaderTest {
+ private static final int DELAY_LOADER = 10;
+
+ @Rule
+ public ActivityTestRule<LoaderActivity> mActivityRule =
+ new ActivityTestRule(LoaderActivity.class);
+
+ @After
+ public void clearActivity() {
+ LoaderActivity.clearState();
+ }
+
+ /**
+ * Test to ensure that there is no Activity leak due to Loader
+ */
+ @Test
+ public void testLeak() throws Throwable {
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ Intent intent = new Intent(mActivityRule.getActivity(), LoaderActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ LoaderActivity.sResumed = new CountDownLatch(1);
+ instrumentation.startActivitySync(intent);
+ assertTrue(LoaderActivity.sResumed.await(1, TimeUnit.SECONDS));
+
+ LoaderFragment fragment = new LoaderFragment();
+ FragmentManager fm = LoaderActivity.sActivity.getSupportFragmentManager();
+
+ fm.beginTransaction()
+ .add(fragment, "1")
+ .commit();
+
+ FragmentTestUtil.executePendingTransactions(mActivityRule, fm);
+
+ fm.beginTransaction()
+ .remove(fragment)
+ .addToBackStack(null)
+ .commit();
+
+ FragmentTestUtil.executePendingTransactions(mActivityRule, fm);
+
+ WeakReference<LoaderActivity> weakActivity = new WeakReference(LoaderActivity.sActivity);
+
+ if (!switchOrientation()) {
+ return; // can't switch orientation for square screens
+ }
+
+ // Wait for everything to settle. We have to make sure that the old Activity
+ // is ready to be collected.
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ FragmentTestUtil.waitForExecution(mActivityRule);
+
+ // Force a garbage collection.
+ FragmentTestUtil.forceGC();
+ assertNull(weakActivity.get());
+ }
+
+ /**
+ * When a LoaderManager is reused, it should notify in onResume
+ */
+ @Test
+ public void startWhenReused() throws Throwable {
+ LoaderActivity activity = mActivityRule.getActivity();
+
+ assertEquals("Loaded!", activity.textView.getText().toString());
+
+ if (!switchOrientation()) {
+ return; // can't switch orientation for square screens
+ }
+
+ // After orientation change, the text should still be loaded properly
+ activity = LoaderActivity.sActivity;
+ assertEquals("Loaded!", activity.textView.getText().toString());
+ }
+
+ /**
+ * When a change is interrupted with stop, the data in the LoaderManager remains stale.
+ */
+ //@Test
+ public void noStaleData() throws Throwable {
+ final LoaderActivity activity = mActivityRule.getActivity();
+ final String[] value = new String[] { "First Value" };
+
+ final CountDownLatch[] loadedLatch = new CountDownLatch[] { new CountDownLatch(1) };
+ final Loader<String>[] loaders = new Loader[1];
+ mActivityRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ final Loader<String> loader =
+ activity.getSupportLoaderManager().initLoader(DELAY_LOADER, null,
+ new LoaderManager.LoaderCallbacks<String>() {
+ @Override
+ public Loader<String> onCreateLoader(int id, Bundle args) {
+ return new AsyncTaskLoader<String>(activity) {
+ @Override
+ protected void onStopLoading() {
+ cancelLoad();
+ }
+
+ @Override
+ public String loadInBackground() {
+ SystemClock.sleep(50);
+ return value[0];
+ }
+
+ @Override
+ protected void onStartLoading() {
+ if (takeContentChanged()) {
+ forceLoad();
+ }
+ super.onStartLoading();
+ }
+ };
+ }
+
+ @Override
+ public void onLoadFinished(Loader<String> loader, String data) {
+ activity.textViewB.setText(data);
+ loadedLatch[0].countDown();
+ }
+
+ @Override
+ public void onLoaderReset(Loader<String> loader) {
+ }
+ });
+ loader.forceLoad();
+ loaders[0] = loader;
+ }
+ });
+
+ assertTrue(loadedLatch[0].await(1, TimeUnit.SECONDS));
+ assertEquals("First Value", activity.textViewB.getText().toString());
+
+ loadedLatch[0] = new CountDownLatch(1);
+ mActivityRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ value[0] = "Second Value";
+ loaders[0].onContentChanged();
+ loaders[0].stopLoading();
+ }
+ });
+
+ // Since the loader was stopped (and canceled), it shouldn't notify the change
+ assertFalse(loadedLatch[0].await(300, TimeUnit.MILLISECONDS));
+
+ mActivityRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ loaders[0].startLoading();
+ }
+ });
+
+ // Since the loader was stopped (and canceled), it shouldn't notify the change
+ assertTrue(loadedLatch[0].await(1, TimeUnit.SECONDS));
+ assertEquals("Second Value", activity.textViewB.getText().toString());
+ }
+
+ private boolean switchOrientation() throws InterruptedException {
+ LoaderActivity activity = LoaderActivity.sActivity;
+
+ int currentOrientation = activity.getResources().getConfiguration().orientation;
+
+ int nextOrientation;
+ int expectedOrientation;
+ if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
+ nextOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+ expectedOrientation = Configuration.ORIENTATION_PORTRAIT;
+ } else if (currentOrientation == Configuration.ORIENTATION_PORTRAIT) {
+ nextOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+ expectedOrientation = Configuration.ORIENTATION_LANDSCAPE;
+ } else {
+ return false; // Don't know what to do with square or unknown orientations
+ }
+
+ // Now switch the orientation
+ LoaderActivity.sResumed = new CountDownLatch(1);
+ LoaderActivity.sDestroyed = new CountDownLatch(1);
+
+ activity.setRequestedOrientation(nextOrientation);
+ assertTrue(LoaderActivity.sResumed.await(1, TimeUnit.SECONDS));
+ assertTrue(LoaderActivity.sDestroyed.await(1, TimeUnit.SECONDS));
+
+ int switchedOrientation =
+ LoaderActivity.sActivity.getResources().getConfiguration().orientation;
+ Assert.assertEquals(expectedOrientation, switchedOrientation);
+ return true;
+ }
+
+
+ public static class LoaderFragment extends Fragment {
+ private static final int LOADER_ID = 1;
+ private final LoaderManager.LoaderCallbacks<Boolean> mLoaderCallbacks =
+ new LoaderManager.LoaderCallbacks<Boolean>() {
+ @Override
+ public Loader<Boolean> onCreateLoader(int id, Bundle args) {
+ return new DummyLoader(getContext());
+ }
+
+ @Override
+ public void onLoadFinished(Loader<Boolean> loader, Boolean data) {
+
+ }
+
+ @Override
+ public void onLoaderReset(Loader<Boolean> loader) {
+
+ }
+ };
+
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ getLoaderManager().initLoader(LOADER_ID, null, mLoaderCallbacks);
+ }
+ }
+
+ static class DummyLoader extends Loader<Boolean> {
+ DummyLoader(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected void onStartLoading() {
+ deliverResult(true);
+ }
+ }
+}
diff --git a/fragment/tests/java/android/support/v4/app/test/LoaderActivity.java b/fragment/tests/java/android/support/v4/app/test/LoaderActivity.java
new file mode 100644
index 0000000..77a71f7
--- /dev/null
+++ b/fragment/tests/java/android/support/v4/app/test/LoaderActivity.java
@@ -0,0 +1,108 @@
+/*
+ * 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.v4.app.test;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.fragment.test.R;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.AsyncTaskLoader;
+import android.support.v4.content.Loader;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import java.util.concurrent.CountDownLatch;
+
+public class LoaderActivity extends FragmentActivity {
+ // These must be cleared after each test using clearState()
+ public static LoaderActivity sActivity;
+ public static CountDownLatch sResumed;
+ public static CountDownLatch sDestroyed;
+
+ public TextView textView;
+ public TextView textViewB;
+
+ public static void clearState() {
+ sActivity = null;
+ sResumed = null;
+ sDestroyed = null;
+ }
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ sActivity = this;
+
+ setContentView(R.layout.fragment_a);
+ textView = (TextView) findViewById(R.id.textA);
+ ViewGroup container = (ViewGroup) textView.getParent();
+ textViewB = new TextView(this);
+ textViewB.setId(R.id.textB);
+ container.addView(textViewB);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ getSupportLoaderManager().initLoader(0, null, new TextLoaderCallback());
+ if (sResumed != null) {
+ sResumed.countDown();
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if (sDestroyed != null) {
+ sDestroyed.countDown();
+ }
+ }
+
+ class TextLoaderCallback implements LoaderManager.LoaderCallbacks<String> {
+ @Override
+ public Loader<String> onCreateLoader(int id, Bundle args) {
+ return new TextLoader(LoaderActivity.this);
+ }
+
+ @Override
+ public void onLoadFinished(Loader<String> loader, String data) {
+ textView.setText(data);
+ }
+
+ @Override
+ public void onLoaderReset(Loader<String> loader) {
+ }
+ }
+
+ static class TextLoader extends AsyncTaskLoader<String> {
+ TextLoader(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected void onStartLoading() {
+ forceLoad();
+ }
+
+ @Override
+ public String loadInBackground() {
+ return "Loaded!";
+ }
+ }
+}
diff --git a/gradlew b/gradlew
index 98b9f82..4c2ef38 100755
--- a/gradlew
+++ b/gradlew
@@ -62,7 +62,7 @@
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Pick the correct fullsdk for this OS.
-if [ darwin ]; then
+if [ $darwin == "true" ]; then
plat="darwin"
else
plat="linux"
diff --git a/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCommon.java b/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCommon.java
index 12b0383..c8c6fa1 100644
--- a/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCommon.java
+++ b/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCommon.java
@@ -21,7 +21,6 @@
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
-import android.os.Build;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v4.graphics.drawable.TintAwareDrawable;
import android.util.AttributeSet;
diff --git a/instantvideo/tests/src/android/support/media/instantvideo/preload/InstantVideoPreloadManagerTest.java b/instantvideo/tests/src/android/support/media/instantvideo/preload/InstantVideoPreloadManagerTest.java
index d50ece8..7b59d1d 100644
--- a/instantvideo/tests/src/android/support/media/instantvideo/preload/InstantVideoPreloadManagerTest.java
+++ b/instantvideo/tests/src/android/support/media/instantvideo/preload/InstantVideoPreloadManagerTest.java
@@ -15,6 +15,9 @@
*/
package android.support.media.instantvideo.preload;
+import static android.support.test.InstrumentationRegistry.getContext;
+
+import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.when;
@@ -22,8 +25,12 @@
import android.support.media.instantvideo.preload.InstantVideoPreloadManager.VideoPreloader;
import android.support.media.instantvideo.preload.InstantVideoPreloadManager.VideoPreloaderFactory;
import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
+import android.support.test.runner.AndroidJUnit4;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -31,43 +38,47 @@
* Tests for IntentVideoPreloadManager.
*/
@SmallTest
-public class InstantVideoPreloadManagerTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class InstantVideoPreloadManagerTest {
private static final Uri PRELOAD_VIDEO_URI_1 = Uri.parse("http://test/test1.mp4");
private static final Uri PRELOAD_VIDEO_URI_2 = Uri.parse("http://test/test2.mp4");
private InstantVideoPreloadManager mPreloadManager;
- @Mock private VideoPreloaderFactory mMockVideoPreloaderFactory;
- @Mock private VideoPreloader mMockVideoPreloader;
+ @Mock
+ private VideoPreloaderFactory mMockVideoPreloaderFactory;
+ @Mock
+ private VideoPreloader mMockVideoPreloader;
- @Override
- public void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() {
MockitoAnnotations.initMocks(this);
when(mMockVideoPreloaderFactory.createVideoPreloader(any(Uri.class)))
.thenReturn(mMockVideoPreloader);
mPreloadManager = new InstantVideoPreloadManager(getContext(), mMockVideoPreloaderFactory);
}
- @Override
- public void tearDown() throws Exception {
+ @After
+ public void tearDown() {
mPreloadManager.clearCache();
- super.tearDown();
}
- public void testPreload() {
+ @Test
+ public void preload() {
mPreloadManager.preload(PRELOAD_VIDEO_URI_1);
assertCacheSize(1);
mPreloadManager.preload(PRELOAD_VIDEO_URI_2);
assertCacheSize(2);
}
- public void testPreload_duplicate() {
+ @Test
+ public void preload_duplicate() {
mPreloadManager.preload(PRELOAD_VIDEO_URI_1);
mPreloadManager.preload(PRELOAD_VIDEO_URI_1);
assertCacheSize(1);
}
- public void testMaxPreloadVideoCount() {
+ @Test
+ public void setMaxPreloadVideoCount() {
mPreloadManager.setMaxPreloadVideoCount(1);
mPreloadManager.preload(PRELOAD_VIDEO_URI_1);
assertCacheSize(1);
@@ -75,7 +86,8 @@
assertCacheSize(1);
}
- public void testClearCache() {
+ @Test
+ public void clearCache() {
mPreloadManager.preload(PRELOAD_VIDEO_URI_1);
mPreloadManager.preload(PRELOAD_VIDEO_URI_2);
mPreloadManager.clearCache();
diff --git a/media-compat/api26/android/support/v4/media/session/MediaControllerCompatApi26.java b/media-compat/api26/android/support/v4/media/session/MediaControllerCompatApi26.java
index 33829e7..34ed628 100644
--- a/media-compat/api26/android/support/v4/media/session/MediaControllerCompatApi26.java
+++ b/media-compat/api26/android/support/v4/media/session/MediaControllerCompatApi26.java
@@ -16,8 +16,9 @@
package android.support.v4.media.session;
-import android.support.annotation.RequiresApi;
+import android.media.MediaDescription;
import android.media.session.MediaController;
+import android.support.annotation.RequiresApi;
@RequiresApi(26)
class MediaControllerCompatApi26 {
@@ -33,6 +34,22 @@
return ((MediaController) controllerObj).isShuffleModeEnabled();
}
+ public static void addQueueItem(Object controllerObj, Object descriptionObj) {
+ ((MediaController) controllerObj).addQueueItem((MediaDescription) descriptionObj);
+ }
+
+ public static void addQueueItem(Object controllerObj, Object descriptionObj, int index) {
+ ((MediaController) controllerObj).addQueueItem((MediaDescription) descriptionObj, index);
+ }
+
+ public static void removeQueueItem(Object controllerObj, Object descriptionObj) {
+ ((MediaController) controllerObj).removeQueueItem((MediaDescription) descriptionObj);
+ }
+
+ public static void removeQueueItemAt(Object controllerObj, int index) {
+ ((MediaController) controllerObj).removeQueueItemAt(index);
+ }
+
public static class TransportControls extends MediaControllerCompatApi23.TransportControls {
public static void setRepeatMode(Object controlsObj, int repeatMode) {
((MediaController.TransportControls) controlsObj).setRepeatMode(repeatMode);
diff --git a/media-compat/api26/android/support/v4/media/session/MediaSessionCompatApi26.java b/media-compat/api26/android/support/v4/media/session/MediaSessionCompatApi26.java
index 6d7ba4f..8289702 100644
--- a/media-compat/api26/android/support/v4/media/session/MediaSessionCompatApi26.java
+++ b/media-compat/api26/android/support/v4/media/session/MediaSessionCompatApi26.java
@@ -16,6 +16,7 @@
package android.support.v4.media.session;
+import android.media.MediaDescription;
import android.media.session.MediaSession;
import android.support.annotation.RequiresApi;
@@ -37,6 +38,10 @@
public interface Callback extends MediaSessionCompatApi24.Callback {
void onSetRepeatMode(int repeatMode);
void onSetShuffleModeEnabled(boolean enabled);
+ void onAddQueueItem(Object descriptionObject);
+ void onAddQueueItem(Object descriptionObject, int index);
+ void onRemoveQueueItem(Object descriptionObject);
+ void onRemoveQueueItemAt(int index);
}
static class CallbackProxy<T extends Callback>
@@ -54,5 +59,25 @@
public void onSetShuffleModeEnabled(boolean enabled) {
mCallback.onSetShuffleModeEnabled(enabled);
}
+
+ @Override
+ public void onAddQueueItem(MediaDescription description) {
+ mCallback.onAddQueueItem(description);
+ }
+
+ @Override
+ public void onAddQueueItem(MediaDescription description, int index) {
+ mCallback.onAddQueueItem(description, index);
+ }
+
+ @Override
+ public void onRemoveQueueItem(MediaDescription description) {
+ mCallback.onRemoveQueueItem(description);
+ }
+
+ @Override
+ public void onRemoveQueueItemAt(int index) {
+ mCallback.onRemoveQueueItemAt(index);
+ }
}
}
diff --git a/media-compat/build.gradle b/media-compat/build.gradle
index 6379429..355ee1a 100644
--- a/media-compat/build.gradle
+++ b/media-compat/build.gradle
@@ -14,6 +14,7 @@
androidTestCompile libs.mockito_core
androidTestCompile libs.dexmaker
androidTestCompile libs.dexmaker_mockito
+ androidTestCompile project(':support-testutils')
}
android {
diff --git a/media-compat/java/android/support/v4/media/MediaBrowserCompat.java b/media-compat/java/android/support/v4/media/MediaBrowserCompat.java
index 24ec335..be9c1de 100644
--- a/media-compat/java/android/support/v4/media/MediaBrowserCompat.java
+++ b/media-compat/java/android/support/v4/media/MediaBrowserCompat.java
@@ -38,6 +38,7 @@
import static android.support.v4.media.MediaBrowserProtocol.DATA_SEARCH_QUERY;
import static android.support.v4.media.MediaBrowserProtocol.EXTRA_CLIENT_VERSION;
import static android.support.v4.media.MediaBrowserProtocol.EXTRA_MESSENGER_BINDER;
+import static android.support.v4.media.MediaBrowserProtocol.EXTRA_SESSION_BINDER;
import static android.support.v4.media.MediaBrowserProtocol.SERVICE_MSG_ON_CONNECT;
import static android.support.v4.media.MediaBrowserProtocol.SERVICE_MSG_ON_CONNECT_FAILED;
import static android.support.v4.media.MediaBrowserProtocol.SERVICE_MSG_ON_LOAD_CHILDREN;
@@ -63,6 +64,7 @@
import android.support.annotation.RequiresApi;
import android.support.annotation.RestrictTo;
import android.support.v4.app.BundleCompat;
+import android.support.v4.media.session.IMediaSession;
import android.support.v4.media.session.MediaControllerCompat.TransportControls;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.os.BuildCompat;
@@ -340,6 +342,7 @@
* @param extras The bundle of service-specific arguments to send to the media browser service.
* The contents of this bundle may affect the search result.
* @param callback The callback to receive the search result. Must be non-null.
+ * @throws IllegalStateException if the browser is not connected to the media browser service.
*/
public void search(@NonNull final String query, final Bundle extras,
@NonNull SearchCallback callback) {
@@ -671,7 +674,7 @@
}
private void setSubscription(Subscription subscription) {
- mSubscriptionRef = new WeakReference(subscription);
+ mSubscriptionRef = new WeakReference<>(subscription);
}
private class StubApi21 implements MediaBrowserCompatApi21.SubscriptionCallback {
@@ -808,8 +811,10 @@
public abstract static class SearchCallback {
final Object mSearchCallbackObj;
+ @SuppressLint("NewApi")
public SearchCallback() {
- if (Build.VERSION.SDK_INT >= 26 || BuildCompat.isAtLeastO()) {
+ if (BuildCompat.isAtLeastO()) {
+ //noinspection AndroidLintNewApi
mSearchCallbackObj = MediaBrowserCompatApi26.createSearchCallback(new StubApi26());
} else {
mSearchCallbackObj = null;
@@ -1150,7 +1155,7 @@
try {
mServiceBinderWrapper.getMediaItem(mediaId, receiver, mCallbacksMessenger);
} catch (RemoteException e) {
- Log.i(TAG, "Remote error getting media item.");
+ Log.i(TAG, "Remote error getting media item: " + mediaId);
mHandler.post(new Runnable() {
@Override
public void run() {
@@ -1164,14 +1169,8 @@
public void search(@NonNull final String query, final Bundle extras,
@NonNull final SearchCallback callback) {
if (!isConnected()) {
- Log.i(TAG, "Not connected, unable to search.");
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- callback.onError(query, extras);
- }
- });
- return;
+ throw new IllegalStateException("search() called while not connected"
+ + " (state=" + getStateLabel(mState) + ")");
}
ResultReceiver receiver = new SearchResultReceiver(query, extras, callback, mHandler);
@@ -1465,6 +1464,7 @@
protected ServiceBinderWrapper mServiceBinderWrapper;
protected Messenger mCallbacksMessenger;
+ private MediaSessionCompat.Token mMediaSessionToken;
public MediaBrowserImplApi21(Context context, ComponentName serviceComponent,
ConnectionCallback callback, Bundle rootHints) {
@@ -1526,8 +1526,11 @@
@NonNull
@Override
public MediaSessionCompat.Token getSessionToken() {
- return MediaSessionCompat.Token.fromToken(
- MediaBrowserCompatApi21.getSessionToken(mBrowserObj));
+ if (mMediaSessionToken == null) {
+ mMediaSessionToken = MediaSessionCompat.Token.fromToken(
+ MediaBrowserCompatApi21.getSessionToken(mBrowserObj));
+ }
+ return mMediaSessionToken;
}
@Override
@@ -1660,14 +1663,7 @@
public void search(@NonNull final String query, final Bundle extras,
@NonNull final SearchCallback callback) {
if (!isConnected()) {
- Log.i(TAG, "Not connected, unable to search.");
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- callback.onError(query, extras);
- }
- });
- return;
+ throw new IllegalStateException("search() called while not connected");
}
if (mServiceBinderWrapper == null) {
Log.i(TAG, "The connected service doesn't support search.");
@@ -1712,12 +1708,19 @@
Log.i(TAG, "Remote error registering client messenger." );
}
}
+ IMediaSession sessionToken = (IMediaSession) BundleCompat.getBinder(
+ extras, EXTRA_SESSION_BINDER);
+ if (sessionToken != null) {
+ mMediaSessionToken = MediaSessionCompat.Token.fromToken(
+ MediaBrowserCompatApi21.getSessionToken(mBrowserObj), sessionToken);
+ }
}
@Override
public void onConnectionSuspended() {
mServiceBinderWrapper = null;
mCallbacksMessenger = null;
+ mMediaSessionToken = null;
mHandler.setCallbacksMessenger(null);
}
@@ -1831,8 +1834,8 @@
private final List<Bundle> mOptionsList;
public Subscription() {
- mCallbacks = new ArrayList();
- mOptionsList = new ArrayList();
+ mCallbacks = new ArrayList<>();
+ mOptionsList = new ArrayList<>();
}
public boolean isEmpty() {
diff --git a/media-compat/java/android/support/v4/media/MediaBrowserProtocol.java b/media-compat/java/android/support/v4/media/MediaBrowserProtocol.java
index 2401d09..b90dc05 100644
--- a/media-compat/java/android/support/v4/media/MediaBrowserProtocol.java
+++ b/media-compat/java/android/support/v4/media/MediaBrowserProtocol.java
@@ -35,6 +35,7 @@
public static final String EXTRA_CLIENT_VERSION = "extra_client_version";
public static final String EXTRA_SERVICE_VERSION = "extra_service_version";
public static final String EXTRA_MESSENGER_BINDER = "extra_messenger";
+ public static final String EXTRA_SESSION_BINDER = "extra_session_binder";
/**
* MediaBrowserCompat will check the version of the connected MediaBrowserServiceCompat,
diff --git a/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java b/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
index c94f74c..9ade9cf 100644
--- a/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
+++ b/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
@@ -39,6 +39,7 @@
import static android.support.v4.media.MediaBrowserProtocol.EXTRA_CLIENT_VERSION;
import static android.support.v4.media.MediaBrowserProtocol.EXTRA_MESSENGER_BINDER;
import static android.support.v4.media.MediaBrowserProtocol.EXTRA_SERVICE_VERSION;
+import static android.support.v4.media.MediaBrowserProtocol.EXTRA_SESSION_BINDER;
import static android.support.v4.media.MediaBrowserProtocol.SERVICE_MSG_ON_CONNECT;
import static android.support.v4.media.MediaBrowserProtocol.SERVICE_MSG_ON_CONNECT_FAILED;
import static android.support.v4.media.MediaBrowserProtocol.SERVICE_MSG_ON_LOAD_CHILDREN;
@@ -296,6 +297,8 @@
rootExtras = new Bundle();
rootExtras.putInt(EXTRA_SERVICE_VERSION, SERVICE_VERSION_CURRENT);
BundleCompat.putBinder(rootExtras, EXTRA_MESSENGER_BINDER, mMessenger.getBinder());
+ BundleCompat.putBinder(rootExtras, EXTRA_SESSION_BINDER,
+ (IBinder) mSession.getExtraBinder());
}
BrowserRoot root = MediaBrowserServiceCompat.this.onGetRoot(
clientPackageName, clientUid, rootHints);
@@ -537,7 +540,7 @@
Bundle rootHints;
ServiceCallbacks callbacks;
BrowserRoot root;
- HashMap<String, List<Pair<IBinder, Bundle>>> subscriptions = new HashMap();
+ HashMap<String, List<Pair<IBinder, Bundle>>> subscriptions = new HashMap<>();
ConnectionRecord() {
}
@@ -1351,8 +1354,9 @@
* @see #EXTRA_RECENT
* @see #EXTRA_OFFLINE
* @see #EXTRA_SUGGESTED
- * @deprecated Use {@link MediaBrowserCompat#search(String, Bundle,
- * MediaBrowserCompat.SearchCallback)} instead.
+ * @deprecated The search functionality is now supported by the methods
+ * {@link MediaBrowserCompat#search} and {@link #onSearch}. Use those methods
+ * instead.
*/
@Deprecated
public static final String EXTRA_SUGGESTION_KEYWORDS
diff --git a/media-compat/java/android/support/v4/media/session/IMediaControllerCallback.aidl b/media-compat/java/android/support/v4/media/session/IMediaControllerCallback.aidl
index d1d143d..ac0de3d 100644
--- a/media-compat/java/android/support/v4/media/session/IMediaControllerCallback.aidl
+++ b/media-compat/java/android/support/v4/media/session/IMediaControllerCallback.aidl
@@ -39,4 +39,5 @@
void onVolumeInfoChanged(in ParcelableVolumeInfo info);
void onRepeatModeChanged(int repeatMode);
void onShuffleModeChanged(boolean enabled);
+ void onCaptioningEnabledChanged(boolean enabled);
}
diff --git a/media-compat/java/android/support/v4/media/session/IMediaSession.aidl b/media-compat/java/android/support/v4/media/session/IMediaSession.aidl
index 969b803..39cfbe6 100644
--- a/media-compat/java/android/support/v4/media/session/IMediaSession.aidl
+++ b/media-compat/java/android/support/v4/media/session/IMediaSession.aidl
@@ -34,7 +34,7 @@
* @hide
*/
interface IMediaSession {
- // Next ID: 44
+ // Next ID: 46
void sendCommand(String command, in Bundle args, in MediaSessionCompat.ResultReceiverWrapper cb) = 0;
boolean sendMediaButton(in KeyEvent mediaButton) = 1;
void registerCallbackListener(in IMediaControllerCallback cb) = 2;
@@ -53,6 +53,7 @@
CharSequence getQueueTitle() = 29;
Bundle getExtras() = 30;
int getRatingType() = 31;
+ boolean isCaptioningEnabled() = 44;
int getRepeatMode() = 36;
boolean isShuffleModeEnabled() = 37;
void addQueueItem(in MediaDescriptionCompat description) = 40;
@@ -78,6 +79,7 @@
void rewind() = 22;
void seekTo(long pos) = 23;
void rate(in RatingCompat rating) = 24;
+ void setCaptioningEnabled(boolean enabled) = 45;
void setRepeatMode(int repeatMode) = 38;
void setShuffleModeEnabled(boolean shuffleMode) = 39;
void sendCustomAction(String action, in Bundle args) = 25;
diff --git a/media-compat/java/android/support/v4/media/session/MediaButtonReceiver.java b/media-compat/java/android/support/v4/media/session/MediaButtonReceiver.java
index 1e05889..0cd8ff9 100644
--- a/media-compat/java/android/support/v4/media/session/MediaButtonReceiver.java
+++ b/media-compat/java/android/support/v4/media/session/MediaButtonReceiver.java
@@ -17,13 +17,14 @@
package android.support.v4.media.session;
import android.app.PendingIntent;
-import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.os.RemoteException;
+import android.support.v4.media.MediaBrowserCompat;
import android.support.v4.media.MediaBrowserServiceCompat;
import android.support.v4.media.session.PlaybackStateCompat.MediaKeyAction;
import android.util.Log;
@@ -45,93 +46,111 @@
* </intent-filter>
* </receiver>
* </pre>
- * This class assumes you have a {@link Service} in your app that controls
+ * This class assumes you have a media browser service implementation in your app that controls
* media playback via a {@link MediaSessionCompat} - all {@link Intent}s received by
- * the MediaButtonReceiver will be forwarded to that service.
+ * the MediaButtonReceiver will be forwarded to the {@link MediaSessionCompat}
+ * associated with the token set via {@link MediaBrowserServiceCompat#setSessionToken}.
* <p />
- * First priority is given to a {@link Service}
- * that includes an intent filter that handles {@link Intent#ACTION_MEDIA_BUTTON}:
- * <pre>
- * <service android:name="com.example.android.MediaPlaybackService" >
- * <intent-filter>
- * <action android:name="android.intent.action.MEDIA_BUTTON" />
- * </intent-filter>
- * </service>
- * </pre>
- *
- * If such a {@link Service} is not found, MediaButtonReceiver will attempt to
- * find a media browser service implementation.
- * If neither is available or more than one valid service/media browser service is found, an
+ * If more than one valid media browser service is found, an
* {@link IllegalStateException} will be thrown.
- * <p />
- * Events can then be handled in {@link Service#onStartCommand(Intent, int, int)} by calling
- * {@link MediaButtonReceiver#handleIntent(MediaSessionCompat, Intent)}, passing in
- * your current {@link MediaSessionCompat}:
- * <pre>
- * private MediaSessionCompat mMediaSessionCompat = ...;
- *
- * public int onStartCommand(Intent intent, int flags, int startId) {
- * MediaButtonReceiver.handleIntent(mMediaSessionCompat, intent);
- * return super.onStartCommand(intent, flags, startId);
- * }
- * </pre>
- *
- * This ensures that the correct callbacks to {@link MediaSessionCompat.Callback}
- * will be triggered based on the incoming {@link KeyEvent}.
*/
public class MediaButtonReceiver extends BroadcastReceiver {
private static final String TAG = "MediaButtonReceiver";
@Override
public void onReceive(Context context, Intent intent) {
- Intent queryIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+ if (intent == null
+ || !Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())
+ || !intent.hasExtra(Intent.EXTRA_KEY_EVENT)) {
+ Log.d(TAG, "Ignore unsupported intent: " + intent);
+ return;
+ }
+ Intent queryIntent = new Intent(MediaBrowserServiceCompat.SERVICE_INTERFACE);
queryIntent.setPackage(context.getPackageName());
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfos = pm.queryIntentServices(queryIntent, 0);
if (resolveInfos.isEmpty()) {
- // Fall back to looking for any available media browser service
- queryIntent.setAction(MediaBrowserServiceCompat.SERVICE_INTERFACE);
- resolveInfos = pm.queryIntentServices(queryIntent, 0);
- }
- if (resolveInfos.isEmpty()) {
- throw new IllegalStateException("Could not find any Service that handles " +
- Intent.ACTION_MEDIA_BUTTON + " or a media browser service implementation");
+ throw new IllegalStateException("Could not find any "
+ + "media browser service implementation");
} else if (resolveInfos.size() != 1) {
- throw new IllegalStateException("Expected 1 Service that handles " +
- queryIntent.getAction() + ", found " + resolveInfos.size() );
+ throw new IllegalStateException("Expected 1 media browser service implementation"
+ + ", found " + resolveInfos.size());
}
ResolveInfo resolveInfo = resolveInfos.get(0);
ComponentName componentName = new ComponentName(resolveInfo.serviceInfo.packageName,
resolveInfo.serviceInfo.name);
- intent.setComponent(componentName);
- context.startService(intent);
+ PendingResult pendingResult = goAsync();
+ Context applicationContext = context.getApplicationContext();
+ MediaButtonConnectionCallback connectionCallback =
+ new MediaButtonConnectionCallback(applicationContext, intent, pendingResult);
+ MediaBrowserCompat mediaBrowser = new MediaBrowserCompat(applicationContext,
+ componentName, connectionCallback, null);
+ connectionCallback.setMediaBrowser(mediaBrowser);
+ mediaBrowser.connect();
}
+ private static class MediaButtonConnectionCallback extends
+ MediaBrowserCompat.ConnectionCallback {
+ private final Context mContext;
+ private final Intent mIntent;
+ private final PendingResult mPendingResult;
+
+ private MediaBrowserCompat mMediaBrowser;
+
+ MediaButtonConnectionCallback(Context context, Intent intent, PendingResult pendingResult) {
+ mContext = context;
+ mIntent = intent;
+ mPendingResult = pendingResult;
+ }
+
+ void setMediaBrowser(MediaBrowserCompat mediaBrowser) {
+ mMediaBrowser = mediaBrowser;
+ }
+
+ @Override
+ public void onConnected() {
+ try {
+ MediaControllerCompat mediaController = new MediaControllerCompat(mContext,
+ mMediaBrowser.getSessionToken());
+ KeyEvent ke = mIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+ mediaController.dispatchMediaButtonEvent(ke);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to create a media controller", e);
+ }
+ finish();
+ }
+
+ @Override
+ public void onConnectionSuspended() {
+ finish();
+ }
+
+ @Override
+ public void onConnectionFailed() {
+ finish();
+ }
+
+ private void finish() {
+ mMediaBrowser.disconnect();
+ mPendingResult.finish();
+ }
+ };
+
/**
* Extracts any available {@link KeyEvent} from an {@link Intent#ACTION_MEDIA_BUTTON}
* intent, passing it onto the {@link MediaSessionCompat} using
* {@link MediaControllerCompat#dispatchMediaButtonEvent(KeyEvent)}, which in turn
* will trigger callbacks to the {@link MediaSessionCompat.Callback} registered via
* {@link MediaSessionCompat#setCallback(MediaSessionCompat.Callback)}.
- * <p />
- * The returned {@link KeyEvent} is non-null if any {@link KeyEvent} is found and can
- * be used if any additional processing is needed beyond what is done in the
- * {@link MediaSessionCompat.Callback}. An example of is to prevent redelivery of a
- * {@link KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE} Intent in the case of the Service being
- * restarted (which, by default, will redeliver the last received Intent).
- * <pre>
- * KeyEvent keyEvent = MediaButtonReceiver.handleIntent(mediaSession, intent);
- * if (keyEvent != null && keyEvent.getKeyCode() == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) {
- * Intent emptyIntent = new Intent(intent);
- * emptyIntent.setAction("");
- * startService(emptyIntent);
- * }
- * </pre>
* @param mediaSessionCompat A {@link MediaSessionCompat} that has a
* {@link MediaSessionCompat.Callback} set.
* @param intent The intent to parse.
* @return The extracted {@link KeyEvent} if found, or null.
+ * @deprecated This call is no longer required. MediaButtonReceiver automatically
+ * forwards the {@link KeyEvent} to the {@link MediaSessionCompat} associated with
+ * the token set via {@link MediaBrowserServiceCompat#setSessionToken}.
*/
+ @Deprecated
public static KeyEvent handleIntent(MediaSessionCompat mediaSessionCompat, Intent intent) {
if (mediaSessionCompat == null || intent == null
|| !Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())
diff --git a/media-compat/java/android/support/v4/media/session/MediaControllerCompat.java b/media-compat/java/android/support/v4/media/session/MediaControllerCompat.java
index 3e28274..402df13 100644
--- a/media-compat/java/android/support/v4/media/session/MediaControllerCompat.java
+++ b/media-compat/java/android/support/v4/media/session/MediaControllerCompat.java
@@ -16,6 +16,7 @@
package android.support.v4.media.session;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
@@ -29,7 +30,6 @@
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.support.annotation.RequiresApi;
-import android.support.annotation.VisibleForTesting;
import android.support.v4.app.BundleCompat;
import android.support.v4.app.SupportActivity;
import android.support.v4.media.MediaDescriptionCompat;
@@ -38,6 +38,7 @@
import android.support.v4.media.VolumeProviderCompat;
import android.support.v4.media.session.MediaSessionCompat.QueueItem;
import android.support.v4.media.session.PlaybackStateCompat.CustomAction;
+import android.support.v4.os.BuildCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
@@ -159,13 +160,14 @@
*
* @param session The session to be controlled.
*/
+ @SuppressLint("NewApi")
public MediaControllerCompat(Context context, MediaSessionCompat session) {
if (session == null) {
throw new IllegalArgumentException("session must not be null");
}
mToken = session.getSessionToken();
- if (android.os.Build.VERSION.SDK_INT >= 26) {
+ if (BuildCompat.isAtLeastO()) {
mImpl = new MediaControllerImplApi26(context, session);
} else if (android.os.Build.VERSION.SDK_INT >= 24) {
mImpl = new MediaControllerImplApi24(context, session);
@@ -185,6 +187,7 @@
* @param sessionToken The token of the session to be controlled.
* @throws RemoteException if the session is not accessible.
*/
+ @SuppressLint("NewApi")
public MediaControllerCompat(Context context, MediaSessionCompat.Token sessionToken)
throws RemoteException {
if (sessionToken == null) {
@@ -192,7 +195,7 @@
}
mToken = sessionToken;
- if (android.os.Build.VERSION.SDK_INT >= 26) {
+ if (BuildCompat.isAtLeastO()) {
mImpl = new MediaControllerImplApi26(context, sessionToken);
} else if (android.os.Build.VERSION.SDK_INT >= 24) {
mImpl = new MediaControllerImplApi24(context, sessionToken);
@@ -258,11 +261,14 @@
/**
* Add a queue item from the given {@code description} at the end of the play queue
- * of this session. Not all sessions may support this.
+ * of this session. Not all sessions may support this. To know whether the session supports
+ * this, get the session's flags with {@link #getFlags()} and check that the flag
+ * {@link MediaSessionCompat#FLAG_HANDLES_QUEUE_COMMANDS} is set.
*
* @param description The {@link MediaDescriptionCompat} for creating the
* {@link MediaSessionCompat.QueueItem} to be inserted.
* @throws UnsupportedOperationException If this session doesn't support this.
+ * @see #getFlags()
* @see MediaSessionCompat#FLAG_HANDLES_QUEUE_COMMANDS
*/
public void addQueueItem(MediaDescriptionCompat description) {
@@ -273,13 +279,16 @@
* Add a queue item from the given {@code description} at the specified position
* in the play queue of this session. Shifts the queue item currently at that position
* (if any) and any subsequent queue items to the right (adds one to their indices).
- * Not all sessions may support this.
+ * Not all sessions may support this. To know whether the session supports this,
+ * get the session's flags with {@link #getFlags()} and check that the flag
+ * {@link MediaSessionCompat#FLAG_HANDLES_QUEUE_COMMANDS} is set.
*
* @param description The {@link MediaDescriptionCompat} for creating the
* {@link MediaSessionCompat.QueueItem} to be inserted.
* @param index The index at which the created {@link MediaSessionCompat.QueueItem}
* is to be inserted.
* @throws UnsupportedOperationException If this session doesn't support this.
+ * @see #getFlags()
* @see MediaSessionCompat#FLAG_HANDLES_QUEUE_COMMANDS
*/
public void addQueueItem(MediaDescriptionCompat description, int index) {
@@ -289,11 +298,14 @@
/**
* Remove the first occurrence of the specified {@link MediaSessionCompat.QueueItem}
* with the given {@link MediaDescriptionCompat description} in the play queue of the
- * associated session. Not all sessions may support this.
+ * associated session. Not all sessions may support this. To know whether the session supports
+ * this, get the session's flags with {@link #getFlags()} and check that the flag
+ * {@link MediaSessionCompat#FLAG_HANDLES_QUEUE_COMMANDS} is set.
*
* @param description The {@link MediaDescriptionCompat} for denoting the
* {@link MediaSessionCompat.QueueItem} to be removed.
* @throws UnsupportedOperationException If this session doesn't support this.
+ * @see #getFlags()
* @see MediaSessionCompat#FLAG_HANDLES_QUEUE_COMMANDS
*/
public void removeQueueItem(MediaDescriptionCompat description) {
@@ -302,10 +314,13 @@
/**
* Remove an queue item at the specified position in the play queue
- * of this session. Not all sessions may support this.
+ * of this session. Not all sessions may support this. To know whether the session supports
+ * this, get the session's flags with {@link #getFlags()} and check that the flag
+ * {@link MediaSessionCompat#FLAG_HANDLES_QUEUE_COMMANDS} is set.
*
* @param index The index of the element to be removed.
* @throws UnsupportedOperationException If this session doesn't support this.
+ * @see #getFlags()
* @see MediaSessionCompat#FLAG_HANDLES_QUEUE_COMMANDS
*/
public void removeQueueItemAt(int index) {
@@ -345,6 +360,15 @@
}
/**
+ * Return whether captioning is enabled for this session.
+ *
+ * @return {@code true} if captioning is enabled, {@code false} if disabled or not set.
+ */
+ public boolean isCaptioningEnabled() {
+ return mImpl.isCaptioningEnabled();
+ }
+
+ /**
* Get the repeat mode for this session.
*
* @return The latest repeat mode set to the session, or
@@ -499,15 +523,6 @@
return mImpl.getPackageName();
}
- @VisibleForTesting
- boolean isExtraBinderReady() {
- if (mImpl instanceof MediaControllerImplApi21) {
- return ((MediaControllerImplApi21) mImpl).mExtraBinder != null;
- } else {
- return false;
- }
- }
-
/**
* Gets the underlying framework
* {@link android.media.session.MediaController} object.
@@ -533,8 +548,9 @@
boolean mRegistered = false;
+ @SuppressLint("NewApi")
public Callback() {
- if (android.os.Build.VERSION.SDK_INT >= 26) {
+ if (BuildCompat.isAtLeastO()) {
mCallbackObj = MediaControllerCompatApi26.createCallback(new StubApi26());
} else if (android.os.Build.VERSION.SDK_INT >= 21) {
mCallbackObj = MediaControllerCompatApi21.createCallback(new StubApi21());
@@ -617,6 +633,14 @@
}
/**
+ * Override to handle changes to the captioning enabled status.
+ *
+ * @param enabled {@code true} if captioning is enabled, {@code false} otherwise.
+ */
+ public void onCaptioningEnabledChanged(boolean enabled) {
+ }
+
+ /**
* Override to handle changes to the repeat mode.
*
* @param repeatMode The repeat mode. It should be one of followings:
@@ -751,6 +775,11 @@
}
@Override
+ public void onCaptioningEnabledChanged(boolean enabled) throws RemoteException {
+ mHandler.post(MessageHandler.MSG_UPDATE_CAPTIONING_ENABLED, enabled, null);
+ }
+
+ @Override
public void onRepeatModeChanged(int repeatMode) throws RemoteException {
mHandler.post(MessageHandler.MSG_UPDATE_REPEAT_MODE, repeatMode, null);
}
@@ -787,6 +816,7 @@
private static final int MSG_DESTROYED = 8;
private static final int MSG_UPDATE_REPEAT_MODE = 9;
private static final int MSG_UPDATE_SHUFFLE_MODE = 10;
+ private static final int MSG_UPDATE_CAPTIONING_ENABLED = 11;
public MessageHandler(Looper looper) {
super(looper);
@@ -813,6 +843,9 @@
case MSG_UPDATE_QUEUE_TITLE:
onQueueTitleChanged((CharSequence) msg.obj);
break;
+ case MSG_UPDATE_CAPTIONING_ENABLED:
+ onCaptioningEnabledChanged((boolean) msg.obj);
+ break;
case MSG_UPDATE_REPEAT_MODE:
onRepeatModeChanged((int) msg.obj);
break;
@@ -994,6 +1027,13 @@
public abstract void setRating(RatingCompat rating);
/**
+ * Enable/disable captioning for this session.
+ *
+ * @param enabled {@code true} to enable captioning, {@code false} to disable.
+ */
+ public abstract void setCaptioningEnabled(boolean enabled);
+
+ /**
* Set the repeat mode for this session.
*
* @param repeatMode The repeat mode. Must be one of the followings:
@@ -1026,6 +1066,8 @@
*
* @see #sendCustomAction(PlaybackStateCompat.CustomAction action,
* Bundle args)
+ * @see MediaSessionCompat#ACTION_FLAG_AS_INAPPROPRIATE
+ * @see MediaSessionCompat#ACTION_SKIP_AD
* @param action The action identifier of the
* {@link PlaybackStateCompat.CustomAction} as specified by
* the {@link MediaSessionCompat}.
@@ -1139,6 +1181,7 @@
CharSequence getQueueTitle();
Bundle getExtras();
int getRatingType();
+ boolean isCaptioningEnabled();
int getRepeatMode();
boolean isShuffleModeEnabled();
long getFlags();
@@ -1154,12 +1197,10 @@
}
static class MediaControllerImplBase implements MediaControllerImpl {
- private MediaSessionCompat.Token mToken;
private IMediaSession mBinder;
private TransportControls mTransportControls;
public MediaControllerImplBase(MediaSessionCompat.Token token) {
- mToken = token;
mBinder = IMediaSession.Stub.asInterface((IBinder) token.getToken());
}
@@ -1333,6 +1374,16 @@
}
@Override
+ public boolean isCaptioningEnabled() {
+ try {
+ return mBinder.isCaptioningEnabled();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Dead object in isCaptioningEnabled.", e);
+ }
+ return false;
+ }
+
+ @Override
public int getRepeatMode() {
try {
return mBinder.getRepeatMode();
@@ -1590,6 +1641,15 @@
}
@Override
+ public void setCaptioningEnabled(boolean enabled) {
+ try {
+ mBinder.setCaptioningEnabled(enabled);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Dead object in setCaptioningEnabled.", e);
+ }
+ }
+
+ @Override
public void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode) {
try {
mBinder.setRepeatMode(repeatMode);
@@ -1635,7 +1695,10 @@
public MediaControllerImplApi21(Context context, MediaSessionCompat session) {
mControllerObj = MediaControllerCompatApi21.fromToken(context,
session.getSessionToken().getToken());
- requestExtraBinder();
+ mExtraBinder = session.getSessionToken().getExtraBinder();
+ if (mExtraBinder == null) {
+ requestExtraBinder();
+ }
}
public MediaControllerImplApi21(Context context, MediaSessionCompat.Token sessionToken)
@@ -1643,7 +1706,10 @@
mControllerObj = MediaControllerCompatApi21.fromToken(context,
sessionToken.getToken());
if (mControllerObj == null) throw new RemoteException();
- requestExtraBinder();
+ mExtraBinder = sessionToken.getExtraBinder();
+ if (mExtraBinder == null) {
+ requestExtraBinder();
+ }
}
@Override
@@ -1726,6 +1792,11 @@
@Override
public void addQueueItem(MediaDescriptionCompat description) {
+ long flags = getFlags();
+ if ((flags & MediaSessionCompat.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
+ throw new UnsupportedOperationException(
+ "This session doesn't support queue management operations");
+ }
Bundle params = new Bundle();
params.putParcelable(COMMAND_ARGUMENT_MEDIA_DESCRIPTION, description);
sendCommand(COMMAND_ADD_QUEUE_ITEM, params, null);
@@ -1733,6 +1804,11 @@
@Override
public void addQueueItem(MediaDescriptionCompat description, int index) {
+ long flags = getFlags();
+ if ((flags & MediaSessionCompat.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
+ throw new UnsupportedOperationException(
+ "This session doesn't support queue management operations");
+ }
Bundle params = new Bundle();
params.putParcelable(COMMAND_ARGUMENT_MEDIA_DESCRIPTION, description);
params.putInt(COMMAND_ARGUMENT_INDEX, index);
@@ -1741,6 +1817,11 @@
@Override
public void removeQueueItem(MediaDescriptionCompat description) {
+ long flags = getFlags();
+ if ((flags & MediaSessionCompat.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
+ throw new UnsupportedOperationException(
+ "This session doesn't support queue management operations");
+ }
Bundle params = new Bundle();
params.putParcelable(COMMAND_ARGUMENT_MEDIA_DESCRIPTION, description);
sendCommand(COMMAND_REMOVE_QUEUE_ITEM, params, null);
@@ -1748,6 +1829,11 @@
@Override
public void removeQueueItemAt(int index) {
+ long flags = getFlags();
+ if ((flags & MediaSessionCompat.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
+ throw new UnsupportedOperationException(
+ "This session doesn't support queue management operations");
+ }
Bundle params = new Bundle();
params.putInt(COMMAND_ARGUMENT_INDEX, index);
sendCommand(COMMAND_REMOVE_QUEUE_ITEM_AT, params, null);
@@ -1776,6 +1862,18 @@
}
@Override
+ public boolean isCaptioningEnabled() {
+ if (mExtraBinder != null) {
+ try {
+ return mExtraBinder.isCaptioningEnabled();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Dead object in isCaptioningEnabled.", e);
+ }
+ }
+ return false;
+ }
+
+ @Override
public int getRepeatMode() {
if (mExtraBinder != null) {
try {
@@ -1845,7 +1943,6 @@
return mControllerObj;
}
- // TODO: Handle the case of calling other methods before receiving the extra binder.
private void requestExtraBinder() {
sendCommand(COMMAND_GET_EXTRA_BINDER, null,
new ExtraBinderRequestResultReceiver(this, new Handler()));
@@ -1945,6 +2042,16 @@
}
@Override
+ public void onCaptioningEnabledChanged(final boolean enabled) throws RemoteException {
+ mCallback.mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mCallback.onCaptioningEnabledChanged(enabled);
+ }
+ });
+ }
+
+ @Override
public void onRepeatModeChanged(final int repeatMode) throws RemoteException {
mCallback.mHandler.post(new Runnable() {
@Override
@@ -2061,6 +2168,13 @@
}
@Override
+ public void setCaptioningEnabled(boolean enabled) {
+ Bundle bundle = new Bundle();
+ bundle.putBoolean(MediaSessionCompat.ACTION_ARGUMENT_CAPTIONING_ENABLED, enabled);
+ sendCustomAction(MediaSessionCompat.ACTION_SET_CAPTIONING_ENABLED, bundle);
+ }
+
+ @Override
public void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode) {
Bundle bundle = new Bundle();
bundle.putInt(MediaSessionCompat.ACTION_ARGUMENT_REPEAT_MODE, repeatMode);
@@ -2225,6 +2339,33 @@
public boolean isShuffleModeEnabled() {
return MediaControllerCompatApi26.isShuffleModeEnabled(mControllerObj);
}
+
+ @Override
+ public void addQueueItem(MediaDescriptionCompat description) {
+ MediaControllerCompatApi26.addQueueItem(
+ mControllerObj,
+ description == null ? null : description.getMediaDescription());
+ }
+
+ @Override
+ public void addQueueItem(MediaDescriptionCompat description, int index) {
+ MediaControllerCompatApi26.addQueueItem(
+ mControllerObj,
+ description == null ? null : description.getMediaDescription(),
+ index);
+ }
+
+ @Override
+ public void removeQueueItem(MediaDescriptionCompat description) {
+ MediaControllerCompatApi26.removeQueueItem(
+ mControllerObj,
+ description == null ? null : description.getMediaDescription());
+ }
+
+ @Override
+ public void removeQueueItemAt(int index) {
+ MediaControllerCompatApi26.removeQueueItemAt(mControllerObj, index);
+ }
}
@RequiresApi(26)
diff --git a/media-compat/java/android/support/v4/media/session/MediaSessionCompat.java b/media-compat/java/android/support/v4/media/session/MediaSessionCompat.java
index 710de2b..fdea9cf 100644
--- a/media-compat/java/android/support/v4/media/session/MediaSessionCompat.java
+++ b/media-compat/java/android/support/v4/media/session/MediaSessionCompat.java
@@ -19,6 +19,7 @@
import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -52,6 +53,7 @@
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.RatingCompat;
import android.support.v4.media.VolumeProviderCompat;
+import android.support.v4.os.BuildCompat;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
@@ -126,6 +128,22 @@
public static final int FLAG_HANDLES_QUEUE_COMMANDS = 1 << 2;
/**
+ * Predefined custom action to flag the media that is currently playing as inappropriate.
+ *
+ * @see Callback#onCustomAction
+ */
+ public static final String ACTION_FLAG_AS_INAPPROPRIATE =
+ "android.support.v4.media.session.action.FLAG_AS_INAPPROPRIATE";
+
+ /**
+ * Predefined custom action to skip the advertisement that is currently playing.
+ *
+ * @see Callback#onCustomAction
+ */
+ public static final String ACTION_SKIP_AD =
+ "android.support.v4.media.session.action.SKIP_AD";
+
+ /**
* Custom action to invoke playFromUri() for the forward compatibility.
*/
static final String ACTION_PLAY_FROM_URI =
@@ -155,6 +173,12 @@
"android.support.v4.media.session.action.PREPARE_FROM_URI";
/**
+ * Custom action to invoke setCaptioningEnabled() for the forward compatibility.
+ */
+ static final String ACTION_SET_CAPTIONING_ENABLED =
+ "android.support.v4.media.session.action.SET_CAPTIONING_ENABLED";
+
+ /**
* Custom action to invoke setRepeatMode() for the forward compatibility.
*/
static final String ACTION_SET_REPEAT_MODE =
@@ -192,6 +216,13 @@
"android.support.v4.media.session.action.ARGUMENT_EXTRAS";
/**
+ * Argument for use with {@link #ACTION_SET_CAPTIONING_ENABLED} indicating whether captioning is
+ * enabled.
+ */
+ static final String ACTION_ARGUMENT_CAPTIONING_ENABLED =
+ "android.support.v4.media.session.action.ARGUMENT_CAPTIONING_ENABLED";
+
+ /**
* Argument for use with {@link #ACTION_SET_REPEAT_MODE} indicating repeat mode.
*/
static final String ACTION_ARGUMENT_REPEAT_MODE =
@@ -549,6 +580,15 @@
}
/**
+ * Enable/disable captioning for this session.
+ *
+ * @param enabled {@code true} to enable captioning, {@code false} to disable.
+ */
+ public void setCaptioningEnabled(boolean enabled) {
+ mImpl.setCaptioningEnabled(enabled);
+ }
+
+ /**
* Set the repeat mode for this session.
* <p>
* Note that if this method is not called before, {@link MediaControllerCompat#getRepeatMode}
@@ -695,8 +735,9 @@
final Object mCallbackObj;
WeakReference<MediaSessionImpl> mSessionImpl;
+ @SuppressLint("NewApi")
public Callback() {
- if (android.os.Build.VERSION.SDK_INT >= 26) {
+ if (BuildCompat.isAtLeastO()) {
mCallbackObj = MediaSessionCompatApi26.createCallback(new StubApi26());
} else if (android.os.Build.VERSION.SDK_INT >= 24) {
mCallbackObj = MediaSessionCompatApi24.createCallback(new StubApi24());
@@ -864,6 +905,14 @@
}
/**
+ * Override to handle requests to enable/disable captioning.
+ *
+ * @param enabled {@code true} to enable captioning, {@code false} to disable.
+ */
+ public void onSetCaptioningEnabled(boolean enabled) {
+ }
+
+ /**
* Override to handle the setting of the repeat mode.
* <p>
* You should call {@link #setRepeatMode} before end of this method in order to notify
@@ -898,6 +947,8 @@
* {@link PlaybackStateCompat.CustomAction}.
* @param extras Optional extras specified by the
* {@link MediaControllerCompat}.
+ * @see #ACTION_FLAG_AS_INAPPROPRIATE
+ * @see #ACTION_SKIP_AD
*/
public void onCustomAction(String action, Bundle extras) {
}
@@ -956,7 +1007,8 @@
MediaSessionImplApi21 impl = (MediaSessionImplApi21) mSessionImpl.get();
if (impl != null) {
Bundle result = new Bundle();
- BundleCompat.putBinder(result, EXTRA_BINDER, impl.getExtraSessionBinder());
+ BundleCompat.putBinder(result, EXTRA_BINDER,
+ (IBinder) impl.getSessionToken().getExtraBinder());
cb.send(0, result);
}
} else if (command.equals(MediaControllerCompat.COMMAND_ADD_QUEUE_ITEM)) {
@@ -1068,6 +1120,9 @@
Uri uri = extras.getParcelable(ACTION_ARGUMENT_URI);
Bundle bundle = extras.getBundle(ACTION_ARGUMENT_EXTRAS);
Callback.this.onPrepareFromUri(uri, bundle);
+ } else if (action.equals(ACTION_SET_CAPTIONING_ENABLED)) {
+ boolean enabled = extras.getBoolean(ACTION_ARGUMENT_CAPTIONING_ENABLED);
+ Callback.this.onSetCaptioningEnabled(enabled);
} else if (action.equals(ACTION_SET_REPEAT_MODE)) {
int repeatMode = extras.getInt(ACTION_ARGUMENT_REPEAT_MODE);
Callback.this.onSetRepeatMode(repeatMode);
@@ -1130,6 +1185,29 @@
public void onSetShuffleModeEnabled(boolean enabled) {
Callback.this.onSetShuffleModeEnabled(enabled);
}
+
+ @Override
+ public void onAddQueueItem(Object descriptionObject) {
+ Callback.this.onAddQueueItem(
+ MediaDescriptionCompat.fromMediaDescription(descriptionObject));
+ }
+
+ @Override
+ public void onAddQueueItem(Object descriptionObject, int index) {
+ Callback.this.onAddQueueItem(
+ MediaDescriptionCompat.fromMediaDescription(descriptionObject), index);
+ }
+
+ @Override
+ public void onRemoveQueueItem(Object descriptionObject) {
+ Callback.this.onRemoveQueueItem(
+ MediaDescriptionCompat.fromMediaDescription(descriptionObject));
+ }
+
+ @Override
+ public void onRemoveQueueItemAt(int index) {
+ Callback.this.onRemoveQueueItemAt(index);
+ }
}
}
@@ -1140,9 +1218,15 @@
*/
public static final class Token implements Parcelable {
private final Object mInner;
+ private final IMediaSession mExtraBinder;
Token(Object inner) {
+ this(inner, null);
+ }
+
+ Token(Object inner, IMediaSession extraBinder) {
mInner = inner;
+ mExtraBinder = extraBinder;
}
/**
@@ -1157,8 +1241,26 @@
* @return A compat Token for use with {@link MediaControllerCompat}.
*/
public static Token fromToken(Object token) {
+ return fromToken(token, null);
+ }
+
+ /**
+ * Creates a compat Token from a framework
+ * {@link android.media.session.MediaSession.Token} object, and the extra binder.
+ * <p>
+ * This method is only supported on
+ * {@link android.os.Build.VERSION_CODES#LOLLIPOP} and later.
+ * </p>
+ *
+ * @param token The framework token object.
+ * @param extraBinder The extra binder.
+ * @return A compat Token for use with {@link MediaControllerCompat}.
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ public static Token fromToken(Object token, IMediaSession extraBinder) {
if (token != null && android.os.Build.VERSION.SDK_INT >= 21) {
- return new Token(MediaSessionCompatApi21.verifyToken(token));
+ return new Token(MediaSessionCompatApi21.verifyToken(token), extraBinder);
}
return null;
}
@@ -1172,6 +1274,7 @@
public void writeToParcel(Parcel dest, int flags) {
if (android.os.Build.VERSION.SDK_INT >= 21) {
dest.writeParcelable((Parcelable) mInner, flags);
+ dest.writeStrongBinder((IBinder) mExtraBinder);
} else {
dest.writeStrongBinder((IBinder) mInner);
}
@@ -1217,23 +1320,33 @@
return mInner;
}
+ /**
+ * @hide
+ */
+ @RestrictTo(LIBRARY_GROUP)
+ public IMediaSession getExtraBinder() {
+ return mExtraBinder;
+ }
+
public static final Parcelable.Creator<Token> CREATOR
= new Parcelable.Creator<Token>() {
- @Override
- public Token createFromParcel(Parcel in) {
- Object inner;
- if (android.os.Build.VERSION.SDK_INT >= 21) {
- inner = in.readParcelable(null);
- } else {
- inner = in.readStrongBinder();
- }
- return new Token(inner);
- }
+ @Override
+ public Token createFromParcel(Parcel in) {
+ Object inner;
+ IMediaSession extraBinder = null;
+ if (android.os.Build.VERSION.SDK_INT >= 21) {
+ inner = in.readParcelable(null);
+ extraBinder = (IMediaSession) in.readStrongBinder();
+ } else {
+ inner = in.readStrongBinder();
+ }
+ return new Token(inner, extraBinder);
+ }
- @Override
- public Token[] newArray(int size) {
- return new Token[size];
- }
+ @Override
+ public Token[] newArray(int size) {
+ return new Token[size];
+ }
};
}
@@ -1468,6 +1581,7 @@
void setQueueTitle(CharSequence title);
void setRatingType(@RatingCompat.Style int type);
+ void setCaptioningEnabled(boolean enabled);
void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode);
void setShuffleModeEnabled(boolean enabled);
void setExtras(Bundle extras);
@@ -1512,6 +1626,7 @@
List<QueueItem> mQueue;
CharSequence mQueueTitle;
@RatingCompat.Style int mRatingType;
+ boolean mCaptioningEnabled;
@PlaybackStateCompat.RepeatMode int mRepeatMode;
boolean mShuffleModeEnabled;
Bundle mExtras;
@@ -1889,6 +2004,14 @@
}
@Override
+ public void setCaptioningEnabled(boolean enabled) {
+ if (mCaptioningEnabled != enabled) {
+ mCaptioningEnabled = enabled;
+ sendCaptioningEnabled(enabled);
+ }
+ }
+
+ @Override
public void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode) {
if (mRepeatMode != repeatMode) {
mRepeatMode = repeatMode;
@@ -2108,6 +2231,18 @@
mControllerCallbacks.finishBroadcast();
}
+ private void sendCaptioningEnabled(boolean enabled) {
+ int size = mControllerCallbacks.beginBroadcast();
+ for (int i = size - 1; i >= 0; i--) {
+ IMediaControllerCallback cb = mControllerCallbacks.getBroadcastItem(i);
+ try {
+ cb.onCaptioningEnabledChanged(enabled);
+ } catch (RemoteException e) {
+ }
+ }
+ mControllerCallbacks.finishBroadcast();
+ }
+
private void sendRepeatMode(int repeatMode) {
int size = mControllerCallbacks.beginBroadcast();
for (int i = size - 1; i >= 0; i--) {
@@ -2328,6 +2463,11 @@
}
@Override
+ public void setCaptioningEnabled(boolean enabled) throws RemoteException {
+ postToHandler(MessageHandler.MSG_SET_CAPTIONING_ENABLED, enabled);
+ }
+
+ @Override
public void setRepeatMode(int repeatMode) throws RemoteException {
postToHandler(MessageHandler.MSG_SET_REPEAT_MODE, repeatMode);
}
@@ -2399,6 +2539,11 @@
}
@Override
+ public boolean isCaptioningEnabled() {
+ return mCaptioningEnabled;
+ }
+
+ @Override
@PlaybackStateCompat.RepeatMode
public int getRepeatMode() {
return mRepeatMode;
@@ -2457,6 +2602,7 @@
private static final int MSG_ADD_QUEUE_ITEM_AT = 26;
private static final int MSG_REMOVE_QUEUE_ITEM = 27;
private static final int MSG_REMOVE_QUEUE_ITEM_AT = 28;
+ private static final int MSG_SET_CAPTIONING_ENABLED = 29;
// KeyEvent constants only available on API 11+
private static final int KEYCODE_MEDIA_PAUSE = 127;
@@ -2576,6 +2722,9 @@
case MSG_SET_VOLUME:
setVolumeTo(msg.arg1, 0);
break;
+ case MSG_SET_CAPTIONING_ENABLED:
+ cb.onSetCaptioningEnabled((boolean) msg.obj);
+ break;
case MSG_SET_REPEAT_MODE:
cb.onSetRepeatMode(msg.arg1);
break;
@@ -2802,23 +2951,25 @@
private final Token mToken;
private boolean mDestroyed = false;
- private ExtraSession mExtraSessionBinder;
private final RemoteCallbackList<IMediaControllerCallback> mExtraControllerCallbacks =
new RemoteCallbackList<>();
private PlaybackStateCompat mPlaybackState;
@RatingCompat.Style int mRatingType;
+ boolean mCaptioningEnabled;
@PlaybackStateCompat.RepeatMode int mRepeatMode;
boolean mShuffleModeEnabled;
public MediaSessionImplApi21(Context context, String tag) {
mSessionObj = MediaSessionCompatApi21.createSession(context, tag);
- mToken = new Token(MediaSessionCompatApi21.getSessionToken(mSessionObj));
+ mToken = new Token(MediaSessionCompatApi21.getSessionToken(mSessionObj),
+ new ExtraSession());
}
public MediaSessionImplApi21(Object mediaSession) {
mSessionObj = MediaSessionCompatApi21.verifySession(mediaSession);
- mToken = new Token(MediaSessionCompatApi21.getSessionToken(mSessionObj));
+ mToken = new Token(MediaSessionCompatApi21.getSessionToken(mSessionObj),
+ new ExtraSession());
}
@Override
@@ -2942,6 +3093,22 @@
}
@Override
+ public void setCaptioningEnabled(boolean enabled) {
+ if (mCaptioningEnabled != enabled) {
+ mCaptioningEnabled = enabled;
+ int size = mExtraControllerCallbacks.beginBroadcast();
+ for (int i = size - 1; i >= 0; i--) {
+ IMediaControllerCallback cb = mExtraControllerCallbacks.getBroadcastItem(i);
+ try {
+ cb.onCaptioningEnabledChanged(enabled);
+ } catch (RemoteException e) {
+ }
+ }
+ mExtraControllerCallbacks.finishBroadcast();
+ }
+ }
+
+ @Override
public void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode) {
if (android.os.Build.VERSION.SDK_INT < 26) {
if (mRepeatMode != repeatMode) {
@@ -3005,13 +3172,6 @@
}
}
- ExtraSession getExtraSessionBinder() {
- if (mExtraSessionBinder == null) {
- mExtraSessionBinder = new ExtraSession();
- }
- return mExtraSessionBinder;
- }
-
class ExtraSession extends IMediaSession.Stub {
@Override
public void sendCommand(String command, Bundle args, ResultReceiverWrapper cb) {
@@ -3183,6 +3343,12 @@
}
@Override
+ public void setCaptioningEnabled(boolean enabled) throws RemoteException {
+ // Will not be called.
+ throw new AssertionError();
+ }
+
+ @Override
public void setRepeatMode(int repeatMode) throws RemoteException {
// Will not be called.
throw new AssertionError();
@@ -3260,6 +3426,11 @@
}
@Override
+ public boolean isCaptioningEnabled() {
+ return mCaptioningEnabled;
+ }
+
+ @Override
@PlaybackStateCompat.RepeatMode
public int getRepeatMode() {
return mRepeatMode;
diff --git a/media-compat/java/android/support/v4/media/session/PlaybackStateCompat.java b/media-compat/java/android/support/v4/media/session/PlaybackStateCompat.java
index ab85133..5d9f84e 100644
--- a/media-compat/java/android/support/v4/media/session/PlaybackStateCompat.java
+++ b/media-compat/java/android/support/v4/media/session/PlaybackStateCompat.java
@@ -50,7 +50,7 @@
ACTION_SEEK_TO, ACTION_PLAY_PAUSE, ACTION_PLAY_FROM_MEDIA_ID, ACTION_PLAY_FROM_SEARCH,
ACTION_SKIP_TO_QUEUE_ITEM, ACTION_PLAY_FROM_URI, ACTION_PREPARE,
ACTION_PREPARE_FROM_MEDIA_ID, ACTION_PREPARE_FROM_SEARCH, ACTION_PREPARE_FROM_URI,
- ACTION_SET_REPEAT_MODE, ACTION_SET_SHUFFLE_MODE_ENABLED})
+ ACTION_SET_REPEAT_MODE, ACTION_SET_SHUFFLE_MODE_ENABLED, ACTION_SET_CAPTIONING_ENABLED})
@Retention(RetentionPolicy.SOURCE)
public @interface Actions {}
@@ -204,6 +204,13 @@
public static final long ACTION_SET_SHUFFLE_MODE_ENABLED = 1 << 19;
/**
+ * Indicates this session supports the set captioning enabled command.
+ *
+ * @see Builder#setActions(long)
+ */
+ public static final long ACTION_SET_CAPTIONING_ENABLED = 1 << 20;
+
+ /**
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
@@ -625,6 +632,7 @@
* <li> {@link PlaybackStateCompat#ACTION_PREPARE_FROM_URI}</li>
* <li> {@link PlaybackStateCompat#ACTION_SET_REPEAT_MODE}</li>
* <li> {@link PlaybackStateCompat#ACTION_SET_SHUFFLE_MODE_ENABLED}</li>
+ * <li> {@link PlaybackStateCompat#ACTION_SET_CAPTIONING_ENABLED}</li>
* </ul>
*/
@Actions
@@ -1169,6 +1177,7 @@
* <li> {@link PlaybackStateCompat#ACTION_PREPARE_FROM_URI}</li>
* <li> {@link PlaybackStateCompat#ACTION_SET_REPEAT_MODE}</li>
* <li> {@link PlaybackStateCompat#ACTION_SET_SHUFFLE_MODE_ENABLED}</li>
+ * <li> {@link PlaybackStateCompat#ACTION_SET_CAPTIONING_ENABLED}</li>
* </ul>
*
* @return this
diff --git a/media-compat/tests/src/android/support/v4/media/MediaBrowserCompatTest.java b/media-compat/tests/src/android/support/v4/media/MediaBrowserCompatTest.java
index fd87a76..5be500d 100644
--- a/media-compat/tests/src/android/support/v4/media/MediaBrowserCompatTest.java
+++ b/media-compat/tests/src/android/support/v4/media/MediaBrowserCompatTest.java
@@ -27,6 +27,7 @@
import android.os.Bundle;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.support.testutils.PollingCheck;
import android.support.v4.media.MediaBrowserCompat.MediaItem;
import org.junit.Test;
diff --git a/media-compat/tests/src/android/support/v4/media/PollingCheck.java b/media-compat/tests/src/android/support/v4/media/PollingCheck.java
deleted file mode 100644
index 222753f..0000000
--- a/media-compat/tests/src/android/support/v4/media/PollingCheck.java
+++ /dev/null
@@ -1,94 +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.v4.media;
-
-import junit.framework.Assert;
-
-import java.util.concurrent.Callable;
-
-public abstract class PollingCheck {
- private static final long TIME_SLICE = 50;
- private long mTimeout = 3000;
-
- public interface PollingCheckCondition {
- boolean canProceed();
- }
-
- public PollingCheck() {
- }
-
- public PollingCheck(long timeout) {
- mTimeout = timeout;
- }
-
- protected abstract boolean check();
-
- public void run() {
- if (check()) {
- return;
- }
-
- long timeout = mTimeout;
- while (timeout > 0) {
- try {
- Thread.sleep(TIME_SLICE);
- } catch (InterruptedException e) {
- Assert.fail("unexpected InterruptedException");
- }
-
- if (check()) {
- return;
- }
-
- timeout -= TIME_SLICE;
- }
-
- Assert.fail("unexpected timeout");
- }
-
- public static void check(CharSequence message, long timeout, Callable<Boolean> condition)
- throws Exception {
- while (timeout > 0) {
- if (condition.call()) {
- return;
- }
-
- Thread.sleep(TIME_SLICE);
- timeout -= TIME_SLICE;
- }
-
- Assert.fail(message.toString());
- }
-
- public static void waitFor(final PollingCheckCondition condition) {
- new PollingCheck() {
- @Override
- protected boolean check() {
- return condition.canProceed();
- }
- }.run();
- }
-
- public static void waitFor(long timeout, final PollingCheckCondition condition) {
- new PollingCheck(timeout) {
- @Override
- protected boolean check() {
- return condition.canProceed();
- }
- }.run();
- }
-}
diff --git a/media-compat/tests/src/android/support/v4/media/session/MediaControllerCompatTest.java b/media-compat/tests/src/android/support/v4/media/session/MediaControllerCompatTest.java
index 2598bef..a1d18d0 100644
--- a/media-compat/tests/src/android/support/v4/media/session/MediaControllerCompatTest.java
+++ b/media-compat/tests/src/android/support/v4/media/session/MediaControllerCompatTest.java
@@ -21,10 +21,10 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import android.media.AudioManager;
import android.net.Uri;
-import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -32,7 +32,6 @@
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.support.v4.media.MediaDescriptionCompat;
-import android.support.v4.media.PollingCheck;
import android.support.v4.media.RatingCompat;
import android.support.v4.media.VolumeProviderCompat;
@@ -52,6 +51,8 @@
private static final String EXTRAS_KEY = "test-key";
private static final String EXTRAS_VALUE = "test-val";
private static final float DELTA = 1e-4f;
+ private static final boolean ENABLED = true;
+ private static final boolean DISABLED = false;
private final Object mWaitLock = new Object();
private Handler mHandler = new Handler(Looper.getMainLooper());
@@ -90,15 +91,6 @@
RatingCompat.RATING_NONE, mController.getRatingType());
mSession.setRatingType(RatingCompat.RATING_5_STARS);
- if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
- // Wait until the extra binder is ready.
- new PollingCheck(TIME_OUT_MS) {
- @Override
- protected boolean check() {
- return mController.getRatingType() != RatingCompat.RATING_NONE;
- }
- }.run();
- }
assertEquals(RatingCompat.RATING_5_STARS, mController.getRatingType());
}
@@ -162,6 +154,15 @@
assertTrue(mCallback.mOnRemoveQueueItemCalled);
assertEquals(mediaId, mCallback.mQueueDescription.getMediaId());
assertEquals(mediaTitle, mCallback.mQueueDescription.getTitle());
+
+ // Try to modify the queue when the session does not support queue management.
+ mSession.setFlags(0);
+ try {
+ mController.addQueueItem(itemDescription);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // Expected.
+ }
}
}
@@ -349,6 +350,12 @@
assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
mCallback.reset();
+ controls.setCaptioningEnabled(ENABLED);
+ mWaitLock.wait(TIME_OUT_MS);
+ assertTrue(mCallback.mOnSetCaptioningEnabledCalled);
+ assertEquals(ENABLED, mCallback.mCaptioningEnabled);
+
+ mCallback.reset();
final int repeatMode = PlaybackStateCompat.REPEAT_MODE_ALL;
controls.setRepeatMode(repeatMode);
mWaitLock.wait(TIME_OUT_MS);
@@ -356,11 +363,10 @@
assertEquals(repeatMode, mCallback.mRepeatMode);
mCallback.reset();
- final boolean shuffleModeEnabled = true;
- controls.setShuffleModeEnabled(shuffleModeEnabled);
+ controls.setShuffleModeEnabled(ENABLED);
mWaitLock.wait(TIME_OUT_MS);
assertTrue(mCallback.mOnSetShuffleModeEnabledCalled);
- assertEquals(shuffleModeEnabled, mCallback.mShuffleModeEnabled);
+ assertEquals(ENABLED, mCallback.mShuffleModeEnabled);
}
}
@@ -394,6 +400,7 @@
private String mCommand;
private Bundle mExtras;
private ResultReceiver mCommandCallback;
+ private boolean mCaptioningEnabled;
private int mRepeatMode;
private boolean mShuffleModeEnabled;
private int mQueueIndex;
@@ -418,6 +425,7 @@
private boolean mOnPrepareFromMediaIdCalled;
private boolean mOnPrepareFromSearchCalled;
private boolean mOnPrepareFromUriCalled;
+ private boolean mOnSetCaptioningEnabledCalled;
private boolean mOnSetRepeatModeCalled;
private boolean mOnSetShuffleModeEnabledCalled;
private boolean mOnAddQueueItemCalled;
@@ -436,6 +444,7 @@
mExtras = null;
mCommand = null;
mCommandCallback = null;
+ mCaptioningEnabled = false;
mShuffleModeEnabled = false;
mRepeatMode = PlaybackStateCompat.REPEAT_MODE_NONE;
mQueueIndex = -1;
@@ -460,6 +469,7 @@
mOnPrepareFromMediaIdCalled = false;
mOnPrepareFromSearchCalled = false;
mOnPrepareFromUriCalled = false;
+ mOnSetCaptioningEnabledCalled = false;
mOnSetRepeatModeCalled = false;
mOnSetShuffleModeEnabledCalled = false;
mOnAddQueueItemCalled = false;
@@ -678,6 +688,15 @@
}
@Override
+ public void onSetCaptioningEnabled(boolean enabled) {
+ synchronized (mWaitLock) {
+ mOnSetCaptioningEnabledCalled = true;
+ mCaptioningEnabled = enabled;
+ mWaitLock.notify();
+ }
+ }
+
+ @Override
public void onSetShuffleModeEnabled(boolean enabled) {
synchronized (mWaitLock) {
mOnSetShuffleModeEnabledCalled = true;
diff --git a/media-compat/tests/src/android/support/v4/media/session/MediaSessionCompatTest.java b/media-compat/tests/src/android/support/v4/media/session/MediaSessionCompatTest.java
index 0e85c1c..1e22669 100644
--- a/media-compat/tests/src/android/support/v4/media/session/MediaSessionCompatTest.java
+++ b/media-compat/tests/src/android/support/v4/media/session/MediaSessionCompatTest.java
@@ -31,14 +31,12 @@
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
-import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Parcel;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
-import android.support.v4.media.PollingCheck;
import android.support.v4.media.MediaDescriptionCompat;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.RatingCompat;
@@ -213,9 +211,6 @@
@SmallTest
public void testSetPlaybackState() throws Exception {
MediaControllerCompat controller = mSession.getController();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- waitUntilExtraBinderReady(controller);
- }
controller.registerCallback(mCallback, mHandler);
synchronized (mWaitLock) {
mCallback.resetLocked();
@@ -310,15 +305,37 @@
}
/**
+ * Tests {@link MediaSessionCompat#setCaptioningEnabled}.
+ */
+ @Test
+ @SmallTest
+ public void testSetCaptioningEnabled() throws Exception {
+ MediaControllerCompat controller = mSession.getController();
+ controller.registerCallback(mCallback, mHandler);
+ synchronized (mWaitLock) {
+ mCallback.resetLocked();
+ mSession.setCaptioningEnabled(true);
+ mWaitLock.wait(TIME_OUT_MS);
+ assertTrue(mCallback.mOnCaptioningEnabledChangedCalled);
+ assertEquals(true, mCallback.mCaptioningEnabled);
+ assertEquals(true, controller.isCaptioningEnabled());
+
+ mCallback.resetLocked();
+ mSession.setCaptioningEnabled(false);
+ mWaitLock.wait(TIME_OUT_MS);
+ assertTrue(mCallback.mOnCaptioningEnabledChangedCalled);
+ assertEquals(false, mCallback.mCaptioningEnabled);
+ assertEquals(false, controller.isCaptioningEnabled());
+ }
+ }
+
+ /**
* Tests {@link MediaSessionCompat#setRepeatMode}.
*/
@Test
@SmallTest
public void testSetRepeatMode() throws Exception {
MediaControllerCompat controller = mSession.getController();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- waitUntilExtraBinderReady(controller);
- }
controller.registerCallback(mCallback, mHandler);
synchronized (mWaitLock) {
mCallback.resetLocked();
@@ -339,13 +356,9 @@
public void testSetShuffleModeEnabled() throws Exception {
final boolean shuffleModeEnabled = true;
MediaControllerCompat controller = mSession.getController();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- waitUntilExtraBinderReady(controller);
- }
controller.registerCallback(mCallback, mHandler);
synchronized (mWaitLock) {
mCallback.resetLocked();
- final int repeatMode = PlaybackStateCompat.REPEAT_MODE_ALL;
mSession.setShuffleModeEnabled(shuffleModeEnabled);
mWaitLock.wait(TIME_OUT_MS);
assertTrue(mCallback.mOnShuffleModeChangedCalled);
@@ -361,10 +374,6 @@
@SmallTest
public void testSendSessionEvent() throws Exception {
MediaControllerCompat controller = mSession.getController();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
- Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
- waitUntilExtraBinderReady(controller);
- }
controller.registerCallback(mCallback, mHandler);
synchronized (mWaitLock) {
mCallback.resetLocked();
@@ -620,15 +629,6 @@
controller.dispatchMediaButtonEvent(new KeyEvent(KeyEvent.ACTION_UP, keyCode));
}
- private void waitUntilExtraBinderReady(final MediaControllerCompat controller) {
- new PollingCheck(TIME_OUT_MS) {
- @Override
- protected boolean check() {
- return controller.isExtraBinderReady();
- }
- }.run();
- }
-
private class MediaControllerCallback extends MediaControllerCompat.Callback {
private volatile boolean mOnPlaybackStateChangedCalled;
private volatile boolean mOnMetadataChangedCalled;
@@ -638,6 +638,7 @@
private volatile boolean mOnAudioInfoChangedCalled;
private volatile boolean mOnSessionDestroyedCalled;
private volatile boolean mOnSessionEventCalled;
+ private volatile boolean mOnCaptioningEnabledChangedCalled;
private volatile boolean mOnRepeatModeChangedCalled;
private volatile boolean mOnShuffleModeChangedCalled;
@@ -648,6 +649,7 @@
private volatile String mEvent;
private volatile Bundle mExtras;
private volatile MediaControllerCompat.PlaybackInfo mPlaybackInfo;
+ private volatile boolean mCaptioningEnabled;
private volatile int mRepeatMode;
private volatile boolean mShuffleModeEnabled;
@@ -669,6 +671,7 @@
mTitle = null;
mExtras = null;
mPlaybackInfo = null;
+ mCaptioningEnabled = false;
mRepeatMode = PlaybackStateCompat.REPEAT_MODE_NONE;
mShuffleModeEnabled = false;
}
@@ -746,6 +749,15 @@
}
@Override
+ public void onCaptioningEnabledChanged(boolean enabled) {
+ synchronized (mWaitLock) {
+ mOnCaptioningEnabledChangedCalled = true;
+ mCaptioningEnabled = enabled;
+ mWaitLock.notify();
+ }
+ }
+
+ @Override
public void onRepeatModeChanged(int repeatMode) {
synchronized (mWaitLock) {
mOnRepeatModeChangedCalled = true;
diff --git a/previewsdk/Android.mk b/previewsdk/Android.mk
deleted file mode 100644
index ccd0547..0000000
--- a/previewsdk/Android.mk
+++ /dev/null
@@ -1,33 +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.
-
-LOCAL_PATH := $(call my-dir)
-
-# Here is the final static library that apps can link against.
-include $(CLEAR_VARS)
-
-previewsdk_generate_constants_exe := $(LOCAL_PATH)/previewconstants.sh
-previewsdk_gen_java_files := $(TARGET_OUT_COMMON_GEN)/previewsdk/PreviewSdkConstants.java
-
-$(previewsdk_gen_java_files): $(previewsdk_generate_constants_exe)
- $(hide) mkdir -p $(dir $@)
- $(hide) PLATFORM_PREVIEW_SDK_VERSION="$(PLATFORM_PREVIEW_SDK_VERSION)" \
- bash $< > $@
-
-LOCAL_MODULE := android-support-previewsdk
-LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-LOCAL_GENERATED_SOURCES := $(previewsdk_gen_java_files)
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_JAVA_LANGUAGE_VERSION := 1.7
-include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/previewsdk/previewconstants.sh b/previewsdk/previewconstants.sh
deleted file mode 100755
index de94f84..0000000
--- a/previewsdk/previewconstants.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-echo "/** Begin preview constants"
-echo " * autogenerated by previewconstants.sh */"
-echo "package android.support.previewsdk;"
-echo "class PreviewConstants {"
-echo " public static final int PREVIEW_SDK_VERSION = $PLATFORM_PREVIEW_SDK_VERSION;"
-echo "}"
diff --git a/previewsdk/src/android/support/previewsdk/PreviewSdk.java b/previewsdk/src/android/support/previewsdk/PreviewSdk.java
deleted file mode 100644
index 8b494c7..0000000
--- a/previewsdk/src/android/support/previewsdk/PreviewSdk.java
+++ /dev/null
@@ -1,46 +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 android.support.previewsdk;
-
-import android.os.Build;
-
-/**
- * Utility class for performing version checks on Android platform preview SDKs.
- *
- * <p>Apps must be very careful when targeting preview builds because binary compatibility
- * is not guaranteed. APIs can be renamed or drastically changed before they are finalized
- * into a new API level. The new SDK constant <code>Build.VERSION.PREVIEW_SDK_INT</code>
- * marks a precise snapshot version of prerelease API.</p>
- *
- * <p>{@link #isKnownPreviewDevice()} will return <code>true</code> if the current device
- * is running a preview build with the same SDK snapshot this support lib was built with.
- * If it returns <code>true</code> it is safe to call prerelease APIs. If not, the app
- * should fall back to only assuming the presence of the latest public, final API level.</p>
- */
-public class PreviewSdk {
- /**
- * Check if the current device is running a prerelease platform preview build matching
- * the SDK this library was built for. If it returns true, it is safe to call prerelease
- * APIs known to this SDK.
- *
- * @return true if the device is running a preview build that matches the SDK.
- */
- public static boolean isKnownPreviewDevice() {
- return "MNC".equals(Build.VERSION.CODENAME)
- && Build.VERSION.PREVIEW_SDK_INT == PreviewConstants.PREVIEW_SDK_VERSION;
- }
-}
diff --git a/recommendation/Android.mk b/recommendation/Android.mk
index 0e0a9d7..2a68de6 100644
--- a/recommendation/Android.mk
+++ b/recommendation/Android.mk
@@ -55,7 +55,7 @@
LOCAL_SDK_VERSION := 21
LOCAL_IS_HOST_MODULE := false
-LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR := build/tools/droiddoc/templates-sdk
+LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR := external/doclava/res/assets/templates-sdk
LOCAL_SHARED_ANDROID_LIBRARIES := $(recommendation.docs.java_libraries)
diff --git a/samples/Support13Demos/Android.mk b/samples/Support13Demos/Android.mk
deleted file mode 100644
index a227e10..0000000
--- a/samples/Support13Demos/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_USE_AAPT2 := true
-
-LOCAL_MODULE_TAGS := samples tests
-
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_STATIC_ANDROID_LIBRARIES += android-support-v13
-
-LOCAL_PACKAGE_NAME := Support13Demos
-
-LOCAL_SDK_VERSION := current
-
-LOCAL_MIN_SDK_VERSION := 13
-
-LOCAL_DEX_PREOPT := false
-
-include $(BUILD_PACKAGE)
-
-# Use the folloing include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/Support4Demos/Android.mk b/samples/Support4Demos/Android.mk
deleted file mode 100644
index 0ba19b0..0000000
--- a/samples/Support4Demos/Android.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_USE_AAPT2 := true
-LOCAL_MODULE_TAGS := samples tests
-
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_STATIC_ANDROID_LIBRARIES += android-support-v4
-
-LOCAL_PACKAGE_NAME := Support4Demos
-
-LOCAL_SDK_VERSION := current
-LOCAL_MIN_SDK_VERSION := 4
-
-LOCAL_DEX_PREOPT := false
-
-include $(BUILD_PACKAGE)
-
-# Use the following include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/view/ViewPagerActivity.java b/samples/Support4Demos/src/com/example/android/supportv4/view/ViewPagerActivity.java
index 5150363..487e8db 100644
--- a/samples/Support4Demos/src/com/example/android/supportv4/view/ViewPagerActivity.java
+++ b/samples/Support4Demos/src/com/example/android/supportv4/view/ViewPagerActivity.java
@@ -16,8 +16,6 @@
package com.example.android.supportv4.view;
-import com.example.android.supportv4.R;
-
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
@@ -28,6 +26,8 @@
import android.view.View;
import android.view.ViewGroup;
+import com.example.android.supportv4.R;
+
import java.util.ArrayList;
public class ViewPagerActivity extends Activity {
@@ -56,7 +56,7 @@
private ArrayList<Pair<String, Integer>> mEntries = new ArrayList<>();
public void add(String title, int color) {
- mEntries.add(new Pair(title, color));
+ mEntries.add(new Pair<>(title, color));
}
@Override
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/widget/BaseSwipeRefreshLayoutActivity.java b/samples/Support4Demos/src/com/example/android/supportv4/widget/BaseSwipeRefreshLayoutActivity.java
index 1403a94..c617507 100644
--- a/samples/Support4Demos/src/com/example/android/supportv4/widget/BaseSwipeRefreshLayoutActivity.java
+++ b/samples/Support4Demos/src/com/example/android/supportv4/widget/BaseSwipeRefreshLayoutActivity.java
@@ -16,8 +16,6 @@
package com.example.android.supportv4.widget;
-import com.example.android.supportv4.R;
-
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
@@ -27,9 +25,8 @@
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
+
+import com.example.android.supportv4.R;
/**
* Example of using the SwipeRefreshLayout.
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/widget/ContentLoadingProgressBarActivity.java b/samples/Support4Demos/src/com/example/android/supportv4/widget/ContentLoadingProgressBarActivity.java
index 08c14dc..c5f86aa 100644
--- a/samples/Support4Demos/src/com/example/android/supportv4/widget/ContentLoadingProgressBarActivity.java
+++ b/samples/Support4Demos/src/com/example/android/supportv4/widget/ContentLoadingProgressBarActivity.java
@@ -17,17 +17,13 @@
package com.example.android.supportv4.widget;
import android.app.Activity;
-import android.widget.Button;
-import android.widget.LinearLayout;
-import android.widget.ProgressBar;
-import android.widget.TextView;
import android.os.Bundle;
-import android.os.Handler;
import android.support.v4.widget.ContentLoadingProgressBar;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewTreeObserver;
-import android.view.Window;
+import android.widget.Button;
+import android.widget.TextView;
import com.example.android.supportv4.R;
diff --git a/samples/Support7Demos/Android.mk b/samples/Support7Demos/Android.mk
deleted file mode 100644
index fbea278..0000000
--- a/samples/Support7Demos/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-# Build the samples.
-include $(CLEAR_VARS)
-LOCAL_USE_AAPT2 := true
-LOCAL_PACKAGE_NAME := Support7Demos
-LOCAL_MODULE_TAGS := samples tests
-LOCAL_SDK_VERSION := current
-LOCAL_MIN_SDK_VERSION := 7
-LOCAL_DEX_PREOPT := false
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_ANDROID_LIBRARIES := \
- android-support-v7-appcompat \
- android-support-v7-gridlayout \
- android-support-v7-mediarouter \
- android-support-v7-cardview \
- android-support-design \
- android-support-v7-recyclerview \
- android-support-v7-palette \
- android-support-v4
-LOCAL_AAPT_FLAGS := --no-version-vectors
-include $(BUILD_PACKAGE)
diff --git a/samples/Support7Demos/res/layout/appcompat_widgets_buttons.xml b/samples/Support7Demos/res/layout/appcompat_widgets_buttons.xml
index 1c60d90..517f4fa 100644
--- a/samples/Support7Demos/res/layout/appcompat_widgets_buttons.xml
+++ b/samples/Support7Demos/res/layout/appcompat_widgets_buttons.xml
@@ -29,8 +29,25 @@
<android.support.v7.widget.SwitchCompat
android:layout_height="wrap_content"
android:layout_width="wrap_content"
+ android:text="SwitchCompat"/>
+
+ <android.support.v7.widget.SwitchCompat
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:enabled="false"
+ android:text="SwitchCompat disabled"/>
+
+ <Switch
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
android:text="Switch"/>
+ <Switch
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:enabled="false"
+ android:text="Switch disabled"/>
+
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/samples/Support7Demos/res/menu/actions.xml b/samples/Support7Demos/res/menu/actions.xml
index f3b0b85..d558365 100644
--- a/samples/Support7Demos/res/menu/actions.xml
+++ b/samples/Support7Demos/res/menu/actions.xml
@@ -18,21 +18,26 @@
<item android:id="@+id/action_search"
android:title="@string/action_bar_search"
android:icon="@drawable/ic_search"
+ android:alphabeticShortcut="s"
+ app:alphabeticModifiers="ALT"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView" />
<item android:id="@+id/action_add"
android:icon="@android:drawable/ic_menu_add"
android:title="@string/action_bar_add"
+ android:alphabeticShortcut="a"
app:contentDescription="@string/action_bar_add_description"
app:tooltipText="@string/action_bar_add_tooltip" />
<item android:id="@+id/action_edit"
android:icon="@android:drawable/ic_menu_edit"
android:title="@string/action_bar_edit"
+ android:alphabeticShortcut="e"
app:showAsAction="always" />
<item android:id="@+id/action_share"
android:icon="@android:drawable/ic_menu_share"
android:title="@string/action_bar_share"
android:enabled="false"
+ android:alphabeticShortcut="s"
app:showAsAction="ifRoom" />
<item android:id="@+id/action_sort"
android:icon="@android:drawable/ic_menu_sort_by_size"
@@ -41,10 +46,14 @@
<menu>
<item android:id="@+id/action_sort_size"
android:icon="@android:drawable/ic_menu_sort_by_size"
- android:title="@string/action_bar_sort_size" />
+ android:title="@string/action_bar_sort_size"
+ android:alphabeticShortcut="s"
+ app:alphabeticModifiers="CTRL|SHIFT" />
<item android:id="@+id/action_sort_alpha"
android:icon="@android:drawable/ic_menu_sort_alphabetically"
- android:title="@string/action_bar_sort_alpha" />
+ android:title="@string/action_bar_sort_alpha"
+ android:alphabeticShortcut="a"
+ app:alphabeticModifiers="CTRL|SHIFT" />
</menu>
</item>
</menu>
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarActionMode.java b/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarActionMode.java
index 6edf593..e263945 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarActionMode.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarActionMode.java
@@ -16,22 +16,16 @@
package com.example.android.supportv7.app;
-import com.example.android.supportv7.R;
-
-import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.view.ActionMode;
-import android.support.v7.widget.SearchView;
-import android.text.TextUtils;
import android.view.Menu;
-import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
-import android.widget.TextView;
import android.widget.Toast;
+import com.example.android.supportv7.R;
+
/**
* This demonstrates idiomatic usage of an action mode.
*/
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/app/AppCompatNightModeAlertDialog.java b/samples/Support7Demos/src/com/example/android/supportv7/app/AppCompatNightModeAlertDialog.java
index 276465b..91da0f4 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/app/AppCompatNightModeAlertDialog.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/app/AppCompatNightModeAlertDialog.java
@@ -15,16 +15,15 @@
*/
package com.example.android.supportv7.app;
-import com.example.android.supportv7.R;
-
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatDelegate;
-import android.support.v7.app.AppCompatDialog;
import android.view.View;
+import com.example.android.supportv7.R;
+
/**
* This demonstrates idiomatic usage of AlertDialog with Theme.AppCompat.DayNight
*/
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/app/AppCompatNightModeDialog.java b/samples/Support7Demos/src/com/example/android/supportv7/app/AppCompatNightModeDialog.java
index d923a92..7a0608e 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/app/AppCompatNightModeDialog.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/app/AppCompatNightModeDialog.java
@@ -15,21 +15,14 @@
*/
package com.example.android.supportv7.app;
-import com.example.android.supportv7.R;
-
-import android.app.Dialog;
-import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
-import android.support.v4.view.WindowCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.app.AppCompatDialog;
-import android.view.Menu;
-import android.view.MenuItem;
import android.view.View;
-import android.widget.Spinner;
-import android.widget.Toast;
+
+import com.example.android.supportv7.R;
/**
* This demonstrates idiomatic usage of Dialog with Theme.AppCompat.DayNight
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/app/DialogFragmentUsage.java b/samples/Support7Demos/src/com/example/android/supportv7/app/DialogFragmentUsage.java
index f44a0df..4661a06 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/app/DialogFragmentUsage.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/app/DialogFragmentUsage.java
@@ -15,13 +15,8 @@
*/
package com.example.android.supportv7.app;
-import com.example.android.supportv7.R;
-
-import android.app.Dialog;
-import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
-import android.support.v4.view.WindowCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatDialog;
import android.support.v7.app.AppCompatDialogFragment;
@@ -34,6 +29,8 @@
import android.widget.Spinner;
import android.widget.Toast;
+import com.example.android.supportv7.R;
+
/**
* This demonstrates idiomatic usage of AppCompatDialogFragment.
*/
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/app/DialogUsage.java b/samples/Support7Demos/src/com/example/android/supportv7/app/DialogUsage.java
index ea1a07d..e2d770b 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/app/DialogUsage.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/app/DialogUsage.java
@@ -15,12 +15,9 @@
*/
package com.example.android.supportv7.app;
-import com.example.android.supportv7.R;
-
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
-import android.support.v4.view.WindowCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.AppCompatDialog;
import android.view.Menu;
@@ -29,6 +26,8 @@
import android.widget.Spinner;
import android.widget.Toast;
+import com.example.android.supportv7.R;
+
/**
* This demonstrates idiomatic usage of AppCompatDialog.
*/
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/BaseLayoutManagerActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/BaseLayoutManagerActivity.java
index a4c01d1..28d7860 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/widget/BaseLayoutManagerActivity.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/BaseLayoutManagerActivity.java
@@ -16,14 +16,7 @@
package com.example.android.supportv7.widget;
-import com.example.android.supportv7.Cheeses;
-import com.example.android.supportv7.R;
-import com.example.android.supportv7.widget.adapter.SimpleStringAdapter;
-import com.example.android.supportv7.widget.util.ConfigToggle;
-import com.example.android.supportv7.widget.util.ConfigViewHolder;
-
import android.app.Activity;
-import android.content.Context;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
@@ -33,11 +26,16 @@
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
-import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
+import com.example.android.supportv7.Cheeses;
+import com.example.android.supportv7.R;
+import com.example.android.supportv7.widget.adapter.SimpleStringAdapter;
+import com.example.android.supportv7.widget.util.ConfigToggle;
+import com.example.android.supportv7.widget.util.ConfigViewHolder;
+
/**
* A simple activity that can be extended to demonstrate LayoutManagers.
* <p>
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/StableIdActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/StableIdActivity.java
index 70216f5..a538408 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/widget/StableIdActivity.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/StableIdActivity.java
@@ -117,7 +117,7 @@
final int pos = viewHolder.getAdapterPosition();
if (pos != RecyclerView.NO_POSITION) {
// swap item to top, and notify data set changed
- Pair d = mData.remove(pos);
+ Pair<Integer, String> d = mData.remove(pos);
mData.add(0, d);
notifyDataSetChanged();
diff --git a/samples/SupportAnimationDemos/AndroidManifest.xml b/samples/SupportAnimationDemos/AndroidManifest.xml
new file mode 100644
index 0000000..25e5ec8
--- /dev/null
+++ b/samples/SupportAnimationDemos/AndroidManifest.xml
@@ -0,0 +1,48 @@
+<?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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.support.animation">
+
+ <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="25" />
+
+ <application android:label="@string/activity_sample_code"
+ android:supportsRtl="true"
+ android:icon="@drawable/app_sample_code"
+ android:theme="@style/android:Theme.Holo.Light">
+ <activity android:name=".MainActivity"
+ android:label="ChainedSpringDemo">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.SAMPLE_CODE" />
+ </intent-filter>
+ </activity>
+ <activity android:name=".BrowseActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity android:name=".SpringActivity"
+ android:label="SpringDemo">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.SAMPLE_CODE" />
+ </intent-filter>
+ </activity>
+
+ </application>
+</manifest>
diff --git a/samples/SupportAnimationDemos/build.gradle b/samples/SupportAnimationDemos/build.gradle
new file mode 100644
index 0000000..dd3e350
--- /dev/null
+++ b/samples/SupportAnimationDemos/build.gradle
@@ -0,0 +1,30 @@
+apply plugin: 'com.android.application'
+
+dependencies {
+ compile project(':support-dynamic-animation')
+}
+
+android {
+ compileSdkVersion project.ext.currentSdk
+
+ defaultConfig {
+ minSdkVersion 16
+ }
+
+ sourceSets {
+ main.manifest.srcFile 'AndroidManifest.xml'
+ main.java.srcDirs = ['src']
+ main.aidl.srcDirs = ['src']
+ main.res.srcDirs = ['res']
+ }
+
+ lintOptions {
+ abortOnError true
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
+}
+
diff --git a/samples/SupportAnimationDemos/res/drawable-hdpi/app_sample_code.png b/samples/SupportAnimationDemos/res/drawable-hdpi/app_sample_code.png
new file mode 100755
index 0000000..66a1984
--- /dev/null
+++ b/samples/SupportAnimationDemos/res/drawable-hdpi/app_sample_code.png
Binary files differ
diff --git a/samples/SupportAnimationDemos/res/drawable-mdpi/app_sample_code.png b/samples/SupportAnimationDemos/res/drawable-mdpi/app_sample_code.png
new file mode 100644
index 0000000..5ae7701
--- /dev/null
+++ b/samples/SupportAnimationDemos/res/drawable-mdpi/app_sample_code.png
Binary files differ
diff --git a/dynamic-animation/AndroidManifest-make.xml b/samples/SupportAnimationDemos/res/drawable/circle.xml
similarity index 68%
copy from dynamic-animation/AndroidManifest-make.xml
copy to samples/SupportAnimationDemos/res/drawable/circle.xml
index bfe97cc..a343f54 100644
--- a/dynamic-animation/AndroidManifest-make.xml
+++ b/samples/SupportAnimationDemos/res/drawable/circle.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!--
+ 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.
@@ -13,7 +14,11 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.support.dynamicanimation">
- <uses-sdk android:minSdkVersion="16"/>
-</manifest>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <size
+ android:width="40dp"
+ android:height="40dp"/>
+ <solid
+ android:color="#2E7D32"/>
+</shape>
\ No newline at end of file
diff --git a/dynamic-animation/AndroidManifest-make.xml b/samples/SupportAnimationDemos/res/drawable/green_circle.xml
similarity index 68%
copy from dynamic-animation/AndroidManifest-make.xml
copy to samples/SupportAnimationDemos/res/drawable/green_circle.xml
index bfe97cc..833fc9e 100644
--- a/dynamic-animation/AndroidManifest-make.xml
+++ b/samples/SupportAnimationDemos/res/drawable/green_circle.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!--
+ 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.
@@ -13,7 +14,11 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.support.dynamicanimation">
- <uses-sdk android:minSdkVersion="16"/>
-</manifest>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <size
+ android:width="40dp"
+ android:height="40dp"/>
+ <solid
+ android:color="#4CAF50"/>
+</shape>
diff --git a/dynamic-animation/AndroidManifest-make.xml b/samples/SupportAnimationDemos/res/drawable/light_green_circle.xml
similarity index 68%
copy from dynamic-animation/AndroidManifest-make.xml
copy to samples/SupportAnimationDemos/res/drawable/light_green_circle.xml
index bfe97cc..c181576 100644
--- a/dynamic-animation/AndroidManifest-make.xml
+++ b/samples/SupportAnimationDemos/res/drawable/light_green_circle.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!--
+ 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.
@@ -13,7 +14,11 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.support.dynamicanimation">
- <uses-sdk android:minSdkVersion="16"/>
-</manifest>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <size
+ android:width="40dp"
+ android:height="40dp"/>
+ <solid
+ android:color="#A5D6A7"/>
+</shape>
diff --git a/dynamic-animation/AndroidManifest-make.xml b/samples/SupportAnimationDemos/res/drawable/spring_demo_circle.xml
similarity index 65%
copy from dynamic-animation/AndroidManifest-make.xml
copy to samples/SupportAnimationDemos/res/drawable/spring_demo_circle.xml
index bfe97cc..d370267 100644
--- a/dynamic-animation/AndroidManifest-make.xml
+++ b/samples/SupportAnimationDemos/res/drawable/spring_demo_circle.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!--
+ 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.
@@ -13,7 +14,11 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.support.dynamicanimation">
- <uses-sdk android:minSdkVersion="16"/>
-</manifest>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <size
+ android:width="40dp"
+ android:height="40dp"/>
+ <solid
+ android:color="@android:color/holo_green_light"></solid>
+</shape>
\ No newline at end of file
diff --git a/samples/SupportAnimationDemos/res/layout/activity_chained_springs.xml b/samples/SupportAnimationDemos/res/layout/activity_chained_springs.xml
new file mode 100644
index 0000000..ff8a7f7
--- /dev/null
+++ b/samples/SupportAnimationDemos/res/layout/activity_chained_springs.xml
@@ -0,0 +1,100 @@
+<?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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent" android:layout_height="match_parent">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="50dp"
+ android:layout_gravity="bottom"
+ android:layout_marginBottom="50dp"
+ android:orientation="horizontal">
+ <LinearLayout
+ android:layout_width="100dp"
+ android:layout_height="match_parent"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Damping Ratio:"/>
+ <TextView
+ android:id="@+id/damping_ratio_txt"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"/>
+ </LinearLayout>
+ <SeekBar
+ android:id="@+id/damping_ratio"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"/>
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="50dp"
+ android:layout_gravity="bottom"
+ android:orientation="horizontal">
+ <LinearLayout
+ android:layout_width="100dp"
+ android:layout_height="match_parent"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Stiffness:"/>
+ <TextView
+ android:id="@+id/stiffness_txt"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"/>
+ </LinearLayout>
+ <SeekBar
+ android:id="@+id/stiffness"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"/>
+ </LinearLayout>
+ <LinearLayout
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+ <TextView
+ android:id="@+id/lead"
+ android:layout_width="60dp"
+ android:layout_height="60dp"
+ android:layout_margin="20dp"
+ android:background="@drawable/circle"
+ android:gravity="center"
+ android:text="Drag\n Me"
+ android:textColor="#FFFFAD"/>
+ <ImageView
+ android:id="@+id/follow1"
+ android:layout_width="60dp"
+ android:layout_height="60dp"
+ android:layout_margin="20dp"
+ android:src="@drawable/green_circle"/>
+ <ImageView
+ android:id="@+id/follow2"
+ android:layout_width="60dp"
+ android:layout_height="60dp"
+ android:layout_margin="20dp"
+ android:src="@drawable/light_green_circle"/>
+ </LinearLayout>
+</FrameLayout>
\ No newline at end of file
diff --git a/samples/SupportAnimationDemos/res/layout/activity_main.xml b/samples/SupportAnimationDemos/res/layout/activity_main.xml
new file mode 100644
index 0000000..4e8d9b4
--- /dev/null
+++ b/samples/SupportAnimationDemos/res/layout/activity_main.xml
@@ -0,0 +1,104 @@
+<?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.
+-->
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/activity_main"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ tools:context="com.example.android.support.animation.SpringActivity">
+
+ <FrameLayout
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <com.example.android.support.animation.SpringView
+ android:id="@+id/actual_spring"
+ android:layout_width="100dp"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_horizontal"/>
+ <ImageView
+ android:id="@+id/imageView"
+ android:layout_width="100dp"
+ android:layout_height="100dp"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginTop="50dp"
+ android:src="@drawable/spring_demo_circle"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="50dp"
+ android:layout_gravity="bottom"
+ android:layout_marginBottom="50dp"
+ android:orientation="horizontal">
+ <LinearLayout
+ android:layout_width="100dp"
+ android:layout_height="match_parent"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Damping Ratio:"/>
+ <TextView
+ android:id="@+id/damping_ratio_txt"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"/>
+ </LinearLayout>
+ <SeekBar
+ android:id="@+id/damping_ratio"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"/>
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="50dp"
+ android:layout_gravity="bottom"
+ android:orientation="horizontal">
+ <LinearLayout
+ android:layout_width="100dp"
+ android:layout_height="match_parent"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Stiffness:"/>
+ <TextView
+ android:id="@+id/stiffness_txt"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"/>
+ </LinearLayout>
+ <SeekBar
+ android:id="@+id/stiffness"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"/>
+ </LinearLayout>
+
+ </FrameLayout>
+</RelativeLayout>
diff --git a/samples/SupportAnimationDemos/res/values-w820dp/dimens.xml b/samples/SupportAnimationDemos/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..3ef1782
--- /dev/null
+++ b/samples/SupportAnimationDemos/res/values-w820dp/dimens.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+<resources>
+ <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+ (such as screen margins) for screens with more than 820dp of available width. This
+ would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+ <dimen name="activity_horizontal_margin">64dp</dimen>
+</resources>
diff --git a/dynamic-animation/AndroidManifest-make.xml b/samples/SupportAnimationDemos/res/values/colors.xml
similarity index 71%
copy from dynamic-animation/AndroidManifest-make.xml
copy to samples/SupportAnimationDemos/res/values/colors.xml
index bfe97cc..7141433 100644
--- a/dynamic-animation/AndroidManifest-make.xml
+++ b/samples/SupportAnimationDemos/res/values/colors.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!--
+ 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.
@@ -13,7 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.support.dynamicanimation">
- <uses-sdk android:minSdkVersion="16"/>
-</manifest>
+<resources>
+ <color name="springColor">#ff0099cc</color>
+</resources>
diff --git a/dynamic-animation/AndroidManifest-make.xml b/samples/SupportAnimationDemos/res/values/dimens.xml
similarity index 68%
copy from dynamic-animation/AndroidManifest-make.xml
copy to samples/SupportAnimationDemos/res/values/dimens.xml
index bfe97cc..f5b011c 100644
--- a/dynamic-animation/AndroidManifest-make.xml
+++ b/samples/SupportAnimationDemos/res/values/dimens.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!--
+ 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.
@@ -13,7 +14,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.support.dynamicanimation">
- <uses-sdk android:minSdkVersion="16"/>
-</manifest>
+<resources>
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/dynamic-animation/AndroidManifest-make.xml b/samples/SupportAnimationDemos/res/values/strings.xml
similarity index 71%
copy from dynamic-animation/AndroidManifest-make.xml
copy to samples/SupportAnimationDemos/res/values/strings.xml
index bfe97cc..3412861 100644
--- a/dynamic-animation/AndroidManifest-make.xml
+++ b/samples/SupportAnimationDemos/res/values/strings.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!--
+ 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.
@@ -13,7 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.support.dynamicanimation">
- <uses-sdk android:minSdkVersion="16"/>
-</manifest>
+<resources>
+ <string name="activity_sample_code">Support Animation Demos</string>
+</resources>
diff --git a/samples/SupportAnimationDemos/src/com/example/android/support/animation/BrowseActivity.java b/samples/SupportAnimationDemos/src/com/example/android/support/animation/BrowseActivity.java
new file mode 100644
index 0000000..e330302
--- /dev/null
+++ b/samples/SupportAnimationDemos/src/com/example/android/support/animation/BrowseActivity.java
@@ -0,0 +1,154 @@
+/*
+ * 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.animation;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This activity lists all the activities in this application.
+ */
+public class BrowseActivity extends ListActivity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Intent intent = getIntent();
+ String path = intent.getStringExtra("com.example.android.support.animation");
+
+ if (path == null) {
+ path = "";
+ }
+
+ setListAdapter(new SimpleAdapter(this, getData(path),
+ android.R.layout.simple_list_item_1, new String[] { "title" },
+ new int[] { android.R.id.text1 }));
+ getListView().setTextFilterEnabled(true);
+ }
+
+ protected List<Map<String, Object>> getData(String prefix) {
+ List<Map<String, Object>> myData = new ArrayList<Map<String, Object>>();
+
+ Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+ mainIntent.addCategory(Intent.CATEGORY_SAMPLE_CODE);
+
+ PackageManager pm = getPackageManager();
+ List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
+
+ if (null == list) {
+ return myData;
+ }
+
+ String[] prefixPath;
+ String prefixWithSlash = prefix;
+
+ if (prefix.equals("")) {
+ prefixPath = null;
+ } else {
+ prefixPath = prefix.split("/");
+ prefixWithSlash = prefix + "/";
+ }
+
+ int len = list.size();
+
+ Map<String, Boolean> entries = new HashMap<String, Boolean>();
+
+ for (int i = 0; i < len; i++) {
+ ResolveInfo info = list.get(i);
+ CharSequence labelSeq = info.loadLabel(pm);
+ String label = labelSeq != null ? labelSeq.toString() : info.activityInfo.name;
+
+ if (prefixWithSlash.length() == 0 || label.startsWith(prefixWithSlash)) {
+
+ String[] labelPath = label.split("/");
+
+ String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length];
+
+ if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) {
+ addItem(myData, nextLabel, activityIntent(
+ info.activityInfo.applicationInfo.packageName,
+ info.activityInfo.name));
+ } else {
+ if (entries.get(nextLabel) == null) {
+ addItem(myData, nextLabel, browseIntent(prefix.equals("")
+ ? nextLabel : prefix + "/" + nextLabel));
+ entries.put(nextLabel, true);
+ }
+ }
+ }
+ }
+
+ Collections.sort(myData, sDisplayNameComparator);
+ return myData;
+ }
+
+ private static final Comparator<Map<String, Object>> sDisplayNameComparator =
+ new Comparator<Map<String, Object>>() {
+ public final Collator collator = Collator.getInstance();
+
+ public int compare(Map<String, Object> map1, Map<String, Object> map2) {
+ return collator.compare(map1.get("title"), map2.get("title"));
+ }
+ };
+
+ protected Intent activityIntent(String pkg, String componentName) {
+ Intent result = new Intent();
+ result.setClassName(pkg, componentName);
+ return result;
+ }
+
+ protected Intent browseIntent(String path) {
+ Intent result = new Intent();
+ result.setClass(this, BrowseActivity.class);
+ result.putExtra("com.example.android.support.animation", path);
+ return result;
+ }
+
+ protected void addItem(List<Map<String, Object>> data, String name, Intent intent) {
+ Map<String, Object> temp = new HashMap<String, Object>();
+ temp.put("title", name);
+ temp.put("intent", intent);
+ data.add(temp);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ Map<String, Object> map = (Map<String, Object>) l.getItemAtPosition(position);
+
+ Intent intent = new Intent((Intent) map.get("intent"));
+ intent.addCategory(Intent.CATEGORY_SAMPLE_CODE);
+ startActivity(intent);
+ }
+}
+
+
diff --git a/samples/SupportAnimationDemos/src/com/example/android/support/animation/MainActivity.java b/samples/SupportAnimationDemos/src/com/example/android/support/animation/MainActivity.java
new file mode 100644
index 0000000..1ded677
--- /dev/null
+++ b/samples/SupportAnimationDemos/src/com/example/android/support/animation/MainActivity.java
@@ -0,0 +1,170 @@
+/*
+ * 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.animation;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.animation.DynamicAnimation;
+import android.support.animation.SpringAnimation;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+/**
+ * Activity for chained spring animations.
+ */
+public class MainActivity extends Activity {
+ private float mDampingRatio = 1.0f;
+ private float mStiffness = 50.0f;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_chained_springs);
+ final View lead = findViewById(R.id.lead);
+ final View follow1 = findViewById(R.id.follow1);
+ final View follow2 = findViewById(R.id.follow2);
+
+ final SpringAnimation anim1X = new SpringAnimation(follow1, DynamicAnimation.TRANSLATION_X,
+ lead.getTranslationX());
+ final SpringAnimation anim1Y = new SpringAnimation(follow1, DynamicAnimation.TRANSLATION_Y,
+ lead.getTranslationY());
+ final SpringAnimation anim2X = new SpringAnimation(follow2, DynamicAnimation.TRANSLATION_X,
+ follow1.getTranslationX());
+ final SpringAnimation anim2Y = new SpringAnimation(follow2, DynamicAnimation.TRANSLATION_Y,
+ follow1.getTranslationY());
+
+ anim1X.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {
+ @Override
+ public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
+ float velocity) {
+ anim2X.animateToFinalPosition(value);
+ }
+ });
+
+ anim1Y.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {
+ @Override
+ public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
+ float velocity) {
+ anim2Y.animateToFinalPosition(value);
+ }
+ });
+
+ ((View) lead.getParent()).setOnTouchListener(new View.OnTouchListener() {
+ public float firstDownX = 0;
+ public float firstDownY = 0;
+ public VelocityTracker tracker;
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ if (motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) {
+
+ if (motionEvent.getX() < lead.getX()
+ || motionEvent.getX() > lead.getX() + lead.getWidth()
+ || motionEvent.getY() < lead.getY()
+ || motionEvent.getY() > lead.getY() + lead.getHeight()) {
+ return false;
+ }
+
+ // Update the stiffness and damping ratio that are configured by user from the
+ // seekbar UI as needed.
+ anim1X.getSpring().setStiffness(mStiffness).setDampingRatio(mDampingRatio);
+ anim1Y.getSpring().setStiffness(mStiffness).setDampingRatio(mDampingRatio);
+ anim2X.getSpring().setStiffness(mStiffness).setDampingRatio(mDampingRatio);
+ anim2Y.getSpring().setStiffness(mStiffness).setDampingRatio(mDampingRatio);
+
+ firstDownX = motionEvent.getX() - lead.getTranslationX();
+ firstDownY = motionEvent.getY() - lead.getTranslationY();
+ tracker = VelocityTracker.obtain();
+ tracker.clear();
+ tracker.addMovement(motionEvent);
+ } else if (motionEvent.getActionMasked() == MotionEvent.ACTION_MOVE) {
+ float deltaX = motionEvent.getX() - firstDownX;
+ float deltaY = motionEvent.getY() - firstDownY;
+
+ // Directly manipulate the lead view.
+ lead.setTranslationX(deltaX);
+ lead.setTranslationY(deltaY);
+
+ // Animate the follow views to the new final position
+ anim1X.animateToFinalPosition(deltaX);
+ anim1Y.animateToFinalPosition(deltaY);
+
+ tracker.addMovement(motionEvent);
+ }
+ return true;
+ }
+ });
+ setupSeekBars();
+ }
+
+ // Setup seek bars so damping ratio and stiffness for the spring can be modified through the UI.
+ void setupSeekBars() {
+ SeekBar dr = (SeekBar) findViewById(R.id.damping_ratio);
+ dr.setMax(130);
+ final TextView drTxt = (TextView) findViewById(R.id.damping_ratio_txt);
+ dr.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
+ if (i < 80) {
+ mDampingRatio = i / 80.0f;
+ } else if (i > 90) {
+ mDampingRatio = (float) Math.exp((i - 90) / 10.0);
+ } else {
+ mDampingRatio = 1;
+ }
+ drTxt.setText(String.format("%.4f", (float) mDampingRatio));
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+
+ }
+ });
+
+ SeekBar stiff = (SeekBar) findViewById(R.id.stiffness);
+ stiff.setMax(110);
+ final TextView nfTxt = (TextView) findViewById(R.id.stiffness_txt);
+ stiff.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
+ float stiffness = (float) Math.exp(i / 10d);
+ mStiffness = stiffness;
+ nfTxt.setText(String.format("%.3f", (float) stiffness));
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+
+ }
+ });
+ dr.setProgress(80);
+ stiff.setProgress(60);
+
+ }
+}
diff --git a/samples/SupportAnimationDemos/src/com/example/android/support/animation/SpringActivity.java b/samples/SupportAnimationDemos/src/com/example/android/support/animation/SpringActivity.java
new file mode 100644
index 0000000..e9f2d62
--- /dev/null
+++ b/samples/SupportAnimationDemos/src/com/example/android/support/animation/SpringActivity.java
@@ -0,0 +1,154 @@
+/*
+ * 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.animation;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.animation.DynamicAnimation;
+import android.support.animation.SpringAnimation;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+/**
+ * This is a single spring animation. It provides a UI to interact with the spring, and two seek
+ * bars to tune the spring constants.
+ */
+public class SpringActivity extends Activity {
+ private float mDampingRatio;
+ private float mStiffness;
+ private SpringView mSpringView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ final View v = findViewById(R.id.container);
+ mSpringView = (SpringView) findViewById(R.id.actual_spring);
+
+ final View img = findViewById(R.id.imageView);
+ setupSeekBars();
+ final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y,
+ 0 /* final position */);
+ anim.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {
+ @Override
+ public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float v, float v1) {
+ // Update the drawing of the spring.
+ mSpringView.setMassHeight(img.getY());
+ }
+ });
+
+ ((View) img.getParent()).setOnTouchListener(new View.OnTouchListener() {
+ public float touchOffset;
+ public VelocityTracker vt;
+ @Override
+ public boolean onTouch(View v, MotionEvent motionEvent) {
+ if (motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) {
+ // check whether the touch happens inside of the img view.
+ boolean inside = motionEvent.getX() >= img.getX()
+ && motionEvent.getX() <= img.getX() + img.getWidth()
+ && motionEvent.getY() >= img.getY()
+ && motionEvent.getY() <= img.getY() + img.getHeight();
+
+ anim.cancel();
+
+ if (!inside) {
+ return false;
+ }
+ // Apply this offset to all the subsequent events
+ touchOffset = img.getTranslationY() - motionEvent.getY();
+ vt = VelocityTracker.obtain();
+ vt.clear();
+ }
+
+ vt.addMovement(motionEvent);
+
+ if (motionEvent.getActionMasked() == MotionEvent.ACTION_MOVE) {
+ img.setTranslationY(motionEvent.getY() + touchOffset);
+ // Updates the drawing of the spring.
+ mSpringView.setMassHeight(img.getY());
+ } else if (motionEvent.getActionMasked() == MotionEvent.ACTION_CANCEL
+ || motionEvent.getActionMasked() == MotionEvent.ACTION_UP) {
+ // Compute the velocity in unit: pixel/second
+ vt.computeCurrentVelocity(1000);
+ float velocity = vt.getYVelocity();
+ anim.getSpring().setDampingRatio(mDampingRatio).setStiffness(mStiffness);
+ anim.setStartVelocity(velocity).start();
+ vt.recycle();
+ }
+ return true;
+ }
+ });
+ }
+
+ // Setup seek bars so damping ratio and stiffness for the spring can be modified through the UI.
+ void setupSeekBars() {
+ SeekBar dr = (SeekBar) findViewById(R.id.damping_ratio);
+ dr.setMax(130);
+ final TextView drTxt = (TextView) findViewById(R.id.damping_ratio_txt);
+ dr.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
+ if (i < 80) {
+ mDampingRatio = i / 80.0f;
+ } else if (i > 90) {
+ mDampingRatio = (float) Math.exp((i - 90) / 10.0);
+ } else {
+ mDampingRatio = 1;
+ }
+ drTxt.setText(String.format("%.4f", (float) mDampingRatio));
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+
+ }
+ });
+
+ SeekBar stiff = (SeekBar) findViewById(R.id.stiffness);
+ stiff.setMax(110);
+ final TextView nfTxt = (TextView) findViewById(R.id.stiffness_txt);
+ stiff.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
+ float stiffness = (float) Math.exp(i / 10d);
+ mStiffness = stiffness;
+ nfTxt.setText(String.format("%.3f", (float) stiffness));
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+
+ }
+ });
+ dr.setProgress(40);
+ stiff.setProgress(60);
+ }
+}
diff --git a/samples/SupportAnimationDemos/src/com/example/android/support/animation/SpringView.java b/samples/SupportAnimationDemos/src/com/example/android/support/animation/SpringView.java
new file mode 100644
index 0000000..14a0fd0
--- /dev/null
+++ b/samples/SupportAnimationDemos/src/com/example/android/support/animation/SpringView.java
@@ -0,0 +1,70 @@
+/*
+ * 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.animation;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.view.View;
+
+/**
+ * The view that draws the spring as it reacts (i.e. expands/compresses) to the user touch.
+ */
+public class SpringView extends View {
+ final Paint mPaint = new Paint();
+ private float mLastHeight = 175;
+
+ public SpringView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setWillNotDraw(false);
+ mPaint.setColor(context.getResources().getColor(R.color.springColor));
+ mPaint.setStrokeWidth(10);
+ }
+
+ /**
+ * Sets the other end of the spring.
+ *
+ * @param height height of the mass, which is used to derive how to draw the spring
+ */
+ public void setMassHeight(float height) {
+ mLastHeight = height;
+ invalidate();
+ }
+
+ @Override
+ public void onDraw(Canvas canvas) {
+ // Draws the spring
+ // 30px long, 15 sections
+ int num = 20;
+ float sectionLen = 150; // px
+ final float x = canvas.getWidth() / 2;
+ float y = 0;
+ float sectionHeight = mLastHeight / num;
+ float sectionWidth = (float) Math.sqrt(sectionLen * sectionLen
+ - sectionHeight * sectionHeight);
+ canvas.drawLine(x, 0, x + sectionWidth / 2, sectionHeight / 2, mPaint);
+ float lastX = x + sectionWidth / 2;
+ float lastY = sectionHeight / 2;
+ for (int i = 1; i < num; i++) {
+ canvas.drawLine(lastX, lastY, 2 * x - lastX, lastY + sectionHeight, mPaint);
+ lastX = 2 * x - lastX;
+ lastY = lastY + sectionHeight;
+ }
+ canvas.drawLine(lastX, lastY, x, mLastHeight, mPaint);
+ }
+}
diff --git a/samples/SupportAppNavigation/Android.mk b/samples/SupportAppNavigation/Android.mk
deleted file mode 100644
index ea9322f..0000000
--- a/samples/SupportAppNavigation/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_USE_AAPT2 := true
-
-LOCAL_MODULE_TAGS := samples tests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := SupportAppNavigation
-
-LOCAL_STATIC_ANDROID_LIBRARIES += android-support-v4
-
-LOCAL_SDK_VERSION := current
-
-LOCAL_MIN_SDK_VERSION := 8
-
-LOCAL_DEX_PREOPT := false
-
-include $(BUILD_PACKAGE)
-
-LOCAL_PROGUARD_FLAG_FILES := proguard.flags
-
-# Use the following include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/SupportAppNavigation/build.gradle b/samples/SupportAppNavigation/build.gradle
new file mode 100644
index 0000000..fdbad1b
--- /dev/null
+++ b/samples/SupportAppNavigation/build.gradle
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+apply plugin: 'com.android.application'
+
+dependencies {
+ compile project(':support-v4')
+}
+
+android {
+ compileSdkVersion project.ext.currentSdk
+
+ defaultConfig {
+ minSdkVersion 14
+ }
+
+ sourceSets {
+ main.manifest.srcFile 'AndroidManifest.xml'
+ main.java.srcDirs = ['src']
+ main.res.srcDirs = ['res']
+ }
+
+ lintOptions {
+ abortOnError true
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ targetCompatibility JavaVersion.VERSION_1_7
+ }
+}
diff --git a/samples/SupportDesignDemos/Android.mk b/samples/SupportDesignDemos/Android.mk
deleted file mode 100644
index 4c74ad2..0000000
--- a/samples/SupportDesignDemos/Android.mk
+++ /dev/null
@@ -1,36 +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.
-
-LOCAL_PATH:= $(call my-dir)
-
-# Build the samples.
-# We need to add some special AAPT flags to generate R classes
-# for resources that are included from the libraries.
-include $(CLEAR_VARS)
-LOCAL_USE_AAPT2 := true
-LOCAL_PACKAGE_NAME := SupportDesignDemos
-LOCAL_MODULE_TAGS := samples
-LOCAL_SDK_VERSION := current
-LOCAL_MIN_SDK_VERSION := 7
-LOCAL_DEX_PREOPT := false
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_ANDROID_LIBRARIES := \
- android-support-v4 \
- android-support-v7-appcompat \
- android-support-v7-recyclerview \
- android-support-transition \
- android-support-design
-LOCAL_AAPT_FLAGS := --no-version-vectors
-LOCAL_PROGUARD_FLAG_FILES := proguard.flags
-include $(BUILD_PACKAGE)
diff --git a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/SimpleStringRecyclerViewAdapter.java b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/SimpleStringRecyclerViewAdapter.java
index 2f9b79f..3bd06f3 100644
--- a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/SimpleStringRecyclerViewAdapter.java
+++ b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/SimpleStringRecyclerViewAdapter.java
@@ -16,17 +16,15 @@
package com.example.android.support.design.widget;
-import com.example.android.support.design.R;
-
import android.content.Context;
-import android.graphics.Color;
import android.support.v7.widget.RecyclerView;
-import android.text.Layout;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;
+import com.example.android.support.design.R;
+
import java.util.ArrayList;
import java.util.Collections;
diff --git a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/SnackbarWithFloatingActionButton.java b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/SnackbarWithFloatingActionButton.java
index 1b79543..14df2b1 100644
--- a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/SnackbarWithFloatingActionButton.java
+++ b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/SnackbarWithFloatingActionButton.java
@@ -18,12 +18,6 @@
import com.example.android.support.design.R;
-import android.os.Bundle;
-import android.support.design.widget.Snackbar;
-import android.support.v7.app.AppCompatActivity;
-import android.view.View;
-import android.view.ViewGroup;
-
/**
* This demonstrates idiomatic usage of Snackbar with a Floating Action Button present
*/
diff --git a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/TabLayoutLayoutItemsUsage.java b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/TabLayoutLayoutItemsUsage.java
index 7e51de3..ba38f3e 100644
--- a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/TabLayoutLayoutItemsUsage.java
+++ b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/TabLayoutLayoutItemsUsage.java
@@ -16,24 +16,11 @@
package com.example.android.support.design.widget;
-import com.example.android.support.design.Cheeses;
-import com.example.android.support.design.R;
-
import android.os.Bundle;
-import android.support.design.widget.TabLayout;
-import android.support.v4.view.PagerAdapter;
-import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.RadioButton;
-import android.widget.RadioGroup;
-import android.widget.TextView;
-import java.util.ArrayList;
-import java.util.Random;
+import com.example.android.support.design.R;
/**
* This demonstrates idiomatic usage of TabLayout with items inflated from the layout
diff --git a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/TabLayoutPreselectedUsage.java b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/TabLayoutPreselectedUsage.java
index 12e1842..b276305 100644
--- a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/TabLayoutPreselectedUsage.java
+++ b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/TabLayoutPreselectedUsage.java
@@ -29,11 +29,11 @@
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
+
import com.example.android.support.design.Cheeses;
import com.example.android.support.design.R;
import java.util.ArrayList;
-import java.util.Random;
/**
* This demonstrates idiomatic usage of TabLayout with a ViewPager
diff --git a/samples/SupportLeanbackDemos/Android.mk b/samples/SupportLeanbackDemos/Android.mk
deleted file mode 100644
index 5a8d110..0000000
--- a/samples/SupportLeanbackDemos/Android.mk
+++ /dev/null
@@ -1,39 +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.
-
-LOCAL_PATH:= $(call my-dir)
-
-# Build the samples.
-# We need to add some special AAPT flags to generate R classes
-# for resources that are included from the libraries.
-include $(CLEAR_VARS)
-LOCAL_USE_AAPT2 := true
-LOCAL_PACKAGE_NAME := SupportLeanbackDemos
-LOCAL_MODULE_TAGS := samples tests
-LOCAL_SDK_VERSION := current
-LOCAL_MIN_SDK_VERSION := 17
-LOCAL_DEX_PREOPT := false
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_ANDROID_LIBRARIES := \
- android-support-compat \
- android-support-core-ui \
- android-support-media-compat \
- android-support-fragment \
- android-support-v7-recyclerview \
- android-support-v17-leanback \
- android-support-v17-preference-leanback \
- android-support-v7-preference \
- android-support-v14-preference
-
-include $(BUILD_PACKAGE)
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseFragment.java
index 2f0e861..7b3f8f7 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseFragment.java
@@ -14,7 +14,6 @@
package com.example.android.leanback;
import android.app.Fragment;
-import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseSupportFragment.java
index c78319d..395c498 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseSupportFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/BrowseSupportFragment.java
@@ -17,7 +17,6 @@
package com.example.android.leanback;
import android.support.v4.app.Fragment;
-import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsDescriptionPresenter.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsDescriptionPresenter.java
index 6d376f0..57eae06 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsDescriptionPresenter.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsDescriptionPresenter.java
@@ -14,7 +14,6 @@
package com.example.android.leanback;
import android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter;
-import android.support.v17.leanback.widget.DetailsOverviewRow;
public class DetailsDescriptionPresenter extends AbstractDetailsDescriptionPresenter {
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java
index 3807de1..6d4deb0 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java
@@ -230,6 +230,10 @@
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
+ final Context context = getActivity();
+ if (context == null) {
+ return;
+ }
if (TEST_OVERVIEW_ROW_ON_SECOND) {
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1));
@@ -240,7 +244,6 @@
mRowsAdapter.add(0, new ListRow(header, listRowAdapter));
}
- final Context context = getActivity();
DetailsOverviewRow dor = new DetailsOverviewRow(mPhotoItem.getTitle());
dor.setImageDrawable(ResourcesCompat.getDrawable(context.getResources(),
mPhotoItem.getImageResourceId(), context.getTheme()));
@@ -262,6 +265,9 @@
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
+ if (getActivity() == null) {
+ return;
+ }
for (int i = 0; i < NUM_ROWS; ++i) {
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1));
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java
index 697b1e0..6c14029 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java
@@ -233,6 +233,10 @@
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
+ final Context context = getActivity();
+ if (context == null) {
+ return;
+ }
if (TEST_OVERVIEW_ROW_ON_SECOND) {
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1));
@@ -243,7 +247,6 @@
mRowsAdapter.add(0, new ListRow(header, listRowAdapter));
}
- final Context context = getActivity();
DetailsOverviewRow dor = new DetailsOverviewRow(mPhotoItem.getTitle());
dor.setImageDrawable(ResourcesCompat.getDrawable(context.getResources(),
mPhotoItem.getImageResourceId(), context.getTheme()));
@@ -265,6 +268,9 @@
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
+ if (getActivity() == null) {
+ return;
+ }
for (int i = 0; i < NUM_ROWS; ++i) {
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1));
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/OnboardingActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/OnboardingActivity.java
index 2fe9bb9..a30a3fd 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/OnboardingActivity.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/OnboardingActivity.java
@@ -15,7 +15,6 @@
import android.app.Activity;
import android.os.Bundle;
-import android.view.ViewTreeObserver;
public class OnboardingActivity extends Activity {
@Override
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/OnboardingSupportActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/OnboardingSupportActivity.java
index f0a2275..177eced 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/OnboardingSupportActivity.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/OnboardingSupportActivity.java
@@ -18,7 +18,6 @@
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
-import android.view.ViewTreeObserver;
public class OnboardingSupportActivity extends FragmentActivity {
@Override
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackFragment.java
index 2687d70..aeab26d 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackFragment.java
@@ -22,12 +22,10 @@
import android.support.v17.leanback.app.PlaybackFragmentGlueHost;
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.PlaybackControlsRow;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.PresenterSelector;
import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
import android.util.Log;
@@ -57,7 +55,6 @@
private static final int ROW_CONTROLS = 0;
private PlaybackControlGlue mGlue;
- private ListRowPresenter mListRowPresenter;
@Override
public SparseArrayObjectAdapter getAdapter() {
@@ -104,22 +101,10 @@
};
mGlue.setHost(new PlaybackFragmentGlueHost(this));
- mListRowPresenter = new ListRowPresenter();
+ ClassPresenterSelector classPresenterSelector = new ClassPresenterSelector();
+ classPresenterSelector.addClassPresenter(ListRow.class, new ListRowPresenter());
- setAdapter(new SparseArrayObjectAdapter(new PresenterSelector() {
- @Override
- public Presenter getPresenter(Object object) {
- if (object instanceof PlaybackControlsRow) {
- return mGlue.getControlsRowPresenter();
- } else if (object instanceof ListRow) {
- return mListRowPresenter;
- }
- throw new IllegalArgumentException("Unhandled object: " + object);
- }
- }));
-
- // Add the controls row
- getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
+ setAdapter(new SparseArrayObjectAdapter(classPresenterSelector));
// Add related content rows
for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
index 21086d9..87b5983 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
@@ -19,6 +19,7 @@
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;
@@ -27,7 +28,6 @@
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;
@@ -56,8 +56,6 @@
private static final int ROW_CONTROLS = 0;
private PlaybackControlHelper mGlue;
- private PlaybackControlsRowPresenter mPlaybackControlsRowPresenter;
- private ListRowPresenter mListRowPresenter;
final Handler mHandler = new Handler();
// Artificial delay to simulate a media being prepared. The onRowChanged callback should be
@@ -143,21 +141,14 @@
}, MEDIA_PREPARATION_DELAY);
mGlue.setOnItemViewClickedListener(mOnItemViewClickedListener);
- mPlaybackControlsRowPresenter = mGlue.createControlsRowAndPresenter();
- mPlaybackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
- mListRowPresenter = new ListRowPresenter();
+ 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(new PresenterSelector() {
- @Override
- public Presenter getPresenter(Object object) {
- if (object instanceof PlaybackControlsRow) {
- return mPlaybackControlsRowPresenter;
- } else if (object instanceof ListRow) {
- return mListRowPresenter;
- }
- throw new IllegalArgumentException("Unhandled object: " + object);
- }
- }));
+ setAdapter(new SparseArrayObjectAdapter(selector));
// Add the controls row
getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java
index 879ee69..7e5e8f9 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java
@@ -22,6 +22,7 @@
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;
@@ -30,7 +31,6 @@
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;
@@ -59,8 +59,6 @@
private static final int ROW_CONTROLS = 0;
private PlaybackControlSupportHelper mGlue;
- private PlaybackControlsRowPresenter mPlaybackControlsRowPresenter;
- private ListRowPresenter mListRowPresenter;
final Handler mHandler = new Handler();
// Artificial delay to simulate a media being prepared. The onRowChanged callback should be
@@ -146,21 +144,14 @@
}, MEDIA_PREPARATION_DELAY);
mGlue.setOnItemViewClickedListener(mOnItemViewClickedListener);
- mPlaybackControlsRowPresenter = mGlue.createControlsRowAndPresenter();
- mPlaybackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
- mListRowPresenter = new ListRowPresenter();
+ 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(new PresenterSelector() {
- @Override
- public Presenter getPresenter(Object object) {
- if (object instanceof PlaybackControlsRow) {
- return mPlaybackControlsRowPresenter;
- } else if (object instanceof ListRow) {
- return mListRowPresenter;
- }
- throw new IllegalArgumentException("Unhandled object: " + object);
- }
- }));
+ setAdapter(new SparseArrayObjectAdapter(selector));
// Add the controls row
getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackSupportFragment.java
index d83f917..4315a05 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackSupportFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackSupportFragment.java
@@ -25,12 +25,10 @@
import android.support.v17.leanback.app.PlaybackSupportFragmentGlueHost;
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.PlaybackControlsRow;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.PresenterSelector;
import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
import android.util.Log;
@@ -60,7 +58,6 @@
private static final int ROW_CONTROLS = 0;
private PlaybackControlGlue mGlue;
- private ListRowPresenter mListRowPresenter;
@Override
public SparseArrayObjectAdapter getAdapter() {
@@ -107,22 +104,10 @@
};
mGlue.setHost(new PlaybackSupportFragmentGlueHost(this));
- mListRowPresenter = new ListRowPresenter();
+ ClassPresenterSelector classPresenterSelector = new ClassPresenterSelector();
+ classPresenterSelector.addClassPresenter(ListRow.class, new ListRowPresenter());
- setAdapter(new SparseArrayObjectAdapter(new PresenterSelector() {
- @Override
- public Presenter getPresenter(Object object) {
- if (object instanceof PlaybackControlsRow) {
- return mGlue.getControlsRowPresenter();
- } else if (object instanceof ListRow) {
- return mListRowPresenter;
- }
- throw new IllegalArgumentException("Unhandled object: " + object);
- }
- }));
-
- // Add the controls row
- getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
+ setAdapter(new SparseArrayObjectAdapter(classPresenterSelector));
// Add related content rows
for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
diff --git a/samples/SupportLeanbackJank/Android.mk b/samples/SupportLeanbackJank/Android.mk
deleted file mode 100644
index 21e3f31..0000000
--- a/samples/SupportLeanbackJank/Android.mk
+++ /dev/null
@@ -1,40 +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.
-
-LOCAL_PATH:= $(call my-dir)
-
-# Build the samples.
-# We need to add some special AAPT flags to generate R classes
-# for resources that are included from the libraries.
-include $(CLEAR_VARS)
-LOCAL_USE_AAPT2 := true
-LOCAL_PACKAGE_NAME := SupportLeanbackJank
-LOCAL_MODULE_TAGS := samples tests
-LOCAL_SDK_VERSION := current
-LOCAL_MIN_SDK_VERSION := 17
-LOCAL_DEX_PREOPT := false
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_JAVA_LIBRARIES := glide
-LOCAL_STATIC_ANDROID_LIBRARIES := \
- android-support-compat \
- android-support-core-ui \
- android-support-media-compat \
- android-support-fragment \
- android-support-v7-recyclerview \
- android-support-v17-leanback \
- android-support-v17-preference-leanback \
- android-support-v7-preference \
- android-support-v14-preference
-
-include $(BUILD_PACKAGE)
diff --git a/samples/SupportLeanbackShowcase/app/src/main/Android.mk b/samples/SupportLeanbackShowcase/app/src/main/Android.mk
deleted file mode 100644
index 76c933e..0000000
--- a/samples/SupportLeanbackShowcase/app/src/main/Android.mk
+++ /dev/null
@@ -1,63 +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.
-
-LOCAL_PATH:= $(call my-dir)
-
-#LOCAL_JACK_FLAGS := -D jack.import.jar.debug-info=false
-
-# Build the samples.
-# We need to add some special AAPT flags to generate R classes
-# for resources that are included from the libraries.
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := SupportLeanbackShowcase
-LOCAL_MODULE_TAGS := samples tests
-LOCAL_SDK_VERSION := current
-LOCAL_MIN_SDK_VERSION := 17
-LOCAL_SRC_FILES := $(call all-java-files-under, java)
-LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-v4 \
- android-support-v7-recyclerview \
- android-support-v7-preference \
- android-support-v7-appcompat \
- android-support-v14-preference \
- android-support-v17-preference-leanback \
- android-support-v17-leanback \
- gson-x \
- picasso-x
-LOCAL_RESOURCE_DIR = \
- $(LOCAL_PATH)/res \
- frameworks/support/v17/preference-leanback/res \
- frameworks/support/v7/preference/res \
- frameworks/support/v7/appcompat/res \
- frameworks/support/v14/preference/res \
- frameworks/support/v17/leanback/res \
- frameworks/support/v7/recyclerview/res
-LOCAL_AAPT_FLAGS := \
- --auto-add-overlay \
- --extra-packages android.support.v17.leanback \
- --extra-packages android.support.v17.preference \
- --extra-packages android.support.v7.preference \
- --extra-packages android.support.v14.preference \
- --extra-packages android.support.v7.appcompat \
- --extra-packages android.support.v7.recyclerview
-include $(BUILD_PACKAGE)
-
-
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
- gson-x:../../../libs/gson-1.7.2.jar \
- picasso-x:../../../libs/picasso-2.5.2.jar \
-
-include $(BUILD_MULTI_PREBUILT)
diff --git a/samples/SupportPercentDemos/Android.mk b/samples/SupportPercentDemos/Android.mk
deleted file mode 100644
index 54c980f..0000000
--- a/samples/SupportPercentDemos/Android.mk
+++ /dev/null
@@ -1,32 +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.
-
-LOCAL_PATH:= $(call my-dir)
-
-# Build the samples.
-# We need to add some special AAPT flags to generate R classes
-# for resources that are included from the libraries.
-include $(CLEAR_VARS)
-LOCAL_USE_AAPT2 := true
-LOCAL_PACKAGE_NAME := SupportPercentDemos
-LOCAL_MODULE_TAGS := samples
-LOCAL_SDK_VERSION := current
-LOCAL_MIN_SDK_VERSION := 7
-LOCAL_DEX_PREOPT := false
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_ANDROID_LIBRARIES := \
- android-support-percent \
- android-support-v4 \
- android-support-v13
-include $(BUILD_PACKAGE)
diff --git a/samples/SupportPreferenceDemos/Android.mk b/samples/SupportPreferenceDemos/Android.mk
deleted file mode 100644
index f131aa0..0000000
--- a/samples/SupportPreferenceDemos/Android.mk
+++ /dev/null
@@ -1,61 +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.
-
-LOCAL_PATH:= $(call my-dir)
-
-# Build the samples.
-# We need to add some special AAPT flags to generate R classes
-# for resources that are included from the libraries.
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := SupportPreferenceDemos
-LOCAL_MODULE_TAGS := samples
-
-LOCAL_SDK_VERSION := current
-LOCAL_MIN_SDK_VERSION := 14
-
-LOCAL_DEX_PREOPT := false
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_STATIC_JAVA_LIBRARIES += \
- android-support-v4 \
- android-support-v7-appcompat \
- android-support-v7-preference \
- android-support-v7-recyclerview \
- android-support-v14-preference \
- android-support-v17-leanback \
- android-support-v17-preference-leanback \
-
-LOCAL_RESOURCE_DIR = \
- $(LOCAL_PATH)/res \
- frameworks/support/v7/appcompat/res \
- frameworks/support/v7/preference/res \
- frameworks/support/v7/recyclerview/res \
- frameworks/support/v14/preference/res \
- frameworks/support/v17/leanback/res \
- frameworks/support/v17/preference-leanback/res
-
-LOCAL_AAPT_FLAGS := \
- --auto-add-overlay \
- --extra-packages android.support.v7.appcompat \
- --extra-packages android.support.v7.preference \
- --extra-packages android.support.v7.recyclerview \
- --extra-packages android.support.v14.preference \
- --extra-packages android.support.v17.leanback \
- --extra-packages android.support.v17.preference \
- --no-version-vectors
-
-LOCAL_PROGUARD_FLAG_FILES := proguard.flags
-
-include $(BUILD_PACKAGE)
diff --git a/samples/SupportTransitionDemos/Android.mk b/samples/SupportTransitionDemos/Android.mk
deleted file mode 100644
index e822a0a..0000000
--- a/samples/SupportTransitionDemos/Android.mk
+++ /dev/null
@@ -1,34 +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.
-
-LOCAL_PATH:= $(call my-dir)
-
-# Build the samples.
-# We need to add some special AAPT flags to generate R classes
-# for resources that are included from the libraries.
-include $(CLEAR_VARS)
-LOCAL_USE_AAPT2 := true
-LOCAL_PACKAGE_NAME := SupportTransitionDemos
-LOCAL_MODULE_TAGS := samples
-LOCAL_SDK_VERSION := current
-LOCAL_MIN_SDK_VERSION := 14
-LOCAL_DEX_PREOPT := false
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_ANDROID_LIBRARIES := \
- android-support-v4 \
- android-support-v7-appcompat \
- android-support-transition
-LOCAL_AAPT_FLAGS := --no-version-vectors --no-version-transitions
-LOCAL_PROGUARD_FLAG_FILES := proguard.flags
-include $(BUILD_PACKAGE)
diff --git a/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/TransitionUsageBase.java b/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/TransitionUsageBase.java
index 0a085f2..f375e4d 100644
--- a/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/TransitionUsageBase.java
+++ b/samples/SupportTransitionDemos/src/com/example/android/support/transition/widget/TransitionUsageBase.java
@@ -16,18 +16,12 @@
package com.example.android.support.transition.widget;
-import android.support.annotation.LayoutRes;
-import com.example.android.support.transition.R;
-
import android.os.Bundle;
-import android.support.transition.Scene;
-import android.support.transition.TransitionManager;
+import android.support.annotation.LayoutRes;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
+
+import com.example.android.support.transition.R;
/**
* Base class for usages of the Transition API.
diff --git a/samples/SupportVectorDrawableDemos/Android.mk b/samples/SupportVectorDrawableDemos/Android.mk
deleted file mode 100644
index 376f841..0000000
--- a/samples/SupportVectorDrawableDemos/Android.mk
+++ /dev/null
@@ -1,44 +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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_USE_AAPT2 := true
-
-LOCAL_MODULE_TAGS := samples tests
-
-LOCAL_SDK_VERSION := current
-
-LOCAL_MIN_SDK_VERSION := 14
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := SupportVectorDrawableDemos
-
-LOCAL_STATIC_ANDROID_LIBRARIES := \
- android-support-v7-appcompat \
- android-support-animatedvectordrawable \
- android-support-vectordrawable \
- android-support-v4
-
-LOCAL_AAPT_FLAGS += --no-version-vectors
-
-include $(BUILD_PACKAGE)
-
-LOCAL_PROGUARD_FLAG_FILES := proguard.flags
-
-# Use the following include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/settings.gradle b/settings.gradle
index 1597c2e..b6c8b40 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -97,6 +97,15 @@
include ':support-instantvideo'
project(':support-instantvideo').projectDir = new File(rootDir, 'instantvideo')
+include ':support-emoji'
+project(':support-emoji').projectDir = new File(rootDir, 'emoji/core')
+
+include ':support-emoji-typeface'
+project(':support-emoji-typeface').projectDir = new File(rootDir, 'emoji/bundled-typeface')
+
+include ':support-emoji-appcompat'
+project(':support-emoji-appcompat').projectDir = new File(rootDir, 'emoji/appcompat')
+
/////////////////////////////
//
// Samples
@@ -135,6 +144,21 @@
include ':support-vector-drawable-demos'
project(':support-vector-drawable-demos').projectDir = new File(samplesRoot, 'SupportVectorDrawableDemos')
+include ':support-animation-demos'
+project(':support-animation-demos').projectDir = new File(samplesRoot, 'SupportAnimationDemos')
+
+include ':support-app-navigation'
+project(':support-app-navigation').projectDir = new File(samplesRoot, 'SupportAppNavigation')
+
+/////////////////////////////
+//
+// Testing libraries
+//
+/////////////////////////////
+
+include ':support-testutils'
+project(':support-testutils').projectDir = new File(rootDir, 'testutils')
+
/////////////////////////////
//
// External
@@ -148,3 +172,7 @@
include ':jdiff'
project(':jdiff').projectDir = new File(externalRoot, 'jdiff')
+
+///// FLATFOOT START
+
+///// FLATFOOT END
\ No newline at end of file
diff --git a/samples/Android.mk b/testutils/NO_DOCS
similarity index 69%
rename from samples/Android.mk
rename to testutils/NO_DOCS
index cc329fe..4dad694 100644
--- a/samples/Android.mk
+++ b/testutils/NO_DOCS
@@ -1,4 +1,4 @@
-# Copyright (C) 2016 The Android Open Source Project
+# 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.
@@ -12,6 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-LOCAL_PATH := $(call my-dir)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
+Having this file, named NO_DOCS, in a directory will prevent
+Android javadocs from being generated for java files under
+the directory. This is especially useful for test projects.
diff --git a/testutils/build.gradle b/testutils/build.gradle
new file mode 100644
index 0000000..f155ded
--- /dev/null
+++ b/testutils/build.gradle
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+apply plugin: 'java'
+
+dependencies {
+ compile libs.junit
+}
+
+targetCompatibility = '1.7'
+sourceCompatibility = '1.7'
diff --git a/customtabs/tests/src/android/support/customtabs/PollingCheck.java b/testutils/src/main/java/android/support/testutils/PollingCheck.java
similarity index 68%
rename from customtabs/tests/src/android/support/customtabs/PollingCheck.java
rename to testutils/src/main/java/android/support/testutils/PollingCheck.java
index 0163e94..8e85896 100644
--- a/customtabs/tests/src/android/support/customtabs/PollingCheck.java
+++ b/testutils/src/main/java/android/support/testutils/PollingCheck.java
@@ -14,29 +14,37 @@
* limitations under the License.
*/
-package android.support.customtabs;
+package android.support.testutils;
-import junit.framework.Assert;
+import org.junit.Assert;
-import java.util.concurrent.Callable;
-
+/**
+ * Utility used for testing that allows to poll for a certain condition to happen within a timeout.
+ */
public abstract class PollingCheck {
+ private static final long DEFAULT_TIMEOUT = 3000;
private static final long TIME_SLICE = 50;
- private long mTimeout = 3000;
+ private final long mTimeout;
+ /**
+ * The condition that the PollingCheck should use to proceed successfully.
+ */
public interface PollingCheckCondition {
+ /**
+ * @return Whether the polling condition has been met.
+ */
boolean canProceed();
}
- public PollingCheck() {
- }
-
public PollingCheck(long timeout) {
mTimeout = timeout;
}
protected abstract boolean check();
+ /**
+ * Start running the polling check.
+ */
public void run() {
if (check()) {
return;
@@ -60,22 +68,12 @@
Assert.fail("unexpected timeout");
}
- public static void check(CharSequence message, long timeout, Callable<Boolean> condition)
- throws Exception {
- while (timeout > 0) {
- if (condition.call()) {
- return;
- }
-
- Thread.sleep(TIME_SLICE);
- timeout -= TIME_SLICE;
- }
-
- Assert.fail(message.toString());
- }
-
+ /**
+ * Instantiate and start polling for a given condition with a default 3000ms timeout.
+ * @param condition The condition to check for success.
+ */
public static void waitFor(final PollingCheckCondition condition) {
- new PollingCheck() {
+ new PollingCheck(DEFAULT_TIMEOUT) {
@Override
protected boolean check() {
return condition.canProceed();
@@ -83,6 +81,11 @@
}.run();
}
+ /**
+ * Instantiate and start polling for a given condition.
+ * @param timeout Time out in ms
+ * @param condition The condition to check for success.
+ */
public static void waitFor(long timeout, final PollingCheckCondition condition) {
new PollingCheck(timeout) {
@Override
diff --git a/tv-provider/src/android/support/media/tv/Channel.java b/tv-provider/src/android/support/media/tv/Channel.java
index 5e158e2..460a6a7 100644
--- a/tv-provider/src/android/support/media/tv/Channel.java
+++ b/tv-provider/src/android/support/media/tv/Channel.java
@@ -31,9 +31,36 @@
import android.text.TextUtils;
import java.net.URISyntaxException;
+import java.nio.charset.Charset;
/**
- * A convenience class to create and insert channel entries into the database.
+ * A convenience class to access {@link TvContractCompat.Channels} entries in the system content
+ * provider.
+ *
+ * <p>This class makes it easy to insert or retrieve a channel from the system content provider,
+ * which is defined in {@link TvContractCompat}.
+ *
+ * <p>Usage example when inserting a channel:
+ * <pre>
+ * Channel channel = new Channel.Builder()
+ * .setDisplayName("Channel Name")
+ * .setDescription("Channel description")
+ * .setType(Channels.TYPE_PREVIEW)
+ * // Set more attributes...
+ * .build();
+ * Uri channelUri = getContentResolver().insert(Channels.CONTENT_URI, channel.toContentValues());
+ * </pre>
+ *
+ * <p>Usage example when retrieving a channel:
+ * <pre>
+ * Channel channel;
+ * try (Cursor cursor = resolver.query(channelUri, null, null, null, null)) {
+ * if (cursor != null && cursor.getCount() != 0) {
+ * cursor.moveToNext();
+ * channel = Channel.fromCursor(cursor);
+ * }
+ * }
+ * </pre>
*/
public final class Channel {
/**
@@ -54,7 +81,6 @@
private final String mDisplayNumber;
private final String mDisplayName;
private final String mDescription;
- private final String mChannelLogo;
private final String mVideoFormat;
private final int mOriginalNetworkId;
private final int mTransportStreamId;
@@ -91,7 +117,6 @@
mAppLinkIconUri = builder.mAppLinkIconUri;
mAppLinkPosterArtUri = builder.mAppLinkPosterArtUri;
mAppLinkIntentUri = builder.mAppLinkIntentUri;
- mChannelLogo = builder.mChannelLogo;
mInternalProviderData = builder.mInternalProviderData;
mNetworkAffiliation = builder.mNetworkAffiliation;
mSearchable = builder.mSearchable;
@@ -224,13 +249,6 @@
/**
- * @return The value of {@link Channels.Logo} for the channel.
- */
- public String getChannelLogo() {
- return mChannelLogo;
- }
-
- /**
* @return The value of {@link Channels#COLUMN_NETWORK_AFFILIATION} for the channel.
*/
public String getNetworkAffiliation() {
@@ -309,7 +327,6 @@
+ ", displayNumber=" + mDisplayNumber
+ ", displayName=" + mDisplayName
+ ", description=" + mDescription
- + ", channelLogo=" + mChannelLogo
+ ", videoFormat=" + mVideoFormat
+ ", appLinkText=" + mAppLinkText + "}";
}
@@ -580,7 +597,6 @@
private String mDisplayNumber;
private String mDisplayName;
private String mDescription;
- private String mChannelLogo;
private String mVideoFormat;
private int mOriginalNetworkId = INVALID_INTEGER_VALUE;
private int mTransportStreamId;
@@ -620,7 +636,6 @@
mAppLinkIconUri = other.mAppLinkIconUri;
mAppLinkPosterArtUri = other.mAppLinkPosterArtUri;
mAppLinkIntentUri = other.mAppLinkIntentUri;
- mChannelLogo = other.mChannelLogo;
mInternalProviderData = other.mInternalProviderData;
mNetworkAffiliation = other.mNetworkAffiliation;
mSearchable = other.mSearchable;
@@ -648,8 +663,10 @@
*
* @param packageName The value of {@link Channels#COLUMN_PACKAGE_NAME} for the channel.
* @return This Builder object to allow for chaining of calls to builder methods.
+ * @hide
*/
- public Builder setPackageName(String packageName) {
+ @RestrictTo(LIBRARY_GROUP)
+ Builder setPackageName(String packageName) {
mPackageName = packageName;
return this;
}
@@ -710,18 +727,6 @@
}
/**
- * Sets the logo of the channel.
- *
- * @param channelLogo The Uri corresponding to the logo for the channel.
- * @return This Builder object to allow for chaining of calls to builder methods.
- * @see Channels.Logo
- */
- public Builder setChannelLogo(String channelLogo) {
- mChannelLogo = channelLogo;
- return this;
- }
-
- /**
* Sets the video format of the Channel.
*
* @param videoFormat The value of {@link Channels#COLUMN_VIDEO_FORMAT} for the channel.
@@ -787,7 +792,7 @@
* @return This Builder object to allow for chaining of calls to builder methods.
*/
public Builder setInternalProviderData(String internalProviderData) {
- mInternalProviderData = internalProviderData.getBytes();
+ mInternalProviderData = internalProviderData.getBytes(Charset.defaultCharset());
return this;
}
diff --git a/tv-provider/src/android/support/media/tv/Program.java b/tv-provider/src/android/support/media/tv/Program.java
index 71c51fb..453e21a 100644
--- a/tv-provider/src/android/support/media/tv/Program.java
+++ b/tv-provider/src/android/support/media/tv/Program.java
@@ -43,7 +43,34 @@
import java.util.Objects;
/**
- * A convenience class to create and insert program information into the database.
+ * A convenience class to access {@link TvContractCompat.Programs} entries in the system content
+ * provider.
+ *
+ * <p>This class makes it easy to insert or retrieve a program from the system content provider,
+ * which is defined in {@link TvContractCompat}.
+ *
+ * <p>Usage example when inserting a program:
+ * <pre>
+ * Program program = new Program.Builder()
+ * .setChannelId(channel.getId())
+ * .setTitle("Program Title")
+ * .setDescription("Program Description")
+ * .setPosterArtUri(Uri.parse("http://example.com/poster_art.png"))
+ * // Set more attributes...
+ * .build();
+ * Uri programUri = getContentResolver().insert(Programs.CONTENT_URI, program.toContentValues());
+ * </pre>
+ *
+ * <p>Usage example when retrieving a program:
+ * <pre>
+ * Program program;
+ * try (Cursor cursor = resolver.query(programUri, null, null, null, null)) {
+ * if (cursor != null && cursor.getCount() != 0) {
+ * cursor.moveToNext();
+ * program = Program.fromCursor(cursor);
+ * }
+ * }
+ * </pre>
*/
public final class Program implements Comparable<Program> {
/**
@@ -546,16 +573,16 @@
&& Arrays.equals(mContentRatings, program.mContentRatings)
&& Arrays.equals(mAudioLanguages, program.mAudioLanguages)
&& (Build.VERSION.SDK_INT < Build.VERSION_CODES.M
- || Objects.equals(mSearchable, program.mSearchable)
+ || (Objects.equals(mSearchable, program.mSearchable)
&& Objects.equals(mInternalProviderFlag1, program.mInternalProviderFlag1)
&& Objects.equals(mInternalProviderFlag2, program.mInternalProviderFlag2)
&& Objects.equals(mInternalProviderFlag3, program.mInternalProviderFlag3)
- && Objects.equals(mInternalProviderFlag4, program.mInternalProviderFlag4))
+ && Objects.equals(mInternalProviderFlag4, program.mInternalProviderFlag4)))
&& (Build.VERSION.SDK_INT < Build.VERSION_CODES.N
- || Objects.equals(mSeasonTitle, program.mSeasonTitle)
- && Objects.equals(mRecordingProhibited, program.mRecordingProhibited))
+ || (Objects.equals(mSeasonTitle, program.mSeasonTitle)
+ && Objects.equals(mRecordingProhibited, program.mRecordingProhibited)))
&& (!BuildCompat.isAtLeastO()
- || Objects.equals(mInternalProviderId, program.mInternalProviderId)
+ || (Objects.equals(mInternalProviderId, program.mInternalProviderId)
&& Objects.equals(mPreviewVideoUri, program.mPreviewVideoUri)
&& Objects.equals(mLastPlaybackPositionMillis,
program.mLastPlaybackPositionMillis)
@@ -579,7 +606,7 @@
&& Objects.equals(mInteractionCount, program.mInteractionCount)
&& Objects.equals(mAuthor, program.mAuthor)
&& Objects.equals(mReviewRatingStyle, program.mReviewRatingStyle)
- && Objects.equals(mReviewRating, program.mReviewRating));
+ && Objects.equals(mReviewRating, program.mReviewRating)));
}
/**
diff --git a/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java b/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java
index 901bf06..6b394e6 100644
--- a/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java
+++ b/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java
@@ -267,6 +267,7 @@
return result;
}
+ @SuppressWarnings("unchecked")
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
setValues(restoreValue ? getPersistedStringSet(mValues) : (Set<String>) defaultValue);
diff --git a/v17/leanback/Android.mk b/v17/leanback/Android.mk
index c6a50b4..6e62436 100644
--- a/v17/leanback/Android.mk
+++ b/v17/leanback/Android.mk
@@ -66,7 +66,7 @@
android-support-v17-leanback
LOCAL_ADDITIONAL_JAVA_DIR := $(call intermediates-dir-for,JAVA_LIBRARIES,android-support-v17-leanback-res,,COMMON)/src
LOCAL_IS_HOST_MODULE := false
-LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR := build/tools/droiddoc/templates-sdk
+LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR := external/doclava/res/assets/templates-sdk
LOCAL_DROIDDOC_OPTIONS := \
-offlinemode \
-hdf android.whichdoc offline \
diff --git a/v17/leanback/kitkat/android/support/v17/leanback/transition/TransitionHelperKitkat.java b/v17/leanback/kitkat/android/support/v17/leanback/transition/TransitionHelperKitkat.java
index 38a80f2..211e8fc 100644
--- a/v17/leanback/kitkat/android/support/v17/leanback/transition/TransitionHelperKitkat.java
+++ b/v17/leanback/kitkat/android/support/v17/leanback/transition/TransitionHelperKitkat.java
@@ -26,12 +26,10 @@
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.transition.TransitionValues;
-import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.view.View;
import android.view.ViewGroup;
-import java.util.ArrayList;
import java.util.HashMap;
@RequiresApi(19)
diff --git a/v17/leanback/res/layout/lb_playback_controls_row.xml b/v17/leanback/res/layout/lb_playback_controls_row.xml
index e3893b3..b449fa9 100644
--- a/v17/leanback/res/layout/lb_playback_controls_row.xml
+++ b/v17/leanback/res/layout/lb_playback_controls_row.xml
@@ -46,6 +46,7 @@
<LinearLayout
android:id="@+id/controls_card_right_panel"
+ android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
diff --git a/v17/leanback/res/values-af/strings.xml b/v17/leanback/res/values-af/strings.xml
index 2f2ca18..3ced389 100644
--- a/v17/leanback/res/values-af/strings.xml
+++ b/v17/leanback/res/values-af/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Aktiveer onderskrifte"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Deaktiveer onderskrifte"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Voer prent in prentmodus in"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Mediakontroles word gewys"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Mediakontroles word versteek; druk D-paneel om te wys"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Voltooi"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Gaan voort"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-am/strings.xml b/v17/leanback/res/values-am/strings.xml
index c4b461a..8729a23 100644
--- a/v17/leanback/res/values-am/strings.xml
+++ b/v17/leanback/res/values-am/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"ዝግ የምስል ስር ጽሑፍ አጻጻፍን አንቃ"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"ዝግ የምስል ስር ጽሑፍ አጻጻፍን አሰናክል"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"ስዕሉን በስዕል ሁነታ ውስጥ ያክሉ"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"የሚዲያ መቆጣጠሪያዎች እንዲታዩ ተደርገዋል"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"የሚዲያ መቆጣጠሪያዎች ተደብቀዋል። d-pad ን ለማሳየት ይጫኑ"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"ጨርስ"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"ቀጥል"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-ar/strings.xml b/v17/leanback/res/values-ar/strings.xml
index cda830c..4c86a05 100644
--- a/v17/leanback/res/values-ar/strings.xml
+++ b/v17/leanback/res/values-ar/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"تمكين الترجمة المصاحبة"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"تعطيل الترجمة المصاحبة"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"إدخال صورة في وضع الصورة"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"تم إظهار عناصر التحكم في الوسائط"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"تم إخفاء عناصر التحكم في الوسائط، يمكنك الضغط على d-pad لإظهارها"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"إنهاء"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"متابعة"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-az/strings.xml b/v17/leanback/res/values-az/strings.xml
index f9f0277..19512e4 100644
--- a/v17/leanback/res/values-az/strings.xml
+++ b/v17/leanback/res/values-az/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Qapalı çəkilişi aktiv edin"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Qapalı çəkilişi deaktiv edin"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Şəkil içində Şəkil Rejiminə daxil olun"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Media idarəetmələri açıqdır"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Media idarəetmələri gizlidir, göstərmək üçün d-pad\'i basın"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Bitir"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Davam edin"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-b+sr+Latn/strings.xml b/v17/leanback/res/values-b+sr+Latn/strings.xml
index 5c466fb..1ae1bd4 100644
--- a/v17/leanback/res/values-b+sr+Latn/strings.xml
+++ b/v17/leanback/res/values-b+sr+Latn/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Omogući titlove"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Onemogući titlove"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Uđi u režim Slika u slici"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Kontrole za medije su prikazane"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Kontrole za medije su skrivene, pritisnite kontrole za kretanje da biste ih prikazali"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Dovrši"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Nastavi"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-be/strings.xml b/v17/leanback/res/values-be/strings.xml
index b9e72bb..0857ec1 100644
--- a/v17/leanback/res/values-be/strings.xml
+++ b/v17/leanback/res/values-be/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Уключыць схаваныя цітры"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Адключыць схаваныя цітры"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Калі ласка, увядзіце выяву ў рэжыме Выяў"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Элементы кіравання мультымедыя паказаны"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Элементы кіравання мультымедыя схаваны. Каб паказаць іх, націсніце пераключальнік напрамкаў"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Завяршыць"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Далей"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-bg/strings.xml b/v17/leanback/res/values-bg/strings.xml
index 642abc5..32fa30b 100644
--- a/v17/leanback/res/values-bg/strings.xml
+++ b/v17/leanback/res/values-bg/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Активиране на субтитрите"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Деактивиране на субтитрите"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Вход в режима „Картина в картина“"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Контролите за мултимедия са показани"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Контролите за мултимедия са скрити. Натиснете контролния пад, за да се покажат"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Край"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Напред"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-bn/strings.xml b/v17/leanback/res/values-bn/strings.xml
index be98f58..f3d37a1 100644
--- a/v17/leanback/res/values-bn/strings.xml
+++ b/v17/leanback/res/values-bn/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"সাবটাইটেল সক্ষম করুন"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"সাবটাইটেল অক্ষম করুন"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"ছবি মোডে ছবি লগান"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"মিডিয়ার নিয়ন্ত্রণগুলি দেখানো হয়েছে"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"মিডিয়ার নিয়ন্ত্রণগুলি লুকানো আছে, দেখার জন্য ডি-প্যাড টিপুন"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"শেষ করুন"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"চালিয়ে যান"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-bs/strings.xml b/v17/leanback/res/values-bs/strings.xml
index 63a76e2..6d17dff 100644
--- a/v17/leanback/res/values-bs/strings.xml
+++ b/v17/leanback/res/values-bs/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Uključi titlove"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Isključi titlove"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Uđi u način rada Slika u slici"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Kontrole za medije su prikazane"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Kontrole za medije su skrivene. Pritisnite d-pad da ih prikažete"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Završiti"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Nastaviti"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-ca/strings.xml b/v17/leanback/res/values-ca/strings.xml
index 5567e23..ef0b2d2 100644
--- a/v17/leanback/res/values-ca/strings.xml
+++ b/v17/leanback/res/values-ca/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Activa els subtítols tancats"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Desactiva els subtítols tancats"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Entra al mode d\'imatge en imatge"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Es mostren els controls multimèdia"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"S\'han amagat els controls multimèdia; prem el teclat direccional per mostrar-los"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Finalitza"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Continua"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-cs/strings.xml b/v17/leanback/res/values-cs/strings.xml
index a5fbfb5..54e5b55 100644
--- a/v17/leanback/res/values-cs/strings.xml
+++ b/v17/leanback/res/values-cs/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Zapnout titulky"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Vypnout titulky"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Přejít do režimu Obraz v obraze"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Ovládací prvky médií jsou zobrazeny"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Ovládací prvky médií jsou skryty, zobrazíte je stisknutím směrového přepínače"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Dokončit"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Pokračovat"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-da/strings.xml b/v17/leanback/res/values-da/strings.xml
index 76062f5..cf0e26e 100644
--- a/v17/leanback/res/values-da/strings.xml
+++ b/v17/leanback/res/values-da/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Aktivér undertekster"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Deaktiver undertekster"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Tilføj billedet i billedtilstand"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Knapperne til afspilning er synlige"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Knapperne til afspilning er skjult. Tryk på D-pad for at se dem"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Afslut"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Fortsæt"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-de/strings.xml b/v17/leanback/res/values-de/strings.xml
index 53ad13a..b16548d 100644
--- a/v17/leanback/res/values-de/strings.xml
+++ b/v17/leanback/res/values-de/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Untertitel aktivieren"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Untertitel deaktivieren"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Bild-in-Bild-Modus aktivieren"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Mediensteuerelemente eingeblendet"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Mediensteuerelemente ausgeblendet. Drücke das Steuerkreuz, um die Steuerelemente wieder einzublenden."</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Fertigstellen"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Weiter"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"."</string>
diff --git a/v17/leanback/res/values-el/strings.xml b/v17/leanback/res/values-el/strings.xml
index 6dc20ef..39a6c21 100644
--- a/v17/leanback/res/values-el/strings.xml
+++ b/v17/leanback/res/values-el/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Ενεργοποίηση υποτίτλων"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Απενεργοποίηση υποτίτλων"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Εισαγωγή εικόνας στη Λειτουργία εικόνας"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Εμφάνιση στοιχείων ελέγχου μέσων"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Απόκρυψη στοιχείων ελέγχου μέσων, πιέστε το d-pad για εμφάνιση"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Τέλος"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Συνέχεια"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-en-rAU/strings.xml b/v17/leanback/res/values-en-rAU/strings.xml
index 8032f7d..ddd47d0 100644
--- a/v17/leanback/res/values-en-rAU/strings.xml
+++ b/v17/leanback/res/values-en-rAU/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Enable Closed Captioning"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Disable Closed Captioning"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Enter Picture In Picture Mode"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Media controls shown"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Media controls hidden, press d-pad to show"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Finish"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Continue"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-en-rGB/strings.xml b/v17/leanback/res/values-en-rGB/strings.xml
index 8032f7d..ddd47d0 100644
--- a/v17/leanback/res/values-en-rGB/strings.xml
+++ b/v17/leanback/res/values-en-rGB/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Enable Closed Captioning"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Disable Closed Captioning"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Enter Picture In Picture Mode"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Media controls shown"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Media controls hidden, press d-pad to show"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Finish"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Continue"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-en-rIN/strings.xml b/v17/leanback/res/values-en-rIN/strings.xml
index 8032f7d..ddd47d0 100644
--- a/v17/leanback/res/values-en-rIN/strings.xml
+++ b/v17/leanback/res/values-en-rIN/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Enable Closed Captioning"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Disable Closed Captioning"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Enter Picture In Picture Mode"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Media controls shown"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Media controls hidden, press d-pad to show"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Finish"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Continue"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-es-rUS/strings.xml b/v17/leanback/res/values-es-rUS/strings.xml
index 8a81040..2969100 100644
--- a/v17/leanback/res/values-es-rUS/strings.xml
+++ b/v17/leanback/res/values-es-rUS/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Habilitar subtítulos"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Inhabilitar subtítulos"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Activar el modo Imagen en imagen"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Se muestran los controles de medios"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Los controles de medios están ocultos; presiona el control direccional para mostrarlos"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Finalizar"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Continuar"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-es/strings.xml b/v17/leanback/res/values-es/strings.xml
index 59f707b..94608a7 100644
--- a/v17/leanback/res/values-es/strings.xml
+++ b/v17/leanback/res/values-es/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Habilitar subtítulos"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Inhabilitar subtítulos"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Activar modo Imagen en imagen"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Controles multimedia mostrados"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Controles multimedia ocultos (pulsa la cruceta para mostrarlos)"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Finalizar"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Continuar"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-et/strings.xml b/v17/leanback/res/values-et/strings.xml
index 6d6bac8..44b9fc6 100644
--- a/v17/leanback/res/values-et/strings.xml
+++ b/v17/leanback/res/values-et/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Luba subtiitrid"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Keela subtiitrid"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Sisene režiimi Pilt pildis"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Meedia juhtnupud on kuvatud"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Meedia juhtnupud on peidetud, kuvamiseks vajutage DPAD-i"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Lõpeta"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Jätka"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-eu/strings.xml b/v17/leanback/res/values-eu/strings.xml
index 98787d4..54837ed 100644
--- a/v17/leanback/res/values-eu/strings.xml
+++ b/v17/leanback/res/values-eu/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Gaitu azpitituluak"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Desgaitu azpitituluak"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Aktibatu \"Argazkia argazkian\" modua"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Multimedia kontrolatzeko aukerak ikusgai"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Ezkutatuta daude multimedia kontrolatzeko aukerak. Erakusteko, sakatu nabigazio-gurutzea."</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Amaitu"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Jarraitu"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-fa/strings.xml b/v17/leanback/res/values-fa/strings.xml
index 3774bd2..e9f01c6 100644
--- a/v17/leanback/res/values-fa/strings.xml
+++ b/v17/leanback/res/values-fa/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"فعال کردن زیرنویس"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"غیرفعال کردن زیرنویس"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"وارد حالت تصویر در تصویر شوید"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"کنترلهای رسانه نشان داده میشوند"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"کنترلهای رسانه پنهان هستند، برای نمایش آنها d-pad را فشار دهید"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"پایان"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"ادامه"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-fi/strings.xml b/v17/leanback/res/values-fi/strings.xml
index 3444642..3ef86ee 100644
--- a/v17/leanback/res/values-fi/strings.xml
+++ b/v17/leanback/res/values-fi/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Ota tekstitys käyttöön"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Poista tekstitys käytöstä"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Vaihda kuva kuvassa ‑tilaan"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Mediasäätimet näkyvissä"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Mediasäätimet piilotettu, näytä painamalla ohjaimen nuolia."</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Valmis"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Jatka"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-fr-rCA/strings.xml b/v17/leanback/res/values-fr-rCA/strings.xml
index 4c8cc19..34b6947 100644
--- a/v17/leanback/res/values-fr-rCA/strings.xml
+++ b/v17/leanback/res/values-fr-rCA/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Activer le sous-titrage"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Désactiver le sous-titrage"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Activer le mode Incrustation d\'image"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Les commandes multimédias sont affichées"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Les commandes multimédias sont masquées, appuyez sur le pavé directionnel pour les afficher."</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Terminer"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Continuer"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-fr/strings.xml b/v17/leanback/res/values-fr/strings.xml
index 9086fa1..0876dcc 100644
--- a/v17/leanback/res/values-fr/strings.xml
+++ b/v17/leanback/res/values-fr/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Activer les sous-titres"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Désactiver les sous-titres"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Activer le mode PIP"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Les commandes multimédias sont affichées"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Les commandes multimédias sont masquées. Appuyez sur le pavé directionnel pour les afficher"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Terminer"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Continuer"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-gl/strings.xml b/v17/leanback/res/values-gl/strings.xml
index 2d2579b..702f5bc 100644
--- a/v17/leanback/res/values-gl/strings.xml
+++ b/v17/leanback/res/values-gl/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Activar subtítulos"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Desactivar subtítulos"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Activar o modo Imaxe superposta"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Móstranse os controis de recursos multimedia"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Os controis de recursos multimedia están ocultos. Preme d-pad para mostralos"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Finalizar"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Continuar"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-gu/strings.xml b/v17/leanback/res/values-gu/strings.xml
index 569da29..bc021cb 100644
--- a/v17/leanback/res/values-gu/strings.xml
+++ b/v17/leanback/res/values-gu/strings.xml
@@ -48,6 +48,10 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"ઉપશીર્ષક સક્ષમ કરો"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"વિગતવાર ઉપશીર્ષકોને અક્ષમ કરો"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"ચિત્ર મોડમાં ચિત્ર દાખલ કરો"</string>
+ <!-- no translation found for lb_playback_controls_shown (6382160135512023238) -->
+ <skip />
+ <!-- no translation found for lb_playback_controls_hidden (8940984081242033574) -->
+ <skip />
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"સમાપ્ત કરો"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"ચાલુ રાખો"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-hi/strings.xml b/v17/leanback/res/values-hi/strings.xml
index 1b73165..6c10c6c 100644
--- a/v17/leanback/res/values-hi/strings.xml
+++ b/v17/leanback/res/values-hi/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"उपशीर्षक सक्षम करें"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"उपशीर्षक अक्षम करें"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"चित्र मोड में चित्र डालें"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"मीडिया कंट्रोल दिखाए गए हैं"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"मीडिया नियंत्रण छिपे हुए हैं, दिखाने के लिए डी-पैड दबाएं"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"समाप्त करें"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"जारी रखें"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-hr/strings.xml b/v17/leanback/res/values-hr/strings.xml
index 73c8dc6..06efef9 100644
--- a/v17/leanback/res/values-hr/strings.xml
+++ b/v17/leanback/res/values-hr/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Omogući titlove"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Onemogući titlove"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Unos slike u načinu slike"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Medijske kontrole prikazane"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Medijske kontrole skrivene su, pritisnite D-pad za prikaz"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Završi"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Nastavi"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-hu/strings.xml b/v17/leanback/res/values-hu/strings.xml
index f30c4f6..7f26563 100644
--- a/v17/leanback/res/values-hu/strings.xml
+++ b/v17/leanback/res/values-hu/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Feliratok engedélyezése"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Feliratok letiltása"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Kép a képben mód indítása"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Médiavezérlők megjelenítve"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"A médiavezérlők el vannak rejtve. Megjelenítésükhöz nyomja le a d-padet."</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Befejezés"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Folytatás"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-hy/strings.xml b/v17/leanback/res/values-hy/strings.xml
index edc1f47..8b612de 100644
--- a/v17/leanback/res/values-hy/strings.xml
+++ b/v17/leanback/res/values-hy/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Միացնել խորագրերը"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Անջատել խորագրերը"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Մուտք «Նկար նկարի մեջ» ռեժիմ"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Մեդիայի կառավարման տարրերը ցուցադրվում են"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Մեդիայի կառավարման տարրերը թաքցված են։ Ցուցադրելու համար սեղմեք d-pad-ը"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Վերջ"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Շարունակել"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-in/strings.xml b/v17/leanback/res/values-in/strings.xml
index 05e9dc9..bb92f5e 100644
--- a/v17/leanback/res/values-in/strings.xml
+++ b/v17/leanback/res/values-in/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Aktifkan Pembuatan Teks"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Nonaktifkan Pembuatan Teks"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Masukkan Foto Dalam Mode Foto"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Kontrol media ditampilkan"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Kontrol media disembunyikan, tekan d-pad untuk menampilkannya"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Selesai"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Lanjutkan"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-is/strings.xml b/v17/leanback/res/values-is/strings.xml
index 84b6430..6e8f560 100644
--- a/v17/leanback/res/values-is/strings.xml
+++ b/v17/leanback/res/values-is/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Kveikja á skjátextum"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Slökkva á skjátextum"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Skoða mynd í myndsniði"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Spilunarstýringar sýndar"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Spilunarstýringar faldar, ýttu á stefnuhnappa til að sýna þær"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Ljúka"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Halda áfram"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-it/strings.xml b/v17/leanback/res/values-it/strings.xml
index b0814d0..8127d5d 100644
--- a/v17/leanback/res/values-it/strings.xml
+++ b/v17/leanback/res/values-it/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Attiva sottotitoli"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Disattiva sottotitoli"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Attiva modalità Picture-in-picture"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Controlli multimediali visualizzati"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Controlli multimediali nascosti, premi il d-pad per visualizzarli"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Fine"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Continua"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-iw/strings.xml b/v17/leanback/res/values-iw/strings.xml
index b94c431..4d6d7f4 100644
--- a/v17/leanback/res/values-iw/strings.xml
+++ b/v17/leanback/res/values-iw/strings.xml
@@ -48,6 +48,10 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"הפעל כתוביות"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"השבת כתוביות"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"הזן את התמונה במצב תמונה"</string>
+ <!-- no translation found for lb_playback_controls_shown (6382160135512023238) -->
+ <skip />
+ <!-- no translation found for lb_playback_controls_hidden (8940984081242033574) -->
+ <skip />
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"סיום"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"המשך"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-ja/strings.xml b/v17/leanback/res/values-ja/strings.xml
index 650f4fd..95a9964 100644
--- a/v17/leanback/res/values-ja/strings.xml
+++ b/v17/leanback/res/values-ja/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"字幕を有効にする"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"字幕を無効にする"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"PIP モードに移動"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"メディア コントロールは表示されています"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"メディア コントロールは非表示になっています。表示するには D-pad を押してください"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"完了"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"続行"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-ka/strings.xml b/v17/leanback/res/values-ka/strings.xml
index 9962645..575c504 100644
--- a/v17/leanback/res/values-ka/strings.xml
+++ b/v17/leanback/res/values-ka/strings.xml
@@ -52,6 +52,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"დახურული წარწერების ჩართვა"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"დახურული წარწერების გაუქმება"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"რეჟიმზე „სურათი სურათში“ გადასვლა"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"ნაჩვენებია მედიის მართვის საშუალებები"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"მედიის მართვის საშუალებები დამალულია, გამოსაჩენად დააჭირეთ D-pad-ს"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"დასრულება"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"გაგრძელება"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"."</string>
diff --git a/v17/leanback/res/values-kk/strings.xml b/v17/leanback/res/values-kk/strings.xml
index 6f7faf2..31c92a5 100644
--- a/v17/leanback/res/values-kk/strings.xml
+++ b/v17/leanback/res/values-kk/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Жасырын титрлерді қосу"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Жасырын титрлерді өшіру"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Сурет ішіндегі сурет режиміне кіру"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Мультимедияны басқару элементтері көрсетілген"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Мультимедияны басқару элементтері жасырын, оларды көрсету үшін d-тақтасын басыңыз"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Аяқтау"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Жалғастыру"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-km/strings.xml b/v17/leanback/res/values-km/strings.xml
index 25abb45..ba3373a 100644
--- a/v17/leanback/res/values-km/strings.xml
+++ b/v17/leanback/res/values-km/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"បើកការដាក់ចំណងដែលបានបិទ"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"បិទការដាក់ចំណងដែលបានបិទ"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"បញ្ចូលរូបភាពនៅក្នុងរបៀបរូបភាព"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"ការគ្រប់គ្រងមេឌៀត្រូវបានបង្ហាញ"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"ការគ្រប់គ្រងមេឌៀត្រូវបានលាក់ សូមចុច d-pad ដើម្បីបង្ហាញ"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"បញ្ចប់"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"បន្ត"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-kn/strings.xml b/v17/leanback/res/values-kn/strings.xml
index 92fdddd..69e0277 100644
--- a/v17/leanback/res/values-kn/strings.xml
+++ b/v17/leanback/res/values-kn/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"ಮುಚ್ಚಿದ ಶೀರ್ಷಿಕೆಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"ಮುಚ್ಚಿದ ಶೀರ್ಷಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"ಚಿತ್ರವನ್ನು ಚಿತ್ರ ಮೋಡ್ನಲ್ಲಿ ಪ್ರವೇಶಿಸಿ"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"ಮಾಧ್ಯಮ ನಿಯಂತ್ರಣಗಳನ್ನು ತೋರಿಸಲಾಗಿದೆ"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"ಮಾಧ್ಯಮ ನಿಯಂತ್ರಣಗಳನ್ನು ಮರೆಮಾಡಲಾಗಿದೆ, ತೋರಿಸಲು d-pad ಒತ್ತಿರಿ"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"ಪೂರ್ಣಗೊಳಿಸು"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"ಮುಂದುವರಿಸು"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-ko/strings.xml b/v17/leanback/res/values-ko/strings.xml
index 1696bca..485aff6 100644
--- a/v17/leanback/res/values-ko/strings.xml
+++ b/v17/leanback/res/values-ko/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"자막 사용 설정"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"자막 사용 중지"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"사진 모드에서 사진 입력"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"미디어 컨트롤이 표시되었습니다."</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"미디어 컨트롤이 숨겨져 있습니다. 표시하려면 D-Pad를 누르세요."</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"완료"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"계속"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-ky/strings.xml b/v17/leanback/res/values-ky/strings.xml
index e2dc200..51537b1 100644
--- a/v17/leanback/res/values-ky/strings.xml
+++ b/v17/leanback/res/values-ky/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Жабык субтитрлерди иштетүү"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Жабык субтитрлерди өчүрүү"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Сүрөт режиминде сүрөт киргизүү"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Медиа файлды башкаруу көрсөтүлдү"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Медиа файлды башкаруу жашырылган, көрүү үчүн d-pad көзөмөлдөө каражатын басыңыз"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Бүтүрүү"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Улантуу"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-lo/strings.xml b/v17/leanback/res/values-lo/strings.xml
index 389b1d0..3053234 100644
--- a/v17/leanback/res/values-lo/strings.xml
+++ b/v17/leanback/res/values-lo/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"ເປີດນຳໃຊ້ຄຳບັນຍາຍແບບປິດ"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"ປິດນຳໃຊ້ຄຳບັນຍາຍແບບປິດ"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"ປ້ອນຮູບພາບໃນໂໝດຮູບພາບ"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"ສະແດງຕົວຄວບຄຸມມີເດຍແລ້ວ"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"ເຊື່ອງຕົວຄວບຄຸມມີເດຍແລ້ວ, ກົດປຸ່ມທິດທາງເພື່ອສະແດງ"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"ສໍາເລັດ"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"ສືບຕໍ່"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-lt/strings.xml b/v17/leanback/res/values-lt/strings.xml
index 43eebb8..ee3d3f6 100644
--- a/v17/leanback/res/values-lt/strings.xml
+++ b/v17/leanback/res/values-lt/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Įgalinti subtitrus"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Išjungti subtitrus"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Įjungti vaizdo vaizde režimą"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Medijos valdikliai rodomi"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Medijos valdikliai paslėpti. Paspauskite krypčių valdiklius, kad rodytumėte"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Baigti"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Tęsti"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-lv/strings.xml b/v17/leanback/res/values-lv/strings.xml
index 644d990..aa04f90 100644
--- a/v17/leanback/res/values-lv/strings.xml
+++ b/v17/leanback/res/values-lv/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Iespējot slēgtos parakstus"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Atspējot slēgtos parakstus"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Aktivizēt režīmu Attēls attēlā"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Multivides vadīklas ir redzamas."</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Multivides vadīklas ir paslēptas. Nospiediet virzienu tastatūru, lai tās tiktu parādītas."</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Pabeigt"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Turpināt"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"."</string>
diff --git a/v17/leanback/res/values-mk/strings.xml b/v17/leanback/res/values-mk/strings.xml
index 6e506fe..f7e4d1f 100644
--- a/v17/leanback/res/values-mk/strings.xml
+++ b/v17/leanback/res/values-mk/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Овозможи затворено објаснување"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Оневозможи затворено објаснување"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Влези во режимот „Слика во слика“"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Контролите за аудио-визуелните контроли се прикажуваат"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Контролите за аудио-визуелните медиуми се скриени, притиснете на подлогата за насока за да ги прикажете"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Заврши"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Продолжи"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"."</string>
diff --git a/v17/leanback/res/values-ml/strings.xml b/v17/leanback/res/values-ml/strings.xml
index 0306a6a..f15aa1d 100644
--- a/v17/leanback/res/values-ml/strings.xml
+++ b/v17/leanback/res/values-ml/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"അടച്ച അടിക്കുറിപ്പ് നൽകൽ പ്രവർത്തനക്ഷമമാക്കുക"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"അടച്ച അടിക്കുറിപ്പ് നൽകൽ പ്രവർത്തനരഹിതമാക്കുക"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"\'ചിത്രത്തിനുള്ളിൽ ചിത്രം\' മോഡിലേക്ക് പ്രവേശിക്കുക"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"മീഡിയ നിയന്ത്രണങ്ങൾ കാണിച്ചിരിക്കുന്നു"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"മീഡിയ നിയന്ത്രണങ്ങൾ മറച്ചിരിക്കുന്നു, കാണിക്കുന്നതിന് ഡി-പാഡ് അമർത്തുക"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"പൂര്ത്തിയാക്കുക"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"തുടരുക"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-mn/strings.xml b/v17/leanback/res/values-mn/strings.xml
index f21b649..672ed15 100644
--- a/v17/leanback/res/values-mn/strings.xml
+++ b/v17/leanback/res/values-mn/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Текст тайлбарыг идэвхжүүлэх"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Текст тайлбарыг идэвхгүйжүүлэх"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Зургийн горимд зураг оруулна уу"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Медиа удирдлага харагдаж байна"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Медиа удирдлага нуугдсан байна, харуулахын тулд d-pad-г дарна уу"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Дуусгах"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Үргэлжлүүлэх"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-mr/strings.xml b/v17/leanback/res/values-mr/strings.xml
index ef6a6a6..99f7a17 100644
--- a/v17/leanback/res/values-mr/strings.xml
+++ b/v17/leanback/res/values-mr/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"उपशीर्षके सक्षम करा"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"उपशीर्षके अक्षम करा"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"चित्र मोडमध्ये चित्र प्रविष्ट करा"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"मीडिया नियंत्रणे दर्शवली आहेत"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"मीडिया नियंत्रणे लपलेली आहेत, दर्शवण्यासाठी d-pad दाबा"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"समाप्त"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"सुरू ठेवा"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-ms/strings.xml b/v17/leanback/res/values-ms/strings.xml
index 1764e52..8ee0bfb 100644
--- a/v17/leanback/res/values-ms/strings.xml
+++ b/v17/leanback/res/values-ms/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Dayakan Kapsyen Tertutup"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Lumpuhkan Kapsyen Tertutup"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Masukkan Gambar Dalam Mod Gambar"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Kawalan media ditunjukkan"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Kawalan media disembunyikan, tekan d-pad untuk menunjukkan"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Selesai"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Teruskan"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-my/strings.xml b/v17/leanback/res/values-my/strings.xml
index 645f169..f0d89d4 100644
--- a/v17/leanback/res/values-my/strings.xml
+++ b/v17/leanback/res/values-my/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"စာတမ်းထိုး ဖွင့်ရန်"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"စာတမ်းထိုးအား ပိတ်ထားရန်"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"ဓာတ်ပုံမုဒ်တွင် ဓာတ်ပုံထည့်ပါ"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"မီဒီယာ ခလုတ်များကို ပြထားပါသည်"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"မီဒီယာခလုတ်များကို ဝှက်ထားပါသည်။ ပြရန် d-pad ကို နှိပ်ပါ"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"ပြီးပြီ"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"ဆက်လုပ်ရန်"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-nb/strings.xml b/v17/leanback/res/values-nb/strings.xml
index ae3394b..69521f1 100644
--- a/v17/leanback/res/values-nb/strings.xml
+++ b/v17/leanback/res/values-nb/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Aktivér teksting"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Deaktiver teksting"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Slå på modusen Bilde-i-bilde"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Mediekontrollene vises"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Mediekontrollene er skjult – trykk på styrepilene for å vise dem"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Fullfør"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Fortsett"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"."</string>
diff --git a/v17/leanback/res/values-ne/strings.xml b/v17/leanback/res/values-ne/strings.xml
index e8baffb..b012d93 100644
--- a/v17/leanback/res/values-ne/strings.xml
+++ b/v17/leanback/res/values-ne/strings.xml
@@ -50,6 +50,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"बन्द क्याप्सनहरु सक्षम"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"बन्द क्याप्सनहरु असक्षम"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"चित्रलाई चित्र मोडमा प्रविष्ट गर्नुहोस्"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"मिडियाका नियन्त्रणहरू देखाएइका छन्"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"मिडियाका नियन्त्रणहरू लुकेका छन्, देखाउनका लागि d-pad लाई थिच्नुहोस्"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"समाप्त गर्नुहोस्"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"जारी राख्नुहोस्"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-nl/strings.xml b/v17/leanback/res/values-nl/strings.xml
index 0a5bdce..21ae66b 100644
--- a/v17/leanback/res/values-nl/strings.xml
+++ b/v17/leanback/res/values-nl/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Ondertiteling inschakelen"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Ondertiteling uitschakelen"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Beeld-in-beeld-modus openen"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Opties voor mediabediening worden weergegeven"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Opties voor mediabediening verborgen. Druk op de D-pad om ze weer te geven."</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Voltooien"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Doorgaan"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"-"</string>
diff --git a/v17/leanback/res/values-pa/strings.xml b/v17/leanback/res/values-pa/strings.xml
index b8c7591..125058d 100644
--- a/v17/leanback/res/values-pa/strings.xml
+++ b/v17/leanback/res/values-pa/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"ਬੰਦ ਕੈਪਸ਼ਨਿੰਗ ਸਮਰੱਥ ਬਣਾਓ"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"ਬੰਦ ਕੈਪਸ਼ਨਿੰਗ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"ਤਸਵੀਰ ਮੋਡ ਵਿੱਚ ਤਸਵੀਰ ਦਾਖਲ ਕਰੋ"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"ਮੀਡੀਆ ਕੰਟਰੋਲ ਵਿਖਾਏ ਗਏ"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"ਮੀਡੀਆ ਕੰਟਰੋਲ ਲੁਕੇ ਹੋਏ ਹਨ, ਵਿਖਾਉਣ ਲਈ ਡੀ-ਪੈਡ ਦਬਾਓ"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"ਖ਼ਤਮ"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"ਜਾਰੀ ਰੱਖੋ"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-pl/strings.xml b/v17/leanback/res/values-pl/strings.xml
index 15de203..e0e87b5 100644
--- a/v17/leanback/res/values-pl/strings.xml
+++ b/v17/leanback/res/values-pl/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Włącz napisy"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Wyłącz napisy"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Włącz tryb obrazu w obrazie"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Elementy sterujące multimediami są wyświetlone"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Elementy sterujące multimediami są ukryte. Naciśnij pad kierunkowy, by je wyświetlić"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Zakończ"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Dalej"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"."</string>
diff --git a/v17/leanback/res/values-pt-rBR/strings.xml b/v17/leanback/res/values-pt-rBR/strings.xml
index 4621809..ca688bf 100644
--- a/v17/leanback/res/values-pt-rBR/strings.xml
+++ b/v17/leanback/res/values-pt-rBR/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Ativar closed captioning"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Desativar closed captioning"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Entrar no modo Picture in Picture"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Os controles de mídia estão sendo exibidos"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Os controles de mídia estão ocultos. Pressione o botão direcional para exibi-los"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Concluir"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Continuar"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-pt-rPT/strings.xml b/v17/leanback/res/values-pt-rPT/strings.xml
index 0df9c00..2e7dff7 100644
--- a/v17/leanback/res/values-pt-rPT/strings.xml
+++ b/v17/leanback/res/values-pt-rPT/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Ativar legendas"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Desativar legendas"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Entrar no modo Imagem na imagem"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Controlos de multimédia apresentados"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Controlos de multimédia ocultados, prima o teclado direcional para mostrar"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Concluir"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Continuar"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-pt/strings.xml b/v17/leanback/res/values-pt/strings.xml
index 4621809..ca688bf 100644
--- a/v17/leanback/res/values-pt/strings.xml
+++ b/v17/leanback/res/values-pt/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Ativar closed captioning"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Desativar closed captioning"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Entrar no modo Picture in Picture"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Os controles de mídia estão sendo exibidos"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Os controles de mídia estão ocultos. Pressione o botão direcional para exibi-los"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Concluir"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Continuar"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-ro/strings.xml b/v17/leanback/res/values-ro/strings.xml
index 5fa64ef..03c6520 100644
--- a/v17/leanback/res/values-ro/strings.xml
+++ b/v17/leanback/res/values-ro/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Activează subtitrările"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Dezactivează subtitrările"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Activați modul Picture-in-Picture"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Comenzile media sunt afișate"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Comenzile media sunt ascunse. Apăsați pe butonul direcțional pentru a le afișa."</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Finalizați"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Continuați"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-ru/strings.xml b/v17/leanback/res/values-ru/strings.xml
index c7a146f..8f96195 100644
--- a/v17/leanback/res/values-ru/strings.xml
+++ b/v17/leanback/res/values-ru/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Включить субтитры."</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Отключить субтитры."</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Включить режим \"Картинка в картинке\"."</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Элементы управления показаны"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Элементы управления скрыты. Нажмите D-pad, чтобы показать их."</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Готово"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Далее"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"."</string>
diff --git a/v17/leanback/res/values-si/strings.xml b/v17/leanback/res/values-si/strings.xml
index 44e4f31..fb812da 100644
--- a/v17/leanback/res/values-si/strings.xml
+++ b/v17/leanback/res/values-si/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"වැසුණු ශිර්ෂ කිරීම සබල කරන ලදි"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"වැසුණු ශිර්ෂ කිරීම අබල කරන ලදි"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"පින්තූරය-තුළ-පින්තූරය ප්රකාරයට ඇතුළු වන්න"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"මාධ්ය පාලක පෙන්වා ඇත"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"මාධ්ය පාලක සඟවා ඇත, පෙන්වීමට d-pad ඔබන්න"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"අවසානය"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"දිගටම කර ගෙන යන්න"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-sk/strings.xml b/v17/leanback/res/values-sk/strings.xml
index bfd972a..c2f2a0a 100644
--- a/v17/leanback/res/values-sk/strings.xml
+++ b/v17/leanback/res/values-sk/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Zapnúť skryté titulky"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Vypnúť skryté titulky"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Vložiť obrázok v režime obrázka"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Ovládacie prvky médií sa zobrazujú"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Ovládacie prvky médií sú skryté, zobrazíte ich stlačením klávesa d-pad"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Dokončiť"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Pokračovať"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-sl/strings.xml b/v17/leanback/res/values-sl/strings.xml
index 1919b29..6e6c5ae 100644
--- a/v17/leanback/res/values-sl/strings.xml
+++ b/v17/leanback/res/values-sl/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Omogoči podnapise"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Onemogoči podnapise"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Vklop načina za sliko v sliki"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Kontrolniki predstavnosti so prikazani"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Kontrolniki predstavnosti so skriti, za prikaz pritisnite smerni gumb"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Dokončaj"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Naprej"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-sq/strings.xml b/v17/leanback/res/values-sq/strings.xml
index 36cfdf3..b0904ff 100644
--- a/v17/leanback/res/values-sq/strings.xml
+++ b/v17/leanback/res/values-sq/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Aktivizo titrat"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Çaktivizo titrat me sekuencë kohore"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Fut një fotografi në modalitetin e fotografisë"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Kontrollet e medias të shfaqura"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Kontrollet e medias të fshehura, shtyp bllokun e drejtimit për t\'i shfaqur"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Përfundo"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Vazhdo"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-sr/strings.xml b/v17/leanback/res/values-sr/strings.xml
index 1a9a0c4..1b69e08 100644
--- a/v17/leanback/res/values-sr/strings.xml
+++ b/v17/leanback/res/values-sr/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Омогући титлове"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Онемогући титлове"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Уђи у режим Слика у слици"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Контроле за медије су приказане"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Контроле за медије су скривене, притисните контроле за кретање да бисте их приказали"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Доврши"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Настави"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-sv/strings.xml b/v17/leanback/res/values-sv/strings.xml
index 5bdd293..5dce6ff 100644
--- a/v17/leanback/res/values-sv/strings.xml
+++ b/v17/leanback/res/values-sv/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Aktivera textning"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Inaktivera textning"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Ange läget Bild-i-bild"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Mediakontrollerna visas"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Mediakontrollerna är dolda och visas om du trycker på styrkorset"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Slutför"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Fortsätt"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-sw/strings.xml b/v17/leanback/res/values-sw/strings.xml
index 6683e46..a7bfa0f 100644
--- a/v17/leanback/res/values-sw/strings.xml
+++ b/v17/leanback/res/values-sw/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Washa manukuu"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Zima manukuu"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Weka Picha Katika Hali ya Picha"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Inaonyesha udhibiti wa maudhui"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Imeficha udhibiti wa maudhui, bonyeza d-pad ili uuonyeshe"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Kamilisha"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Endelea"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-ta/strings.xml b/v17/leanback/res/values-ta/strings.xml
index 5afde83..7b0ffaf 100644
--- a/v17/leanback/res/values-ta/strings.xml
+++ b/v17/leanback/res/values-ta/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"விரிவான வசனங்களை இயக்கு"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"விரிவான வசனங்களை முடக்கு"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"பிக்ச்சர் இன் பிக்ச்சர் பயன்முறைக்குச் செல்"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"மீடியா கட்டுப்பாடுகள் காட்டப்படுகின்றன"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"மீடியா கட்டுப்பாடுகள் மறைக்கப்பட்டுள்ளன. கட்டுப்பாடுகளைக் காட்ட, டிபேடை அழுத்தவும்"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"முடி"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"தொடர்க"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-te/strings.xml b/v17/leanback/res/values-te/strings.xml
index f74c525..e1b3ba2 100644
--- a/v17/leanback/res/values-te/strings.xml
+++ b/v17/leanback/res/values-te/strings.xml
@@ -48,6 +48,10 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"సంవృత శీర్షికలను ప్రారంభించు"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"సంవృత శీర్షికలను నిలిపివేయి"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"చిత్రంలో చిత్రం మోడ్లోకి ప్రవేశించండి"</string>
+ <!-- no translation found for lb_playback_controls_shown (6382160135512023238) -->
+ <skip />
+ <!-- no translation found for lb_playback_controls_hidden (8940984081242033574) -->
+ <skip />
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"ముగించు"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"కొనసాగించు"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-th/strings.xml b/v17/leanback/res/values-th/strings.xml
index 8440dd9..4e8fea2 100644
--- a/v17/leanback/res/values-th/strings.xml
+++ b/v17/leanback/res/values-th/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"เปิดใช้คำบรรยาย"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"ปิดใช้คำบรรยาย"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"เข้าสู่โหมดการแสดงผลหลายแหล่งพร้อมกัน"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"แสดงการควบคุมสื่ออยู่"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"ซ่อนการควบคุมสื่ออยู่ กด d-pad เพื่อแสดง"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"เสร็จสิ้น"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"ต่อไป"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-tl/strings.xml b/v17/leanback/res/values-tl/strings.xml
index c2f52a4..b2795c2 100644
--- a/v17/leanback/res/values-tl/strings.xml
+++ b/v17/leanback/res/values-tl/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"I-enable ang Paglalagay ng Subtitle"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"I-disable ang Paglalagay ng Subtitle"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Pumasok sa Picture In Picture Mode"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Ipinapakita ang mga kontrol ng media"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Nakatago ang mga kontrol ng media, pindutin ang d-pad upang ipakita"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Tapusin"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Magpatuloy"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-tr/strings.xml b/v17/leanback/res/values-tr/strings.xml
index 0c6431e..611998d 100644
--- a/v17/leanback/res/values-tr/strings.xml
+++ b/v17/leanback/res/values-tr/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Altyazıları Etkinleştir"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Altyazıları Devre Dışı Bırak"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Resim İçinde Resim Moduna Geç"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Medya denetimleri gösteriliyor"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Medya denetimleri gizli durumda. Görüntülemek için d-pad\'e basın."</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Son"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Devam"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"."</string>
diff --git a/v17/leanback/res/values-uk/strings.xml b/v17/leanback/res/values-uk/strings.xml
index bb6bde7..a6ba427 100644
--- a/v17/leanback/res/values-uk/strings.xml
+++ b/v17/leanback/res/values-uk/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Увімкнути субтитри"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Вимкнути субтитри"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Перейти в режим \"Картинка в картинці\""</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Показано елементи керування медіа"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Елементи керування медіа сховано. Натисніть цифрову панель, щоб показати їх"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Закінчити"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Продовжити"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"."</string>
diff --git a/v17/leanback/res/values-ur/strings.xml b/v17/leanback/res/values-ur/strings.xml
index f387aa3..a87ac02 100644
--- a/v17/leanback/res/values-ur/strings.xml
+++ b/v17/leanback/res/values-ur/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"سب ٹائٹلز کو فعال کریں"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"سب ٹائٹلز کو غیر فعال کریں"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"\'تصویر میں تصویر موڈ\' میں داخل ہوں"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"میڈیا کنٹرولز عیاں ہیں"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"میڈیا کنٹرولز مخفی ہیں، شو کرنے کیلئے d-pad دبائیں"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"مکمل کریں"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"جاری رکھیں"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-uz/strings.xml b/v17/leanback/res/values-uz/strings.xml
index 48dc067..c491358 100644
--- a/v17/leanback/res/values-uz/strings.xml
+++ b/v17/leanback/res/values-uz/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Taglavhalarni yoqish"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Taglavhalarni o‘chirib qo‘yish"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Tasvir ichida tasvir rejimiga kirish"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Boshqaruv elementlari ko‘rsatilgan"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Boshqaruv elementlari yashirilgan, ko‘rsatish uchun D-pad tugmasini bosing"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Tugatish"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Davom etish"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-vi/strings.xml b/v17/leanback/res/values-vi/strings.xml
index 8d8c282..296f0e8 100644
--- a/v17/leanback/res/values-vi/strings.xml
+++ b/v17/leanback/res/values-vi/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Bật phụ đề"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Tắt phụ đề"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Vào ảnh ở chế độ ảnh"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Điều khiển phương tiện được hiển thị"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Điều khiển phương tiện bị ẩn, nhấn d-pad để hiển thị"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Hoàn tất"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Tiếp tục"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-zh-rCN/strings.xml b/v17/leanback/res/values-zh-rCN/strings.xml
index 611bff1..8d7ebc0 100644
--- a/v17/leanback/res/values-zh-rCN/strings.xml
+++ b/v17/leanback/res/values-zh-rCN/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"开启字幕"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"关闭字幕"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"进入画中画模式"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"媒体控件已显示"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"媒体控件已隐藏,按 D-pad 即可显示"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"完成"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"继续"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-zh-rHK/strings.xml b/v17/leanback/res/values-zh-rHK/strings.xml
index c18032e..6e6688e 100644
--- a/v17/leanback/res/values-zh-rHK/strings.xml
+++ b/v17/leanback/res/values-zh-rHK/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"啟用字幕"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"停用字幕"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"進入「畫中畫模式」"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"畫面已顯示媒體控制項"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"畫面已隱藏媒體控制項,按十字鍵即可顯示"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"完成"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"繼續"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-zh-rTW/strings.xml b/v17/leanback/res/values-zh-rTW/strings.xml
index 1e14d0a..cdbdaa2 100644
--- a/v17/leanback/res/values-zh-rTW/strings.xml
+++ b/v17/leanback/res/values-zh-rTW/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"啟用字幕"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"停用字幕"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"進入子母畫面模式"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"媒體控制項已顯示"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"媒體控制項已隱藏,按下 D-Pad 即可顯示"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"完成"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"繼續"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values-zu/strings.xml b/v17/leanback/res/values-zu/strings.xml
index 7fb290f..d62005b 100644
--- a/v17/leanback/res/values-zu/strings.xml
+++ b/v17/leanback/res/values-zu/strings.xml
@@ -48,6 +48,8 @@
<string name="lb_playback_controls_closed_captioning_enable" msgid="2429655367176440226">"Nika amandla imibhalo engezansi"</string>
<string name="lb_playback_controls_closed_captioning_disable" msgid="6133362019475930048">"Khubaza imihbalo engezansi"</string>
<string name="lb_playback_controls_picture_in_picture" msgid="3040035547765350690">"Ngena isithombe kumodi yesithombe"</string>
+ <string name="lb_playback_controls_shown" msgid="6382160135512023238">"Izilawuli zemidiya zibonisiwe"</string>
+ <string name="lb_playback_controls_hidden" msgid="8940984081242033574">"Izilawuli zemidiya zifihliwe, cindezela ku-d-pad ukuze uzibonise"</string>
<string name="lb_guidedaction_finish_title" msgid="4015190340667946245">"Qeda"</string>
<string name="lb_guidedaction_continue_title" msgid="8842094924543063706">"Qhubeka"</string>
<string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
diff --git a/v17/leanback/res/values/dimens.xml b/v17/leanback/res/values/dimens.xml
index 8d174be..4bf237d 100644
--- a/v17/leanback/res/values/dimens.xml
+++ b/v17/leanback/res/values/dimens.xml
@@ -124,9 +124,11 @@
<dimen name="lb_action_text_size">16sp</dimen>
<dimen name="lb_action_button_corner_radius">2dp</dimen>
- <dimen name="lb_playback_controls_align_bottom">58dp</dimen>
- <dimen name="lb_playback_controls_padding_top">216dp</dimen>
+ <!-- distance of bottom of playback row to bottom edge, used for overscan protection and
+ peeking related rows-->
<dimen name="lb_playback_controls_padding_bottom">28dp</dimen>
+ <!-- distance of other rows' center to bottom edge, half of screen by default -->
+ <dimen name="lb_playback_other_rows_center_to_bottom">270dp</dimen>
<dimen name="lb_playback_major_fade_translate_y">200dp</dimen>
<dimen name="lb_playback_minor_fade_translate_y">16dp</dimen>
<dimen name="lb_playback_controls_card_height">176dp</dimen>
diff --git a/v17/leanback/res/values/strings.xml b/v17/leanback/res/values/strings.xml
index 1ca09dd..cbf4904 100644
--- a/v17/leanback/res/values/strings.xml
+++ b/v17/leanback/res/values/strings.xml
@@ -81,6 +81,10 @@
<!-- Talkback label for the control button to enter picture in picture mode -->
<string name="lb_playback_controls_picture_in_picture">Enter Picture In Picture Mode</string>
+
+ <string name="lb_playback_controls_shown">Media controls shown</string>
+ <string name="lb_playback_controls_hidden">Media controls hidden, press d-pad to show</string>
+
<!-- Title of standard Finish action for GuidedStepFragment -->
<string name="lb_guidedaction_finish_title">Finish</string>
<!-- Title of standard Continue action for GuidedStepFragment -->
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
index 1c9e5ca..ed20153 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
@@ -578,7 +578,7 @@
* against {@link PageRow}.
*/
public final static class MainFragmentAdapterRegistry {
- private final Map<Class, FragmentFactory> mItemToFragmentFactoryMapping = new HashMap();
+ private final Map<Class, FragmentFactory> mItemToFragmentFactoryMapping = new HashMap<>();
private final static FragmentFactory sDefaultFragmentFactory = new ListRowFragmentFactory();
public MainFragmentAdapterRegistry() {
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
index c7d8de4..43e10b2 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
@@ -581,7 +581,7 @@
* against {@link PageRow}.
*/
public final static class MainFragmentAdapterRegistry {
- private final Map<Class, FragmentFactory> mItemToFragmentFactoryMapping = new HashMap();
+ private final Map<Class, FragmentFactory> mItemToFragmentFactoryMapping = new HashMap<>();
private final static FragmentFactory sDefaultFragmentFactory = new ListRowFragmentFactory();
public MainFragmentAdapterRegistry() {
diff --git a/v17/leanback/src/android/support/v17/leanback/app/DetailsBackgroundVideoHelper.java b/v17/leanback/src/android/support/v17/leanback/app/DetailsBackgroundVideoHelper.java
index 37a6bfc..5e2980d 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/DetailsBackgroundVideoHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/DetailsBackgroundVideoHelper.java
@@ -88,8 +88,6 @@
mParallaxEffect = mDetailsParallax
.addEffect(frameTop.atFraction(maxFrameTop), frameTop.atFraction(minFrameTop))
.target(new ParallaxTarget() {
-
- float mFraction;
@Override
public void update(float fraction) {
if (fraction == maxFrameTop) {
@@ -97,12 +95,6 @@
} else {
updateState(PLAY_VIDEO);
}
- mFraction = fraction;
- }
-
- @Override
- public float getFraction() {
- return mFraction;
}
});
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/DetailsFragment.java b/v17/leanback/src/android/support/v17/leanback/app/DetailsFragment.java
index 9438ce5..00a1ace 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/DetailsFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/DetailsFragment.java
@@ -126,7 +126,7 @@
final WeakReference<DetailsFragment> mRef;
WaitEnterTransitionTimeout(DetailsFragment f) {
- mRef = new WeakReference(f);
+ mRef = new WeakReference<>(f);
f.getView().postDelayed(this, WAIT_ENTERTRANSITION_START);
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragment.java
index 79ab727..eb78840 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragment.java
@@ -129,7 +129,7 @@
final WeakReference<DetailsSupportFragment> mRef;
WaitEnterTransitionTimeout(DetailsSupportFragment f) {
- mRef = new WeakReference(f);
+ mRef = new WeakReference<>(f);
f.getView().postDelayed(this, WAIT_ENTERTRANSITION_START);
}
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 8d6367a..ed4d822 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackFragment.java
@@ -33,6 +33,7 @@
import android.support.v17.leanback.widget.BaseOnItemViewClickedListener;
import android.support.v17.leanback.widget.BaseOnItemViewSelectedListener;
import android.support.v17.leanback.widget.ClassPresenterSelector;
+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.PlaybackRowPresenter;
@@ -40,6 +41,7 @@
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.support.v17.leanback.widget.VerticalGridView;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
@@ -62,8 +64,12 @@
* 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.
+ * A playback row is a row rendered by {@link PlaybackRowPresenter}.
+ * App can call {@link #setPlaybackRow(Row)} to set playback row for the first element of adapter.
+ * App can call {@link #setPlaybackRowPresenter(PlaybackRowPresenter)} to set presenter for it.
+ * {@link #setPlaybackRow(Row)} and {@link #setPlaybackRowPresenter(PlaybackRowPresenter)} are
+ * optional, app can pass playback row and PlaybackRowPresenter in the adapter using
+ * {@link #setAdapter(ObjectAdapter)}.
* </p>
*/
public class PlaybackFragment extends Fragment {
@@ -179,8 +185,8 @@
private static final int IN = 1;
private static final int OUT = 2;
- private int mPaddingTop;
private int mPaddingBottom;
+ private int mOtherRowsCenterToBottom;
private View mRootView;
private int mBackgroundType = BG_DARK;
private int mBgDarkColor;
@@ -594,6 +600,8 @@
mOtherRowFadeInAnimator.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.
@@ -633,31 +641,30 @@
if (listview == null) {
return;
}
- // Padding affects alignment when last row is focused
- // (last is first when there's only one row).
- setPadding(listview, mPaddingTop, mPaddingBottom);
- // Item alignment affects focused row that isn't the last.
- listview.setItemAlignmentOffset(0);
+ // 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 rows to the bottom.
- listview.setWindowAlignmentOffset(0);
- listview.setWindowAlignmentOffsetPercent(50);
- listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_BOTH_EDGE);
- }
-
- private static void setPadding(View view, int paddingTop, int paddingBottom) {
- view.setPadding(view.getPaddingLeft(), paddingTop,
- view.getPaddingRight(), paddingBottom);
+ // 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);
- mPaddingTop =
- getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_top);
+ mOtherRowsCenterToBottom = getResources()
+ .getDimensionPixelSize(R.dimen.lb_playback_other_rows_center_to_bottom);
mPaddingBottom =
getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom);
mBgDarkColor =
@@ -844,7 +851,9 @@
}
/**
- * Sets the playback row for the playback controls.
+ * Sets the playback row for the playback controls. The row will be set as first element
+ * of adapter if the adapter is {@link ArrayObjectAdapter} or {@link SparseArrayObjectAdapter}.
+ * @param row The row that represents the playback.
*/
public void setPlaybackRow(Row row) {
this.mRow = row;
@@ -853,11 +862,38 @@
}
/**
- * Sets the presenter for rendering the playback controls.
+ * Sets the presenter for rendering the playback row set by {@link #setPlaybackRow(Row)}. If
+ * adapter does not set a {@link PresenterSelector}, {@link #setAdapter(ObjectAdapter)} will
+ * create a {@link ClassPresenterSelector} by default and map from the row object class to this
+ * {@link PlaybackRowPresenter}.
+ *
+ * @param presenter Presenter used to render {@link #setPlaybackRow(Row)}.
*/
public void setPlaybackRowPresenter(PlaybackRowPresenter presenter) {
this.mPresenter = presenter;
setupPresenter();
+ setPlaybackRowPresenterAlignment();
+ }
+
+ void setPlaybackRowPresenterAlignment() {
+ if (mAdapter != null && mAdapter.getPresenterSelector() != null) {
+ Presenter[] presenters = mAdapter.getPresenterSelector().getPresenters();
+ if (presenters != null) {
+ for (int i = 0; i < presenters.length; i++) {
+ if (presenters[i] instanceof PlaybackRowPresenter
+ && presenters[i].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});
+ presenters[i].setFacet(ItemAlignmentFacet.class, itemAlignment);
+ }
+ }
+ }
+ }
}
/**
@@ -871,12 +907,19 @@
}
/**
- * Sets the list of rows for the fragment.
+ * Sets the list of rows for the fragment. A default {@link ClassPresenterSelector} will be
+ * created if {@link ObjectAdapter#getPresenterSelector()} is null. if user provides
+ * {@link #setPlaybackRow(Row)} and {@link #setPlaybackRowPresenter(PlaybackRowPresenter)},
+ * the row and presenter will be set onto the adapter.
+ *
+ * @param adapter The adapter that contains related rows and optional playback row.
*/
public void setAdapter(ObjectAdapter adapter) {
mAdapter = adapter;
setupRow();
setupPresenter();
+ setPlaybackRowPresenterAlignment();
+
if (mRowsFragment != null) {
mRowsFragment.setAdapter(adapter);
}
@@ -890,6 +933,9 @@
} else {
adapter.replace(0, mRow);
}
+ } else if (mAdapter instanceof SparseArrayObjectAdapter && mRow != null) {
+ SparseArrayObjectAdapter adapter = ((SparseArrayObjectAdapter) mAdapter);
+ adapter.set(0, mRow);
}
}
@@ -898,10 +944,9 @@
PresenterSelector selector = mAdapter.getPresenterSelector();
if (selector == null) {
selector = new ClassPresenterSelector();
+ ((ClassPresenterSelector) selector).addClassPresenter(mRow.getClass(), mPresenter);
mAdapter.setPresenterSelector(selector);
- }
-
- if (selector instanceof ClassPresenterSelector) {
+ } else if (selector instanceof ClassPresenterSelector) {
((ClassPresenterSelector) selector).addClassPresenter(mRow.getClass(), mPresenter);
}
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
index c601b2e..c934f6b 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
@@ -28,10 +28,12 @@
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;
@@ -105,7 +107,7 @@
private static final int IN = 1;
static final int OUT = 2;
- private int mPaddingTop;
+ private int mOtherRowsCenterToBottom;
private int mPaddingBottom;
private View mRootView;
private int mBackgroundType = BG_DARK;
@@ -610,6 +612,8 @@
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.
@@ -638,35 +642,52 @@
}
@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;
}
- // Padding affects alignment when last row is focused
- // (last is first when there's only one row).
- setPadding(listview, mPaddingTop, mPaddingBottom);
- // Item alignment affects focused row that isn't the last.
- listview.setItemAlignmentOffset(0);
+ // 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 rows to the bottom.
- listview.setWindowAlignmentOffset(0);
- listview.setWindowAlignmentOffsetPercent(50);
- listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_BOTH_EDGE);
- }
-
- private static void setPadding(View view, int paddingTop, int paddingBottom) {
- view.setPadding(view.getPaddingLeft(), paddingTop,
- view.getPaddingRight(), paddingBottom);
+ // 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);
- mPaddingTop =
- getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_top);
+ mOtherRowsCenterToBottom = getResources()
+ .getDimensionPixelSize(R.dimen.lb_playback_other_rows_center_to_bottom);
mPaddingBottom =
getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom);
mBgDarkColor =
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
index b4df936..ecabdaa 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
@@ -31,10 +31,12 @@
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;
@@ -108,7 +110,7 @@
private static final int IN = 1;
static final int OUT = 2;
- private int mPaddingTop;
+ private int mOtherRowsCenterToBottom;
private int mPaddingBottom;
private View mRootView;
private int mBackgroundType = BG_DARK;
@@ -613,6 +615,8 @@
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.
@@ -641,35 +645,52 @@
}
@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;
}
- // Padding affects alignment when last row is focused
- // (last is first when there's only one row).
- setPadding(listview, mPaddingTop, mPaddingBottom);
- // Item alignment affects focused row that isn't the last.
- listview.setItemAlignmentOffset(0);
+ // 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 rows to the bottom.
- listview.setWindowAlignmentOffset(0);
- listview.setWindowAlignmentOffsetPercent(50);
- listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_BOTH_EDGE);
- }
-
- private static void setPadding(View view, int paddingTop, int paddingBottom) {
- view.setPadding(view.getPaddingLeft(), paddingTop,
- view.getPaddingRight(), paddingBottom);
+ // 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);
- mPaddingTop =
- getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_top);
+ mOtherRowsCenterToBottom = getResources()
+ .getDimensionPixelSize(R.dimen.lb_playback_other_rows_center_to_bottom);
mPaddingBottom =
getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom);
mBgDarkColor =
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackSupportFragment.java
index 3133264..2e39904 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackSupportFragment.java
@@ -36,6 +36,7 @@
import android.support.v17.leanback.widget.BaseOnItemViewClickedListener;
import android.support.v17.leanback.widget.BaseOnItemViewSelectedListener;
import android.support.v17.leanback.widget.ClassPresenterSelector;
+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.PlaybackRowPresenter;
@@ -43,6 +44,7 @@
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.support.v17.leanback.widget.VerticalGridView;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
@@ -65,8 +67,12 @@
* 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.
+ * A playback row is a row rendered by {@link PlaybackRowPresenter}.
+ * App can call {@link #setPlaybackRow(Row)} to set playback row for the first element of adapter.
+ * App can call {@link #setPlaybackRowPresenter(PlaybackRowPresenter)} to set presenter for it.
+ * {@link #setPlaybackRow(Row)} and {@link #setPlaybackRowPresenter(PlaybackRowPresenter)} are
+ * optional, app can pass playback row and PlaybackRowPresenter in the adapter using
+ * {@link #setAdapter(ObjectAdapter)}.
* </p>
*/
public class PlaybackSupportFragment extends Fragment {
@@ -182,8 +188,8 @@
private static final int IN = 1;
private static final int OUT = 2;
- private int mPaddingTop;
private int mPaddingBottom;
+ private int mOtherRowsCenterToBottom;
private View mRootView;
private int mBackgroundType = BG_DARK;
private int mBgDarkColor;
@@ -597,6 +603,8 @@
mOtherRowFadeInAnimator.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.
@@ -636,31 +644,30 @@
if (listview == null) {
return;
}
- // Padding affects alignment when last row is focused
- // (last is first when there's only one row).
- setPadding(listview, mPaddingTop, mPaddingBottom);
- // Item alignment affects focused row that isn't the last.
- listview.setItemAlignmentOffset(0);
+ // 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 rows to the bottom.
- listview.setWindowAlignmentOffset(0);
- listview.setWindowAlignmentOffsetPercent(50);
- listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_BOTH_EDGE);
- }
-
- private static void setPadding(View view, int paddingTop, int paddingBottom) {
- view.setPadding(view.getPaddingLeft(), paddingTop,
- view.getPaddingRight(), paddingBottom);
+ // 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);
- mPaddingTop =
- getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_top);
+ mOtherRowsCenterToBottom = getResources()
+ .getDimensionPixelSize(R.dimen.lb_playback_other_rows_center_to_bottom);
mPaddingBottom =
getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom);
mBgDarkColor =
@@ -847,7 +854,9 @@
}
/**
- * Sets the playback row for the playback controls.
+ * Sets the playback row for the playback controls. The row will be set as first element
+ * of adapter if the adapter is {@link ArrayObjectAdapter} or {@link SparseArrayObjectAdapter}.
+ * @param row The row that represents the playback.
*/
public void setPlaybackRow(Row row) {
this.mRow = row;
@@ -856,11 +865,38 @@
}
/**
- * Sets the presenter for rendering the playback controls.
+ * Sets the presenter for rendering the playback row set by {@link #setPlaybackRow(Row)}. If
+ * adapter does not set a {@link PresenterSelector}, {@link #setAdapter(ObjectAdapter)} will
+ * create a {@link ClassPresenterSelector} by default and map from the row object class to this
+ * {@link PlaybackRowPresenter}.
+ *
+ * @param presenter Presenter used to render {@link #setPlaybackRow(Row)}.
*/
public void setPlaybackRowPresenter(PlaybackRowPresenter presenter) {
this.mPresenter = presenter;
setupPresenter();
+ setPlaybackRowPresenterAlignment();
+ }
+
+ void setPlaybackRowPresenterAlignment() {
+ if (mAdapter != null && mAdapter.getPresenterSelector() != null) {
+ Presenter[] presenters = mAdapter.getPresenterSelector().getPresenters();
+ if (presenters != null) {
+ for (int i = 0; i < presenters.length; i++) {
+ if (presenters[i] instanceof PlaybackRowPresenter
+ && presenters[i].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});
+ presenters[i].setFacet(ItemAlignmentFacet.class, itemAlignment);
+ }
+ }
+ }
+ }
}
/**
@@ -874,12 +910,19 @@
}
/**
- * Sets the list of rows for the fragment.
+ * Sets the list of rows for the fragment. A default {@link ClassPresenterSelector} will be
+ * created if {@link ObjectAdapter#getPresenterSelector()} is null. if user provides
+ * {@link #setPlaybackRow(Row)} and {@link #setPlaybackRowPresenter(PlaybackRowPresenter)},
+ * the row and presenter will be set onto the adapter.
+ *
+ * @param adapter The adapter that contains related rows and optional playback row.
*/
public void setAdapter(ObjectAdapter adapter) {
mAdapter = adapter;
setupRow();
setupPresenter();
+ setPlaybackRowPresenterAlignment();
+
if (mRowsSupportFragment != null) {
mRowsSupportFragment.setAdapter(adapter);
}
@@ -893,6 +936,9 @@
} else {
adapter.replace(0, mRow);
}
+ } else if (mAdapter instanceof SparseArrayObjectAdapter && mRow != null) {
+ SparseArrayObjectAdapter adapter = ((SparseArrayObjectAdapter) mAdapter);
+ adapter.set(0, mRow);
}
}
@@ -901,10 +947,9 @@
PresenterSelector selector = mAdapter.getPresenterSelector();
if (selector == null) {
selector = new ClassPresenterSelector();
+ ((ClassPresenterSelector) selector).addClassPresenter(mRow.getClass(), mPresenter);
mAdapter.setPresenterSelector(selector);
- }
-
- if (selector instanceof ClassPresenterSelector) {
+ } else if (selector instanceof ClassPresenterSelector) {
((ClassPresenterSelector) selector).addClassPresenter(mRow.getClass(), mPresenter);
}
}
diff --git a/v17/leanback/src/android/support/v17/leanback/graphics/BoundsRule.java b/v17/leanback/src/android/support/v17/leanback/graphics/BoundsRule.java
index 75ab391..700f7f0 100644
--- a/v17/leanback/src/android/support/v17/leanback/graphics/BoundsRule.java
+++ b/v17/leanback/src/android/support/v17/leanback/graphics/BoundsRule.java
@@ -23,88 +23,87 @@
* rectangular bound - left/top/right/bottom.
*/
public class BoundsRule {
- static final int INHERIT_PARENT = 0;
- static final int ABSOLUTE_VALUE = 1;
- static final int INHERIT_WITH_OFFSET = 2;
/**
- * This class represents individual rules for updating the bounds. Currently we support
- * 3 different rule types -
- *
- * <ul>
- * <li>inheritFromParent: it applies a percentage to the parent property to compute
- * the final value </li>
- * <li>absoluteValue: it always used the supplied absolute value</li>
- * <li>inheritFromParentWithOffset: this uses a combination of INHERIT_PARENT
- * and ABSOLUTE_VALUE. First it applies the percentage on the parent and then adds the
- * offset to compute the final value</li>
- * </ul>
+ * This class represents individual rules for updating the bounds.
*/
public final static class ValueRule {
- private final int type;
- private float fraction;
- private int absoluteValue;
+ float mFraction;
+ int mAbsoluteValue;
- ValueRule(int type, int absoluteValue, float fraction) {
- this.type = type;
- this.absoluteValue = absoluteValue;
- this.fraction = fraction;
+ /**
+ * Creates ValueRule using a fraction of parent size.
+ *
+ * @param fraction Percentage of parent.
+ * @return Newly created ValueRule.
+ */
+ public static ValueRule inheritFromParent(float fraction) {
+ return new ValueRule(0, fraction);
+ }
+
+ /**
+ * Creates ValueRule using an absolute value.
+ *
+ * @param absoluteValue Absolute value.
+ * @return Newly created ValueRule.
+ */
+ public static ValueRule absoluteValue(int absoluteValue) {
+ return new ValueRule(absoluteValue, 0);
+ }
+
+ /**
+ * Creates ValueRule of fraction and offset.
+ *
+ * @param fraction Percentage of parent.
+ * @param value Offset
+ * @return Newly created ValueRule.
+ */
+ public static ValueRule inheritFromParentWithOffset(float fraction, int value) {
+ return new ValueRule(value, fraction);
+ }
+
+ ValueRule(int absoluteValue, float fraction) {
+ this.mAbsoluteValue = absoluteValue;
+ this.mFraction = fraction;
}
ValueRule(ValueRule rule) {
- this.type = rule.type;
- this.fraction = rule.fraction;
- this.absoluteValue = rule.absoluteValue;
+ this.mFraction = rule.mFraction;
+ this.mAbsoluteValue = rule.mAbsoluteValue;
}
/**
* Sets the fractional value (percentage of parent) for this rule.
+ *
+ * @param fraction Percentage of parent.
*/
public void setFraction(float fraction) {
- this.fraction = fraction;
+ this.mFraction = fraction;
}
/**
- * Returns the current fractional value.
+ * @return The current fractional value.
*/
public float getFraction() {
- return fraction;
+ return mFraction;
}
/**
- * Sets the absolute value for this rule.
+ * Sets the absolute/offset value for rule.
+ *
+ * @param absoluteValue Absolute value.
*/
public void setAbsoluteValue(int absoluteValue) {
- this.absoluteValue = absoluteValue;
+ this.mAbsoluteValue = absoluteValue;
}
/**
- * Returns the current absolute value.
+ * @return The current absolute/offset value forrule.
*/
public int getAbsoluteValue() {
- return absoluteValue;
+ return mAbsoluteValue;
}
- }
- /**
- * Factory method for creating ValueRule of type INHERIT_FROM_PARENT.
- */
- public static ValueRule inheritFromParent(float fraction) {
- return new ValueRule(INHERIT_PARENT, 0, fraction);
- }
-
- /**
- * Factory method for creating ValueRule of type ABSOLUTE_VALUE.
- */
- public static ValueRule absoluteValue(int value) {
- return new ValueRule(ABSOLUTE_VALUE, value, 0);
- }
-
- /**
- * Factory method for creating ValueRule of type INHERIT_WITH_OFFSET.
- */
- public static ValueRule inheritFromParentWithOffset(float fraction, int value) {
- return new ValueRule(INHERIT_WITH_OFFSET, value, fraction);
}
/**
@@ -150,17 +149,7 @@
}
private int doCalculate(int value, ValueRule rule, int size) {
- int offset = 0;
- switch(rule.type) {
- case INHERIT_WITH_OFFSET:
- offset = rule.absoluteValue;
- case INHERIT_PARENT:
- return value + offset + (int)(rule.fraction * size);
- case ABSOLUTE_VALUE:
- return rule.absoluteValue;
- }
-
- throw new IllegalArgumentException("Invalid type: "+rule.type);
+ return value + rule.mAbsoluteValue + (int) (rule.mFraction * size);
}
/** {@link ValueRule} for left attribute of {@link BoundsRule} */
diff --git a/v17/leanback/src/android/support/v17/leanback/graphics/CompositeDrawable.java b/v17/leanback/src/android/support/v17/leanback/graphics/CompositeDrawable.java
index edbca3c..4b68e69 100644
--- a/v17/leanback/src/android/support/v17/leanback/graphics/CompositeDrawable.java
+++ b/v17/leanback/src/android/support/v17/leanback/graphics/CompositeDrawable.java
@@ -21,8 +21,8 @@
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.os.Build;
import android.support.annotation.NonNull;
+import android.support.v17.leanback.graphics.BoundsRule.ValueRule;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.util.Property;
@@ -318,7 +318,7 @@
@Override
public void set(CompositeDrawable.ChildDrawable obj, Integer value) {
if (obj.getBoundsRule().top == null) {
- obj.getBoundsRule().top = BoundsRule.absoluteValue(value);
+ obj.getBoundsRule().top = ValueRule.absoluteValue(value);
} else {
obj.getBoundsRule().top.setAbsoluteValue(value);
}
@@ -344,7 +344,7 @@
@Override
public void set(CompositeDrawable.ChildDrawable obj, Integer value) {
if (obj.getBoundsRule().bottom == null) {
- obj.getBoundsRule().bottom = BoundsRule.absoluteValue(value);
+ obj.getBoundsRule().bottom = ValueRule.absoluteValue(value);
} else {
obj.getBoundsRule().bottom.setAbsoluteValue(value);
}
@@ -371,7 +371,7 @@
@Override
public void set(CompositeDrawable.ChildDrawable obj, Integer value) {
if (obj.getBoundsRule().left == null) {
- obj.getBoundsRule().left = BoundsRule.absoluteValue(value);
+ obj.getBoundsRule().left = ValueRule.absoluteValue(value);
} else {
obj.getBoundsRule().left.setAbsoluteValue(value);
}
@@ -397,7 +397,7 @@
@Override
public void set(CompositeDrawable.ChildDrawable obj, Integer value) {
if (obj.getBoundsRule().right == null) {
- obj.getBoundsRule().right = BoundsRule.absoluteValue(value);
+ obj.getBoundsRule().right = ValueRule.absoluteValue(value);
} else {
obj.getBoundsRule().right.setAbsoluteValue(value);
}
@@ -426,7 +426,7 @@
@Override
public void set(CompositeDrawable.ChildDrawable obj, Float value) {
if (obj.getBoundsRule().top == null) {
- obj.getBoundsRule().top = BoundsRule.inheritFromParent(value);
+ obj.getBoundsRule().top = ValueRule.inheritFromParent(value);
} else {
obj.getBoundsRule().top.setFraction(value);
}
@@ -456,7 +456,7 @@
@Override
public void set(CompositeDrawable.ChildDrawable obj, Float value) {
if (obj.getBoundsRule().bottom == null) {
- obj.getBoundsRule().bottom = BoundsRule.inheritFromParent(value);
+ obj.getBoundsRule().bottom = ValueRule.inheritFromParent(value);
} else {
obj.getBoundsRule().bottom.setFraction(value);
}
@@ -485,7 +485,7 @@
@Override
public void set(CompositeDrawable.ChildDrawable obj, Float value) {
if (obj.getBoundsRule().left == null) {
- obj.getBoundsRule().left = BoundsRule.inheritFromParent(value);
+ obj.getBoundsRule().left = ValueRule.inheritFromParent(value);
} else {
obj.getBoundsRule().left.setFraction(value);
}
@@ -510,11 +510,11 @@
* isn't available at compile time.
*/
public static final Property<CompositeDrawable.ChildDrawable, Float> RIGHT_FRACTION =
- new Property<CompositeDrawable.ChildDrawable, Float>(Float.class, "fractoinRight") {
+ new Property<CompositeDrawable.ChildDrawable, Float>(Float.class, "fractionRight") {
@Override
public void set(CompositeDrawable.ChildDrawable obj, Float value) {
if (obj.getBoundsRule().right == null) {
- obj.getBoundsRule().right = BoundsRule.inheritFromParent(value);
+ obj.getBoundsRule().right = ValueRule.inheritFromParent(value);
} else {
obj.getBoundsRule().right.setFraction(value);
}
diff --git a/v17/leanback/src/android/support/v17/leanback/media/PlaybackControlGlue.java b/v17/leanback/src/android/support/v17/leanback/media/PlaybackControlGlue.java
index 215ba22..9af9302 100644
--- a/v17/leanback/src/android/support/v17/leanback/media/PlaybackControlGlue.java
+++ b/v17/leanback/src/android/support/v17/leanback/media/PlaybackControlGlue.java
@@ -535,6 +535,7 @@
private void updateControlsRow() {
updateRowMetadata();
+ updateControlButtons();
sHandler.removeMessages(MSG_UPDATE_PLAYBACK_STATE, mGlueWeakReference);
updatePlaybackState();
}
@@ -591,6 +592,49 @@
}
}
+ void updateControlButtons() {
+ final SparseArrayObjectAdapter primaryActionsAdapter = (SparseArrayObjectAdapter)
+ getControlsRow().getPrimaryActionsAdapter();
+ final long actions = getSupportedActions();
+ if ((actions & ACTION_SKIP_TO_PREVIOUS) != 0 && mSkipPreviousAction == null) {
+ mSkipPreviousAction = new PlaybackControlsRow.SkipPreviousAction(getContext());
+ primaryActionsAdapter.set(ACTION_SKIP_TO_PREVIOUS, mSkipPreviousAction);
+ } else if ((actions & ACTION_SKIP_TO_PREVIOUS) == 0 && mSkipPreviousAction != null) {
+ primaryActionsAdapter.clear(ACTION_SKIP_TO_PREVIOUS);
+ mSkipPreviousAction = null;
+ }
+ if ((actions & ACTION_REWIND) != 0 && mRewindAction == null) {
+ mRewindAction = new PlaybackControlsRow.RewindAction(getContext(),
+ mRewindSpeeds.length);
+ primaryActionsAdapter.set(ACTION_REWIND, mRewindAction);
+ } else if ((actions & ACTION_REWIND) == 0 && mRewindAction != null) {
+ primaryActionsAdapter.clear(ACTION_REWIND);
+ mRewindAction = null;
+ }
+ if ((actions & ACTION_PLAY_PAUSE) != 0 && mPlayPauseAction == null) {
+ mPlayPauseAction = new PlaybackControlsRow.PlayPauseAction(getContext());
+ primaryActionsAdapter.set(ACTION_PLAY_PAUSE, mPlayPauseAction);
+ } else if ((actions & ACTION_PLAY_PAUSE) == 0 && mPlayPauseAction != null) {
+ primaryActionsAdapter.clear(ACTION_PLAY_PAUSE);
+ mPlayPauseAction = null;
+ }
+ if ((actions & ACTION_FAST_FORWARD) != 0 && mFastForwardAction == null) {
+ mFastForwardAction = new PlaybackControlsRow.FastForwardAction(getContext(),
+ mFastForwardSpeeds.length);
+ primaryActionsAdapter.set(ACTION_FAST_FORWARD, mFastForwardAction);
+ } else if ((actions & ACTION_FAST_FORWARD) == 0 && mFastForwardAction != null) {
+ primaryActionsAdapter.clear(ACTION_FAST_FORWARD);
+ mFastForwardAction = null;
+ }
+ if ((actions & ACTION_SKIP_TO_NEXT) != 0 && mSkipNextAction == null) {
+ mSkipNextAction = new PlaybackControlsRow.SkipNextAction(getContext());
+ primaryActionsAdapter.set(ACTION_SKIP_TO_NEXT, mSkipNextAction);
+ } else if ((actions & ACTION_SKIP_TO_NEXT) == 0 && mSkipNextAction != null) {
+ primaryActionsAdapter.clear(ACTION_SKIP_TO_NEXT);
+ mSkipNextAction = null;
+ }
+ }
+
private void updatePlaybackState(int playbackSpeed) {
if (mControlsRow == null) {
return;
@@ -598,56 +642,6 @@
final SparseArrayObjectAdapter primaryActionsAdapter = (SparseArrayObjectAdapter)
getControlsRow().getPrimaryActionsAdapter();
- final long actions = getSupportedActions();
- if ((actions & ACTION_SKIP_TO_PREVIOUS) != 0) {
- if (mSkipPreviousAction == null) {
- mSkipPreviousAction = new PlaybackControlsRow.SkipPreviousAction(getContext());
- }
- primaryActionsAdapter.set(ACTION_SKIP_TO_PREVIOUS, mSkipPreviousAction);
- } else {
- primaryActionsAdapter.clear(ACTION_SKIP_TO_PREVIOUS);
- mSkipPreviousAction = null;
- }
- if ((actions & ACTION_REWIND) != 0) {
- if (mRewindAction == null) {
- mRewindAction = new PlaybackControlsRow.RewindAction(
- getContext(),
- mRewindSpeeds.length);
- }
- primaryActionsAdapter.set(ACTION_REWIND, mRewindAction);
- } else {
- primaryActionsAdapter.clear(ACTION_REWIND);
- mRewindAction = null;
- }
- if ((actions & ACTION_PLAY_PAUSE) != 0) {
- if (mPlayPauseAction == null) {
- mPlayPauseAction = new PlaybackControlsRow.PlayPauseAction(getContext());
- }
- primaryActionsAdapter.set(ACTION_PLAY_PAUSE, mPlayPauseAction);
- } else {
- primaryActionsAdapter.clear(ACTION_PLAY_PAUSE);
- mPlayPauseAction = null;
- }
- if ((actions & ACTION_FAST_FORWARD) != 0) {
- if (mFastForwardAction == null) {
- mFastForwardAction = new PlaybackControlsRow.FastForwardAction(
- getContext(),
- mFastForwardSpeeds.length);
- }
- primaryActionsAdapter.set(ACTION_FAST_FORWARD, mFastForwardAction);
- } else {
- primaryActionsAdapter.clear(ACTION_FAST_FORWARD);
- mFastForwardAction = null;
- }
- if ((actions & ACTION_SKIP_TO_NEXT) != 0) {
- if (mSkipNextAction == null) {
- mSkipNextAction = new PlaybackControlsRow.SkipNextAction(getContext());
- }
- primaryActionsAdapter.set(ACTION_SKIP_TO_NEXT, mSkipNextAction);
- } else {
- primaryActionsAdapter.clear(ACTION_SKIP_TO_NEXT);
- mSkipNextAction = null;
- }
if (mFastForwardAction != null) {
int index = 0;
diff --git a/v17/leanback/src/android/support/v17/leanback/transition/ParallaxTransition.java b/v17/leanback/src/android/support/v17/leanback/transition/ParallaxTransition.java
index dfba1c0..d8ee734 100644
--- a/v17/leanback/src/android/support/v17/leanback/transition/ParallaxTransition.java
+++ b/v17/leanback/src/android/support/v17/leanback/transition/ParallaxTransition.java
@@ -55,7 +55,7 @@
}
Animator createAnimator(View view) {
- final Parallax<?> source = (Parallax) view.getTag(R.id.lb_parallax_source);
+ final Parallax source = (Parallax) view.getTag(R.id.lb_parallax_source);
if (source == null) {
return null;
}
diff --git a/v17/leanback/src/android/support/v17/leanback/util/MathUtil.java b/v17/leanback/src/android/support/v17/leanback/util/MathUtil.java
index 523bd4c..487188d 100644
--- a/v17/leanback/src/android/support/v17/leanback/util/MathUtil.java
+++ b/v17/leanback/src/android/support/v17/leanback/util/MathUtil.java
@@ -13,8 +13,6 @@
*/
package android.support.v17.leanback.util;
-import java.lang.Exception;
-
/**
* Math Utilities for leanback library.
* @hide
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/AbstractMediaListHeaderPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/AbstractMediaListHeaderPresenter.java
index ddcf3c6..9f2e452 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/AbstractMediaListHeaderPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/AbstractMediaListHeaderPresenter.java
@@ -15,11 +15,10 @@
import android.content.Context;
import android.graphics.Color;
-import android.util.TypedValue;
+import android.support.v17.leanback.R;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
-import android.support.v17.leanback.R;
import android.view.ViewGroup;
import android.widget.TextView;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/Action.java b/v17/leanback/src/android/support/v17/leanback/widget/Action.java
index 5e6e313..715fdd9 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/Action.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/Action.java
@@ -15,7 +15,6 @@
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
-import android.view.KeyEvent;
import java.util.ArrayList;
@@ -32,7 +31,7 @@
private Drawable mIcon;
private CharSequence mLabel1;
private CharSequence mLabel2;
- private ArrayList mKeyCodes = new ArrayList();
+ private ArrayList<Integer> mKeyCodes = new ArrayList<>();
/**
* Constructor for an Action.
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewLogoPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewLogoPresenter.java
index 22dba9c..f23acbc 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewLogoPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewLogoPresenter.java
@@ -94,7 +94,7 @@
ViewHolder vh = new ViewHolder(view);
ViewGroup.LayoutParams lp = view.getLayoutParams();
vh.setSizeFromDrawableIntrinsic(lp.width == ViewGroup.LayoutParams.WRAP_CONTENT
- && lp.width == ViewGroup.LayoutParams.WRAP_CONTENT);
+ && lp.height == ViewGroup.LayoutParams.WRAP_CONTENT);
return vh;
}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewRow.java b/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewRow.java
index c7aaf6c..9e8dbcd 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewRow.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewRow.java
@@ -17,7 +17,6 @@
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.view.KeyEvent;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/DetailsParallax.java b/v17/leanback/src/android/support/v17/leanback/widget/DetailsParallax.java
index 374485d..ad5f13a 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/DetailsParallax.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/DetailsParallax.java
@@ -34,19 +34,17 @@
* @see android.support.v17.leanback.app.DetailsSupportFragmentBackgroundController
*/
public class DetailsParallax extends RecyclerViewParallax {
- final Parallax.IntProperty mFrameTop;
- final Parallax.IntProperty mFrameBottom;
+ final IntProperty mFrameTop;
+ final IntProperty mFrameBottom;
public DetailsParallax() {
// track the top edge of details_frame of first item of adapter
- mFrameTop = this
- .addProperty("overviewRowTop")
+ mFrameTop = addProperty("overviewRowTop")
.adapterPosition(0)
.viewId(R.id.details_frame);
// track the bottom edge of details_frame of first item of adapter
- mFrameBottom = this
- .addProperty("overviewRowBottom")
+ mFrameBottom = addProperty("overviewRowBottom")
.adapterPosition(0)
.viewId(R.id.details_frame)
.fraction(1.0f);
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/DetailsParallaxDrawable.java b/v17/leanback/src/android/support/v17/leanback/widget/DetailsParallaxDrawable.java
index d77bc44..37e3480 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/DetailsParallaxDrawable.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/DetailsParallaxDrawable.java
@@ -23,7 +23,6 @@
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.v17.leanback.R;
-import android.support.v17.leanback.graphics.BoundsRule;
import android.support.v17.leanback.graphics.CompositeDrawable;
import android.support.v17.leanback.graphics.FitWidthBitmapDrawable;
import android.util.TypedValue;
@@ -124,8 +123,6 @@
}
addChildDrawable(coverDrawable);
addChildDrawable(mBottomDrawable = bottomDrawable);
- getChildAt(0).getBoundsRule().bottom = BoundsRule.inheritFromParent(1f);
- getChildAt(1).getBoundsRule().top = BoundsRule.inheritFromParent(1f);
connect(context, parallax, coverDrawableParallaxTarget);
}
@@ -179,23 +176,18 @@
.getDimensionPixelSize(R.dimen.lb_details_v2_align_pos_for_actions);
final int toValue = context.getResources()
.getDimensionPixelSize(R.dimen.lb_details_v2_align_pos_for_description);
- parallax
- .addEffect(frameTop.atAbsolute(fromValue), frameTop.atAbsolute(toValue))
+ parallax.addEffect(frameTop.atAbsolute(fromValue), frameTop.atAbsolute(toValue))
.target(coverDrawableParallaxTarget);
// Add solid color parallax effect:
// When frameBottom moves from bottom of the screen to top of the screen,
// change solid ColorDrawable's top from bottom of screen to top of the screen.
- parallax.addEffect(frameBottom.atFraction(1f), frameBottom.atFraction(0f))
- .target(getChildAt(1),
- PropertyValuesHolder.ofFloat(
- CompositeDrawable.ChildDrawable.TOP_FRACTION, 1f, 0f));
+ parallax.addEffect(frameBottom.atMax(), frameBottom.atMin())
+ .target(getChildAt(1), ChildDrawable.TOP_ABSOLUTE);
// Also when frameTop moves from bottom of screen to top of the screen,
// we are changing bottom of the bitmap from bottom of screen to top of screen.
- parallax.addEffect(frameTop.atFraction(1f), frameTop.atFraction(0f))
- .target(getChildAt(0),
- PropertyValuesHolder.ofFloat(
- CompositeDrawable.ChildDrawable.BOTTOM_FRACTION, 1f, 0f));
+ parallax.addEffect(frameTop.atMax(), frameTop.atMin())
+ .target(getChildAt(0), ChildDrawable.BOTTOM_ABSOLUTE);
}
}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ForegroundHelper.java b/v17/leanback/src/android/support/v17/leanback/widget/ForegroundHelper.java
index 252a317..64cb769 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ForegroundHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ForegroundHelper.java
@@ -3,7 +3,6 @@
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.View;
-import android.view.ViewGroup;
final class ForegroundHelper {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/GuidanceStylist.java b/v17/leanback/src/android/support/v17/leanback/widget/GuidanceStylist.java
index 888cc8f..edcec42 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GuidanceStylist.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GuidanceStylist.java
@@ -14,13 +14,10 @@
package android.support.v17.leanback.widget;
import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v17.leanback.R;
import android.text.TextUtils;
-import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/GuidedDatePickerAction.java b/v17/leanback/src/android/support/v17/leanback/widget/GuidedDatePickerAction.java
index d655e85..5871247 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GuidedDatePickerAction.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GuidedDatePickerAction.java
@@ -15,7 +15,6 @@
import android.content.Context;
import android.os.Bundle;
-import android.support.v17.leanback.widget.picker.DatePicker;
import java.util.Calendar;
import java.util.TimeZone;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ItemAlignment.java b/v17/leanback/src/android/support/v17/leanback/widget/ItemAlignment.java
index 4790a12..e1b7d13 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ItemAlignment.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ItemAlignment.java
@@ -16,12 +16,8 @@
import static android.support.v7.widget.RecyclerView.HORIZONTAL;
import static android.support.v7.widget.RecyclerView.VERTICAL;
-import static android.support.v17.leanback.widget.BaseGridView.ITEM_ALIGN_OFFSET_PERCENT_DISABLED;
-import android.graphics.Rect;
-import android.support.v17.leanback.widget.GridLayoutManager.LayoutParams;
import android.view.View;
-import android.view.ViewGroup;
/**
* Defines alignment position on two directions of an item view. Typically item
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ItemBridgeAdapterShadowOverlayWrapper.java b/v17/leanback/src/android/support/v17/leanback/widget/ItemBridgeAdapterShadowOverlayWrapper.java
index 19e6e9a..ff152f7 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ItemBridgeAdapterShadowOverlayWrapper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ItemBridgeAdapterShadowOverlayWrapper.java
@@ -15,7 +15,6 @@
import android.content.Context;
import android.view.View;
-import android.view.ViewGroup.LayoutParams;
/**
* A wrapper class working with {@link ItemBridgeAdapter} to wrap item view in a
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/OnChildViewHolderSelectedListener.java b/v17/leanback/src/android/support/v17/leanback/widget/OnChildViewHolderSelectedListener.java
index ae9d436..ae170c0 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/OnChildViewHolderSelectedListener.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/OnChildViewHolderSelectedListener.java
@@ -15,8 +15,6 @@
import android.support.v17.leanback.widget.ItemAlignmentFacet.ItemAlignmentDef;
import android.support.v7.widget.RecyclerView;
-import android.view.View;
-import android.view.ViewGroup;
/**
* Interface for receiving notification when a child of this ViewGroup has been selected.
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/Parallax.java b/v17/leanback/src/android/support/v17/leanback/widget/Parallax.java
index 573ca02..aebf9b4 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/Parallax.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/Parallax.java
@@ -31,22 +31,40 @@
* rules to mapping property values to {@link ParallaxTarget}.
*
* <p>
- * There are two types of Parallax, int or float. App should subclass either
- * {@link Parallax.IntParallax} or {@link Parallax.FloatParallax}. App may subclass
- * {@link Parallax.IntProperty} or {@link Parallax.FloatProperty} to supply additional information
- * about how to retrieve Property value. {@link RecyclerViewParallax} is a great example of
- * Parallax implementation tracking child view positions on screen.
+ * Example:
+ * <code>
+ * // when Property "var1" changes from 15 to max value, perform parallax effect to
+ * // change myView's translationY from 0 to 100.
+ * Parallax<IntProperty> parallax = new Parallax<IntProperty>() {...};
+ * p1 = parallax.addProperty("var1");
+ * parallax.addEffect(p1.at(15), p1.atMax())
+ * .target(myView, PropertyValuesHolder.ofFloat("translationY", 0, 100));
+ * </code>
+ * </p>
+ *
+ * <p>
+ * To create a {@link ParallaxEffect}, user calls {@link #addEffect(PropertyMarkerValue[])} with a
+ * list of {@link PropertyMarkerValue} which defines the range of {@link Parallax.IntProperty} or
+ * {@link Parallax.FloatProperty}. Then user adds {@link ParallaxTarget} into
+ * {@link ParallaxEffect}.
+ * </p>
+ * <p>
+ * App may subclass {@link Parallax.IntProperty} or {@link Parallax.FloatProperty} to supply
+ * additional information about how to retrieve Property value. {@link RecyclerViewParallax} is
+ * a great example of Parallax implementation tracking child view positions on screen.
* </p>
* <p>
* <ul>Restrictions of properties
+ * <li>FloatProperty and IntProperty cannot be mixed in one Parallax</li>
* <li>Values must be in ascending order.</li>
* <li>If the UI element is unknown above screen, use UNKNOWN_BEFORE.</li>
* <li>if the UI element is unknown below screen, use UNKNOWN_AFTER.</li>
* <li>UNKNOWN_BEFORE and UNKNOWN_AFTER are not allowed to be next to each other.</li>
* </ul>
- * These rules can be verified by {@link #verifyProperties()}.
+ * These rules will be verified at runtime.
* </p>
- * Subclass should override {@link #updateValues()} to update property values and perform
+ * <p>
+ * Subclass must override {@link #updateValues()} to update property values and perform
* {@link ParallaxEffect}s. Subclass may call {@link #updateValues()} automatically e.g.
* {@link RecyclerViewParallax} calls {@link #updateValues()} in RecyclerView scrolling. App might
* call {@link #updateValues()} manually when Parallax is unaware of the value change. For example,
@@ -54,15 +72,12 @@
* changes; it's the app's responsibility to call {@link #updateValues()} in every frame of
* animation.
* </p>
- * @param <PropertyT> Class of the property, e.g. {@link IntProperty} or {@link FloatProperty}.
+ * @param <PropertyT> Subclass of {@link Parallax.IntProperty} or {@link Parallax.FloatProperty}
*/
-public abstract class Parallax<PropertyT extends Property> {
-
- private final List<ParallaxEffect> mEffects = new ArrayList<ParallaxEffect>(4);
+public abstract class Parallax<PropertyT extends android.util.Property> {
/**
* Class holding a fixed value for a Property in {@link Parallax}.
- * Base class for {@link IntPropertyMarkerValue} and {@link FloatPropertyMarkerValue}.
* @param <PropertyT> Class of the property, e.g. {@link IntProperty} or {@link FloatProperty}.
*/
public static class PropertyMarkerValue<PropertyT> {
@@ -82,10 +97,10 @@
/**
* IntProperty provide access to an index based integer type property inside
- * {@link IntParallax}. The IntProperty typically represents UI element position inside
- * {@link IntParallax}.
+ * {@link Parallax}. The IntProperty typically represents UI element position inside
+ * {@link Parallax}.
*/
- public static class IntProperty extends Property<IntParallax, Integer> {
+ public static class IntProperty extends Property<Parallax, Integer> {
/**
* Property value is unknown and it's smaller than minimal value of Parallax. For
@@ -94,7 +109,7 @@
public static final int UNKNOWN_BEFORE = Integer.MIN_VALUE;
/**
- * Property value is unknown and it's larger than {@link IntParallax#getMaxValue()}. For
+ * Property value is unknown and it's larger than {@link Parallax#getMaxValue()}. For
* example if a child is not created and after the last visible child of RecyclerView.
*/
public static final int UNKNOWN_AFTER = Integer.MAX_VALUE;
@@ -105,7 +120,7 @@
* Constructor.
*
* @param name Name of this Property.
- * @param index Index of this Property inside {@link IntParallax}.
+ * @param index Index of this Property inside {@link Parallax}.
*/
public IntProperty(String name, int index) {
super(Integer.class, name);
@@ -113,168 +128,112 @@
}
@Override
- public final Integer get(IntParallax object) {
- return getIntValue(object);
+ public final Integer get(Parallax object) {
+ return object.getIntPropertyValue(mIndex);
}
@Override
- public final void set(IntParallax object, Integer value) {
- setIntValue(object, value);
- }
-
- final int getIntValue(IntParallax source) {
- return source.getPropertyValue(mIndex);
- }
-
- final void setIntValue(IntParallax source, int value) {
- source.setPropertyValue(mIndex, value);
+ public final void set(Parallax object, Integer value) {
+ object.setIntPropertyValue(mIndex, value);
}
/**
- * @return Index of this Property in {@link IntParallax}.
+ * @return Index of this Property in {@link Parallax}.
*/
public final int getIndex() {
return mIndex;
}
/**
- * Creates an {@link IntPropertyMarkerValue} object for the absolute marker value.
+ * Fast version of get() method that returns a primitive int value of the Property.
+ * @param object The Parallax object that owns this Property.
+ * @return Int value of the Property.
+ */
+ public final int getValue(Parallax object) {
+ return object.getIntPropertyValue(mIndex);
+ }
+
+ /**
+ * Fast version of set() method that takes a primitive int value into the Property.
+ *
+ * @param object The Parallax object that owns this Property.
+ * @param value Int value of the Property.
+ */
+ public final void setValue(Parallax object, int value) {
+ object.setIntPropertyValue(mIndex, value);
+ }
+
+ /**
+ * Creates an {@link PropertyMarkerValue} object for the absolute marker value.
*
* @param absoluteValue The integer marker value.
- * @return A new {@link IntPropertyMarkerValue} object.
+ * @return A new {@link PropertyMarkerValue} object.
*/
- public final IntPropertyMarkerValue atAbsolute(int absoluteValue) {
+ public final PropertyMarkerValue atAbsolute(int absoluteValue) {
return new IntPropertyMarkerValue(this, absoluteValue, 0f);
}
/**
- * Creates an {@link IntPropertyMarkerValue} object for a fraction of
- * {@link IntParallax#getMaxValue()}.
+ * Creates an {@link PropertyMarkerValue} object for the marker value representing
+ * {@link Parallax#getMaxValue()}.
+ *
+ * @return A new {@link PropertyMarkerValue} object.
+ */
+ public final PropertyMarkerValue atMax() {
+ return new IntPropertyMarkerValue(this, 0, 1f);
+ }
+
+ /**
+ * Creates an {@link PropertyMarkerValue} object for the marker value representing 0.
+ *
+ * @return A new {@link PropertyMarkerValue} object.
+ */
+ public final PropertyMarkerValue atMin() {
+ return new IntPropertyMarkerValue(this, 0);
+ }
+
+ /**
+ * Creates an {@link PropertyMarkerValue} object for a fraction of
+ * {@link Parallax#getMaxValue()}.
*
* @param fractionOfMaxValue 0 to 1 fraction to multiply with
- * {@link IntParallax#getMaxValue()} for
+ * {@link Parallax#getMaxValue()} for
* the marker value.
- * @return A new {@link IntPropertyMarkerValue} object.
+ * @return A new {@link PropertyMarkerValue} object.
*/
- public final IntPropertyMarkerValue atFraction(float fractionOfMaxValue) {
+ public final PropertyMarkerValue atFraction(float fractionOfMaxValue) {
return new IntPropertyMarkerValue(this, 0, fractionOfMaxValue);
}
/**
- * Create an {@link IntPropertyMarkerValue} object by multiplying the fraction with
- * {@link IntParallax#getMaxValue()} and adding offsetValue to it.
+ * Create an {@link PropertyMarkerValue} object by multiplying the fraction with
+ * {@link Parallax#getMaxValue()} and adding offsetValue to it.
*
* @param offsetValue An offset integer value to be added to marker
* value.
* @param fractionOfMaxParentVisibleSize 0 to 1 fraction to multiply with
- * {@link IntParallax#getMaxValue()} for
+ * {@link Parallax#getMaxValue()} for
* the marker value.
- * @return A new {@link IntPropertyMarkerValue} object.
+ * @return A new {@link PropertyMarkerValue} object.
*/
- public final IntPropertyMarkerValue at(int offsetValue,
- float fractionOfMaxParentVisibleSize) {
+ public final PropertyMarkerValue at(int offsetValue,
+ float fractionOfMaxParentVisibleSize) {
return new IntPropertyMarkerValue(this, offsetValue, fractionOfMaxParentVisibleSize);
}
}
/**
- * Parallax that manages a list of {@link IntProperty}. App may override this class with a
- * specific {@link IntProperty} subclass.
- *
- * @param <IntPropertyT> Type of {@link IntProperty} or subclass.
- */
- public abstract static class IntParallax<IntPropertyT extends IntProperty>
- extends Parallax<IntPropertyT> {
-
- private int[] mValues = new int[4];
-
- /**
- * Get index based property value.
- *
- * @param index Index of the property.
- * @return Value of the property.
- */
- public final int getPropertyValue(int index) {
- return mValues[index];
- }
-
- /**
- * Set index based property value.
- *
- * @param index Index of the property.
- * @param value Value of the property.
- */
- public final void setPropertyValue(int index, int value) {
- if (index >= mProperties.size()) {
- throw new ArrayIndexOutOfBoundsException();
- }
- mValues[index] = value;
- }
-
- /**
- * Return the max value, which is typically parent visible area, e.g. RecyclerView's height
- * if we are tracking Y position of a child. The size can be used to calculate marker value
- * using the provided fraction of IntPropertyMarkerValue.
- *
- * @return Max value of parallax.
- * @see IntPropertyMarkerValue#IntPropertyMarkerValue(IntProperty, int, float)
- */
- public abstract int getMaxValue();
-
- @Override
- public final IntPropertyT addProperty(String name) {
- int newPropertyIndex = mProperties.size();
- IntPropertyT property = createProperty(name, newPropertyIndex);
- mProperties.add(property);
- int size = mValues.length;
- if (size == newPropertyIndex) {
- int[] newValues = new int[size * 2];
- for (int i = 0; i < size; i++) {
- newValues[i] = mValues[i];
- }
- mValues = newValues;
- }
- mValues[newPropertyIndex] = IntProperty.UNKNOWN_AFTER;
- return property;
- }
-
- @Override
- public final void verifyProperties() throws IllegalStateException {
- if (mProperties.size() < 2) {
- return;
- }
- int last = mProperties.get(0).getIntValue(this);
- for (int i = 1; i < mProperties.size(); i++) {
- int v = mProperties.get(i).getIntValue(this);
- if (v < last) {
- throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is"
- + " smaller than Property[%d]\"%s\"",
- i, mProperties.get(i).getName(),
- i - 1, mProperties.get(i - 1).getName()));
- } else if (last == IntProperty.UNKNOWN_BEFORE && v == IntProperty.UNKNOWN_AFTER) {
- throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is"
- + " UNKNOWN_BEFORE and Property[%d]\"%s\" is UNKNOWN_AFTER",
- i - 1, mProperties.get(i - 1).getName(),
- i, mProperties.get(i).getName()));
- }
- last = v;
- }
- }
-
- }
-
- /**
* Implementation of {@link PropertyMarkerValue} for {@link IntProperty}.
*/
- public static class IntPropertyMarkerValue extends PropertyMarkerValue<IntProperty> {
+ static class IntPropertyMarkerValue extends PropertyMarkerValue<IntProperty> {
private final int mValue;
private final float mFactionOfMax;
- public IntPropertyMarkerValue(IntProperty property, int value) {
+ IntPropertyMarkerValue(IntProperty property, int value) {
this(property, value, 0f);
}
- public IntPropertyMarkerValue(IntProperty property, int value, float fractionOfMax) {
+ IntPropertyMarkerValue(IntProperty property, int value, float fractionOfMax) {
super(property);
mValue = value;
mFactionOfMax = fractionOfMax;
@@ -283,7 +242,7 @@
/**
* @return The marker value of integer type.
*/
- public final int getMarkerValue(IntParallax source) {
+ final int getMarkerValue(Parallax source) {
return mFactionOfMax == 0 ? mValue : mValue + Math.round(source
.getMaxValue() * mFactionOfMax);
}
@@ -291,10 +250,10 @@
/**
* FloatProperty provide access to an index based integer type property inside
- * {@link FloatParallax}. The FloatProperty typically represents UI element position inside
- * {@link FloatParallax}.
+ * {@link Parallax}. The FloatProperty typically represents UI element position inside
+ * {@link Parallax}.
*/
- public static class FloatProperty extends Property<FloatParallax, Float> {
+ public static class FloatProperty extends Property<Parallax, Float> {
/**
* Property value is unknown and it's smaller than minimal value of Parallax. For
@@ -303,7 +262,7 @@
public static final float UNKNOWN_BEFORE = -Float.MAX_VALUE;
/**
- * Property value is unknown and it's larger than {@link FloatParallax#getMaxValue()}. For
+ * Property value is unknown and it's larger than {@link Parallax#getMaxValue()}. For
* example if a child is not created and after the last visible child of RecyclerView.
*/
public static final float UNKNOWN_AFTER = Float.MAX_VALUE;
@@ -314,7 +273,7 @@
* Constructor.
*
* @param name Name of this Property.
- * @param index Index of this Property inside {@link FloatParallax}.
+ * @param index Index of this Property inside {@link Parallax}.
*/
public FloatProperty(String name, int index) {
super(Float.class, name);
@@ -322,168 +281,111 @@
}
@Override
- public final Float get(FloatParallax object) {
- return getFloatValue(object);
+ public final Float get(Parallax object) {
+ return object.getFloatPropertyValue(mIndex);
}
@Override
- public final void set(FloatParallax object, Float value) {
- setFloatValue(object, value);
- }
-
- final float getFloatValue(FloatParallax source) {
- return source.getPropertyValue(mIndex);
- }
-
- final void setFloatValue(FloatParallax source, float value) {
- source.setPropertyValue(mIndex, value);
+ public final void set(Parallax object, Float value) {
+ object.setFloatPropertyValue(mIndex, value);
}
/**
- * @return Index of this Property in {@link FloatParallax}.
+ * @return Index of this Property in {@link Parallax}.
*/
public final int getIndex() {
return mIndex;
}
/**
- * Creates an {@link FloatPropertyMarkerValue} object for the absolute marker value.
+ * Fast version of get() method that returns a primitive int value of the Property.
+ * @param object The Parallax object that owns this Property.
+ * @return Float value of the Property.
+ */
+ public final float getValue(Parallax object) {
+ return object.getFloatPropertyValue(mIndex);
+ }
+
+ /**
+ * Fast version of set() method that takes a primitive float value into the Property.
+ *
+ * @param object The Parallax object that owns this Property.
+ * @param value Float value of the Property.
+ */
+ public final void setValue(Parallax object, float value) {
+ object.setFloatPropertyValue(mIndex, value);
+ }
+
+ /**
+ * Creates an {@link PropertyMarkerValue} object for the absolute marker value.
*
* @param markerValue The float marker value.
- * @return A new {@link FloatPropertyMarkerValue} object.
+ * @return A new {@link PropertyMarkerValue} object.
*/
- public final FloatPropertyMarkerValue atAbsolute(float markerValue) {
+ public final PropertyMarkerValue atAbsolute(float markerValue) {
return new FloatPropertyMarkerValue(this, markerValue, 0f);
}
/**
- * Creates an {@link FloatPropertyMarkerValue} object for a fraction of
- * {@link FloatParallax#getMaxValue()}.
+ * Creates an {@link PropertyMarkerValue} object for the marker value representing
+ * {@link Parallax#getMaxValue()}.
+ *
+ * @return A new {@link PropertyMarkerValue} object.
+ */
+ public final PropertyMarkerValue atMax() {
+ return new FloatPropertyMarkerValue(this, 0, 1f);
+ }
+
+ /**
+ * Creates an {@link PropertyMarkerValue} object for the marker value representing 0.
+ *
+ * @return A new {@link PropertyMarkerValue} object.
+ */
+ public final PropertyMarkerValue atMin() {
+ return new FloatPropertyMarkerValue(this, 0);
+ }
+
+ /**
+ * Creates an {@link PropertyMarkerValue} object for a fraction of
+ * {@link Parallax#getMaxValue()}.
*
* @param fractionOfMaxParentVisibleSize 0 to 1 fraction to multiply with
- * {@link FloatParallax#getMaxValue()} for
+ * {@link Parallax#getMaxValue()} for
* the marker value.
- * @return A new {@link FloatPropertyMarkerValue} object.
+ * @return A new {@link PropertyMarkerValue} object.
*/
- public final FloatPropertyMarkerValue atFraction(float fractionOfMaxParentVisibleSize) {
+ public final PropertyMarkerValue atFraction(float fractionOfMaxParentVisibleSize) {
return new FloatPropertyMarkerValue(this, 0, fractionOfMaxParentVisibleSize);
}
/**
- * Create an {@link FloatPropertyMarkerValue} object by multiplying the fraction with
- * {@link FloatParallax#getMaxValue()} and adding offsetValue to it.
+ * Create an {@link PropertyMarkerValue} object by multiplying the fraction with
+ * {@link Parallax#getMaxValue()} and adding offsetValue to it.
*
* @param offsetValue An offset float value to be added to marker value.
* @param fractionOfMaxParentVisibleSize 0 to 1 fraction to multiply with
- * {@link FloatParallax#getMaxValue()} for
+ * {@link Parallax#getMaxValue()} for
* the marker value.
- * @return A new {@link FloatPropertyMarkerValue} object.
+ * @return A new {@link PropertyMarkerValue} object.
*/
- public final FloatPropertyMarkerValue at(float offsetValue,
- float fractionOfMaxParentVisibleSize) {
+ public final PropertyMarkerValue at(float offsetValue,
+ float fractionOfMaxParentVisibleSize) {
return new FloatPropertyMarkerValue(this, offsetValue, fractionOfMaxParentVisibleSize);
}
}
/**
- * Parallax that manages a list of {@link FloatProperty}. App may override this class with a
- * specific {@link FloatProperty} subclass.
- *
- * @param <FloatPropertyT> Type of {@link FloatProperty} or subclass.
- */
- public abstract static class FloatParallax<FloatPropertyT extends FloatProperty> extends
- Parallax<FloatPropertyT> {
-
- private float[] mValues = new float[4];
-
- /**
- * Get index based property value.
- *
- * @param index Index of the property.
- * @return Value of the property.
- */
- public final float getPropertyValue(int index) {
- return mValues[index];
- }
-
- /**
- * Set index based property value.
- *
- * @param index Index of the property.
- * @param value Value of the property.
- */
- public final void setPropertyValue(int index, float value) {
- if (index >= mProperties.size()) {
- throw new ArrayIndexOutOfBoundsException();
- }
- mValues[index] = value;
- }
-
- /**
- * Return the max value which is typically size of parent visible area, e.g. RecyclerView's
- * height if we are tracking Y position of a child. The size can be used to calculate marker
- * value using the provided fraction of FloatPropertyMarkerValue.
- *
- * @return Size of parent visible area.
- * @see FloatPropertyMarkerValue#FloatPropertyMarkerValue(FloatProperty, float, float)
- */
- public abstract float getMaxValue();
-
- @Override
- public final FloatPropertyT addProperty(String name) {
- int newPropertyIndex = mProperties.size();
- FloatPropertyT property = createProperty(name, newPropertyIndex);
- mProperties.add(property);
- int size = mValues.length;
- if (size == newPropertyIndex) {
- float[] newValues = new float[size * 2];
- for (int i = 0; i < size; i++) {
- newValues[i] = mValues[i];
- }
- mValues = newValues;
- }
- mValues[newPropertyIndex] = FloatProperty.UNKNOWN_AFTER;
- return property;
- }
-
- @Override
- public final void verifyProperties() throws IllegalStateException {
- if (mProperties.size() < 2) {
- return;
- }
- float last = mProperties.get(0).getFloatValue(this);
- for (int i = 1; i < mProperties.size(); i++) {
- float v = mProperties.get(i).getFloatValue(this);
- if (v < last) {
- throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is"
- + " smaller than Property[%d]\"%s\"",
- i, mProperties.get(i).getName(),
- i - 1, mProperties.get(i - 1).getName()));
- } else if (last == FloatProperty.UNKNOWN_BEFORE && v
- == FloatProperty.UNKNOWN_AFTER) {
- throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is"
- + " UNKNOWN_BEFORE and Property[%d]\"%s\" is UNKNOWN_AFTER",
- i - 1, mProperties.get(i - 1).getName(),
- i, mProperties.get(i).getName()));
- }
- last = v;
- }
- }
-
- }
-
- /**
* Implementation of {@link PropertyMarkerValue} for {@link FloatProperty}.
*/
- public static class FloatPropertyMarkerValue extends PropertyMarkerValue<FloatProperty> {
+ static class FloatPropertyMarkerValue extends PropertyMarkerValue<FloatProperty> {
private final float mValue;
private final float mFactionOfMax;
- public FloatPropertyMarkerValue(FloatProperty property, float value) {
+ FloatPropertyMarkerValue(FloatProperty property, float value) {
this(property, value, 0f);
}
- public FloatPropertyMarkerValue(FloatProperty property, float value, float fractionOfMax) {
+ FloatPropertyMarkerValue(FloatProperty property, float value, float fractionOfMax) {
super(property);
mValue = value;
mFactionOfMax = fractionOfMax;
@@ -492,7 +394,7 @@
/**
* @return The marker value.
*/
- public final float getMarkerValue(FloatParallax source) {
+ final float getMarkerValue(Parallax source) {
return mFactionOfMax == 0 ? mValue : mValue + source.getMaxValue()
* mFactionOfMax;
}
@@ -501,6 +403,156 @@
final List<PropertyT> mProperties = new ArrayList<PropertyT>();
final List<PropertyT> mPropertiesReadOnly = Collections.unmodifiableList(mProperties);
+ private int[] mValues = new int[4];
+ private float[] mFloatValues = new float[4];
+
+ private final List<ParallaxEffect> mEffects = new ArrayList<ParallaxEffect>(4);
+
+ /**
+ * Return the max value which is typically size of parent visible area, e.g. RecyclerView's
+ * height if we are tracking Y position of a child. The size can be used to calculate marker
+ * value using the provided fraction of FloatPropertyMarkerValue.
+ *
+ * @return Size of parent visible area.
+ * @see IntPropertyMarkerValue#IntPropertyMarkerValue(IntProperty, int, float)
+ * @see FloatPropertyMarkerValue#FloatPropertyMarkerValue(FloatProperty, float, float)
+ */
+ public abstract float getMaxValue();
+
+ /**
+ * Get index based property value.
+ *
+ * @param index Index of the property.
+ * @return Value of the property.
+ */
+ final int getIntPropertyValue(int index) {
+ return mValues[index];
+ }
+
+ /**
+ * Set index based property value.
+ *
+ * @param index Index of the property.
+ * @param value Value of the property.
+ */
+ final void setIntPropertyValue(int index, int value) {
+ if (index >= mProperties.size()) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ mValues[index] = value;
+ }
+
+ /**
+ * Add a new IntProperty in the Parallax object. App may override
+ * {@link #createProperty(String, int)}.
+ *
+ * @param name Name of the property.
+ * @return Newly created Property object.
+ * @see #createProperty(String, int)
+ */
+ public final PropertyT addProperty(String name) {
+ int newPropertyIndex = mProperties.size();
+ PropertyT property = createProperty(name, newPropertyIndex);
+ if (property instanceof IntProperty) {
+ int size = mValues.length;
+ if (size == newPropertyIndex) {
+ int[] newValues = new int[size * 2];
+ for (int i = 0; i < size; i++) {
+ newValues[i] = mValues[i];
+ }
+ mValues = newValues;
+ }
+ mValues[newPropertyIndex] = IntProperty.UNKNOWN_AFTER;
+ } else if (property instanceof FloatProperty) {
+ int size = mFloatValues.length;
+ if (size == newPropertyIndex) {
+ float[] newValues = new float[size * 2];
+ for (int i = 0; i < size; i++) {
+ newValues[i] = mFloatValues[i];
+ }
+ mFloatValues = newValues;
+ }
+ mFloatValues[newPropertyIndex] = FloatProperty.UNKNOWN_AFTER;
+ } else {
+ throw new IllegalArgumentException("Invalid Property type");
+ }
+ mProperties.add(property);
+ return property;
+ }
+
+ /**
+ * Verify sanity of property values, throws RuntimeException if fails. The property values
+ * must be in ascending order. UNKNOW_BEFORE and UNKNOWN_AFTER are not allowed to be next to
+ * each other.
+ */
+ void verifyIntProperties() throws IllegalStateException {
+ if (mProperties.size() < 2) {
+ return;
+ }
+ int last = getIntPropertyValue(0);
+ for (int i = 1; i < mProperties.size(); i++) {
+ int v = getIntPropertyValue(i);
+ if (v < last) {
+ throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is"
+ + " smaller than Property[%d]\"%s\"",
+ i, mProperties.get(i).getName(),
+ i - 1, mProperties.get(i - 1).getName()));
+ } else if (last == IntProperty.UNKNOWN_BEFORE && v == IntProperty.UNKNOWN_AFTER) {
+ throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is"
+ + " UNKNOWN_BEFORE and Property[%d]\"%s\" is UNKNOWN_AFTER",
+ i - 1, mProperties.get(i - 1).getName(),
+ i, mProperties.get(i).getName()));
+ }
+ last = v;
+ }
+ }
+
+ final void verifyFloatProperties() throws IllegalStateException {
+ if (mProperties.size() < 2) {
+ return;
+ }
+ float last = getFloatPropertyValue(0);
+ for (int i = 1; i < mProperties.size(); i++) {
+ float v = getFloatPropertyValue(i);
+ if (v < last) {
+ throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is"
+ + " smaller than Property[%d]\"%s\"",
+ i, mProperties.get(i).getName(),
+ i - 1, mProperties.get(i - 1).getName()));
+ } else if (last == FloatProperty.UNKNOWN_BEFORE && v
+ == FloatProperty.UNKNOWN_AFTER) {
+ throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is"
+ + " UNKNOWN_BEFORE and Property[%d]\"%s\" is UNKNOWN_AFTER",
+ i - 1, mProperties.get(i - 1).getName(),
+ i, mProperties.get(i).getName()));
+ }
+ last = v;
+ }
+ }
+
+ /**
+ * Get index based property value.
+ *
+ * @param index Index of the property.
+ * @return Value of the property.
+ */
+ final float getFloatPropertyValue(int index) {
+ return mFloatValues[index];
+ }
+
+ /**
+ * Set index based property value.
+ *
+ * @param index Index of the property.
+ * @param value Value of the property.
+ */
+ final void setFloatPropertyValue(int index, float value) {
+ if (index >= mProperties.size()) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ mFloatValues[index] = value;
+ }
+
/**
* @return A unmodifiable list of properties.
*/
@@ -509,14 +561,6 @@
}
/**
- * Add a new Property in the Parallax object.
- *
- * @param name Name of the property.
- * @return Newly created Property.
- */
- public abstract PropertyT addProperty(String name);
-
- /**
* Create a new Property object. App does not directly call this method. See
* {@link #addProperty(String)}.
*
@@ -526,13 +570,6 @@
public abstract PropertyT createProperty(String name, int index);
/**
- * Verify sanity of property values, throws RuntimeException if fails. The property values
- * must be in ascending order. UNKNOW_BEFORE and UNKNOWN_AFTER are not allowed to be next to
- * each other.
- */
- public abstract void verifyProperties() throws IllegalStateException;
-
- /**
* Update property values and perform {@link ParallaxEffect}s. Subclass may override and call
* super.updateValues() after updated properties values.
*/
@@ -544,16 +581,6 @@
}
/**
- * Adds a {@link ParallaxEffect} object which defines rules to perform mapping to multiple
- * {@link ParallaxTarget}s.
- *
- * @param effect A {@link ParallaxEffect} object.
- */
- public void addEffect(ParallaxEffect effect) {
- mEffects.add(effect);
- }
-
- /**
* Returns a list of {@link ParallaxEffect} object which defines rules to perform mapping to
* multiple {@link ParallaxTarget}s.
*
@@ -586,24 +613,16 @@
* @param ranges A list of marker values that defines the ranges.
* @return Newly created ParallaxEffect object.
*/
- public ParallaxEffect addEffect(IntPropertyMarkerValue... ranges) {
- IntEffect effect = new IntEffect();
+ public ParallaxEffect addEffect(PropertyMarkerValue... ranges) {
+ ParallaxEffect effect;
+ if (ranges[0].getProperty() instanceof IntProperty) {
+ effect = new IntEffect();
+ } else {
+ effect = new FloatEffect();
+ }
effect.setPropertyRanges(ranges);
- addEffect(effect);
+ mEffects.add(effect);
return effect;
}
- /**
- * Create a {@link ParallaxEffect} object that will track source variable changes within a
- * provided set of ranges.
- *
- * @param ranges A list of marker values that defines the ranges.
- * @return Newly created ParallaxEffect object.
- */
- public ParallaxEffect addEffect(FloatPropertyMarkerValue... ranges) {
- FloatEffect effect = new FloatEffect();
- effect.setPropertyRanges(ranges);
- addEffect(effect);
- return effect;
- }
}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ParallaxEffect.java b/v17/leanback/src/android/support/v17/leanback/widget/ParallaxEffect.java
index 5760bdb..5c06e29 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ParallaxEffect.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ParallaxEffect.java
@@ -21,6 +21,7 @@
import android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue;
import android.support.v17.leanback.widget.Parallax.IntProperty;
import android.support.v17.leanback.widget.Parallax.PropertyMarkerValue;
+import android.util.Property;
import java.util.ArrayList;
import java.util.List;
@@ -36,25 +37,30 @@
* on, the fraction increases from 0 at beginning to 1 at the end. Then the fraction is passed on
* to {@link ParallaxTarget#update(float)}.
* <p>
- * ParallaxEffect has two concrete subclasses, {@link IntEffect} and {@link FloatEffect}.
+ * App use {@link Parallax#addEffect(PropertyMarkerValue...)} to create a ParallaxEffect.
*/
-public abstract class ParallaxEffect<ParallaxEffectT extends ParallaxEffect,
- PropertyMarkerValueT extends Parallax.PropertyMarkerValue> {
+public abstract class ParallaxEffect {
- final List<PropertyMarkerValueT> mMarkerValues = new ArrayList<PropertyMarkerValueT>(2);
+ final List<Parallax.PropertyMarkerValue> mMarkerValues = new ArrayList(2);
final List<Float> mWeights = new ArrayList<Float>(2);
final List<Float> mTotalWeights = new ArrayList<Float>(2);
final List<ParallaxTarget> mTargets = new ArrayList<ParallaxTarget>(4);
/**
+ * Only accessible from package
+ */
+ ParallaxEffect() {
+ }
+
+ /**
* Returns the list of {@link PropertyMarkerValue}s, which represents the range of values that
* source variables can take.
*
* @return A list of {@link Parallax.PropertyMarkerValue}s.
* @see #performMapping(Parallax)
*/
- public final List<PropertyMarkerValueT> getPropertyRanges() {
- return mMarkerValues;
+ public final List<Parallax.PropertyMarkerValue> getPropertyRanges() {
+ return mMarkerValues;
}
/**
@@ -75,9 +81,9 @@
* @param markerValues A list of {@link PropertyMarkerValue}s.
* @see #performMapping(Parallax)
*/
- public final void setPropertyRanges(PropertyMarkerValueT... markerValues) {
+ public final void setPropertyRanges(Parallax.PropertyMarkerValue... markerValues) {
mMarkerValues.clear();
- for (PropertyMarkerValueT markerValue : markerValues) {
+ for (Parallax.PropertyMarkerValue markerValue : markerValues) {
mMarkerValues.add(markerValue);
}
}
@@ -154,6 +160,23 @@
}
/**
+ * Creates a {@link ParallaxTarget} using direct mapping from source property into target
+ * property, the new {@link ParallaxTarget} will be added to its list of targets.
+ *
+ * @param targetObject Target object for property.
+ * @param targetProperty The target property that will receive values.
+ * @return This ParallaxEffect object, allowing calls to methods in this class to be chained.
+ * @param <T> Type of target object.
+ * @param <V> Type of target property value, either Integer or Float.
+ * @see ParallaxTarget#isDirectMapping()
+ */
+ public final <T, V extends Number> ParallaxEffect target(T targetObject,
+ Property<T, V> targetProperty) {
+ mTargets.add(new ParallaxTarget.DirectPropertyTarget(targetObject, targetProperty));
+ return this;
+ }
+
+ /**
* Returns the list of {@link ParallaxTarget} objects.
*
* @return The list of {@link ParallaxTarget} objects.
@@ -177,10 +200,28 @@
if (mMarkerValues.size() < 2) {
return;
}
- source.verifyProperties();
- float fraction = calculateFraction(source);
+ if (this instanceof IntEffect) {
+ source.verifyIntProperties();
+ } else {
+ source.verifyFloatProperties();
+ }
+ boolean fractionCalculated = false;
+ float fraction = 0;
+ Number directValue = null;
for (int i = 0; i < mTargets.size(); i++) {
- mTargets.get(i).update(fraction);
+ ParallaxTarget target = mTargets.get(i);
+ if (target.isDirectMapping()) {
+ if (directValue == null) {
+ directValue = calculateDirectValue(source);
+ }
+ target.directUpdate(directValue);
+ } else {
+ if (!fractionCalculated) {
+ fractionCalculated = true;
+ fraction = calculateFraction(source);
+ }
+ target.update(fraction);
+ }
}
}
@@ -191,7 +232,15 @@
*
* @return Float value between 0 and 1.
*/
- protected abstract float calculateFraction(Parallax source);
+ abstract float calculateFraction(Parallax source);
+
+ /**
+ * This method is expected to get the current value of the single {@link IntProperty} or
+ * {@link FloatProperty}.
+ *
+ * @return Current value of the single {@link IntProperty} or {@link FloatProperty}.
+ */
+ abstract Number calculateDirectValue(Parallax source);
/**
* When there are multiple ranges (aka three or more markerValues), this method adjust the
@@ -226,21 +275,48 @@
/**
* Implementation of {@link ParallaxEffect} for integer type.
*/
- public static final class IntEffect extends ParallaxEffect<IntEffect,
- Parallax.IntPropertyMarkerValue> {
+ static final class IntEffect extends ParallaxEffect {
@Override
- protected float calculateFraction(Parallax s) {
- Parallax.IntParallax source = (Parallax.IntParallax) s;
+ Number calculateDirectValue(Parallax source) {
+ if (mMarkerValues.size() != 2) {
+ throw new RuntimeException("Must use two marker values for direct mapping");
+ }
+ if (mMarkerValues.get(0).getProperty() != mMarkerValues.get(1).getProperty()) {
+ throw new RuntimeException(
+ "Marker value must use same Property for direct mapping");
+ }
+ int value1 = ((Parallax.IntPropertyMarkerValue) mMarkerValues.get(0))
+ .getMarkerValue(source);
+ int value2 = ((Parallax.IntPropertyMarkerValue) mMarkerValues.get(1))
+ .getMarkerValue(source);
+ if (value1 > value2) {
+ int swapValue = value2;
+ value2 = value1;
+ value1 = swapValue;
+ }
+
+ Number currentValue = ((IntProperty) mMarkerValues.get(0).getProperty()).get(source);
+ if (currentValue.intValue() < value1) {
+ currentValue = value1;
+ } else if (currentValue.intValue() > value2) {
+ currentValue = value2;
+ }
+ return currentValue;
+ }
+
+ @Override
+ float calculateFraction(Parallax source) {
int lastIndex = 0;
int lastValue = 0;
int lastMarkerValue = 0;
// go through all markerValues, find first markerValue that current value is less than.
for (int i = 0; i < mMarkerValues.size(); i++) {
- Parallax.IntPropertyMarkerValue k = mMarkerValues.get(i);
+ Parallax.IntPropertyMarkerValue k = (Parallax.IntPropertyMarkerValue)
+ mMarkerValues.get(i);
int index = k.getProperty().getIndex();
int markerValue = k.getMarkerValue(source);
- int currentValue = source.getPropertyValue(index);
+ int currentValue = source.getIntPropertyValue(index);
float fraction;
if (i == 0) {
@@ -294,21 +370,47 @@
/**
* Implementation of {@link ParallaxEffect} for float type.
*/
- public static final class FloatEffect extends ParallaxEffect<FloatEffect,
- Parallax.FloatPropertyMarkerValue> {
+ static final class FloatEffect extends ParallaxEffect {
@Override
- protected float calculateFraction(Parallax s) {
- Parallax.FloatParallax source = (Parallax.FloatParallax) s;
+ Number calculateDirectValue(Parallax source) {
+ if (mMarkerValues.size() != 2) {
+ throw new RuntimeException("Must use two marker values for direct mapping");
+ }
+ if (mMarkerValues.get(0).getProperty() != mMarkerValues.get(1).getProperty()) {
+ throw new RuntimeException(
+ "Marker value must use same Property for direct mapping");
+ }
+ float value1 = ((FloatPropertyMarkerValue) mMarkerValues.get(0))
+ .getMarkerValue(source);
+ float value2 = ((FloatPropertyMarkerValue) mMarkerValues.get(1))
+ .getMarkerValue(source);
+ if (value1 > value2) {
+ float swapValue = value2;
+ value2 = value1;
+ value1 = swapValue;
+ }
+
+ Number currentValue = ((FloatProperty) mMarkerValues.get(0).getProperty()).get(source);
+ if (currentValue.floatValue() < value1) {
+ currentValue = value1;
+ } else if (currentValue.floatValue() > value2) {
+ currentValue = value2;
+ }
+ return currentValue;
+ }
+
+ @Override
+ float calculateFraction(Parallax source) {
int lastIndex = 0;
float lastValue = 0;
float lastMarkerValue = 0;
// go through all markerValues, find first markerValue that current value is less than.
for (int i = 0; i < mMarkerValues.size(); i++) {
- FloatPropertyMarkerValue k = mMarkerValues.get(i);
+ FloatPropertyMarkerValue k = (FloatPropertyMarkerValue) mMarkerValues.get(i);
int index = k.getProperty().getIndex();
float markerValue = k.getMarkerValue(source);
- float currentValue = source.getPropertyValue(index);
+ float currentValue = source.getFloatPropertyValue(index);
float fraction;
if (i == 0) {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ParallaxTarget.java b/v17/leanback/src/android/support/v17/leanback/widget/ParallaxTarget.java
index 7020433..49783ab 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ParallaxTarget.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ParallaxTarget.java
@@ -18,32 +18,51 @@
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
+import android.util.Property;
import android.view.animation.LinearInterpolator;
/**
- * ParallaxTarget is responsible for updating the target through the {@link #update(float)} method.
- * {@link ParallaxEffect} transforms the values of {@link Parallax}, which represents the
- * current state of UI, into a float value between 0 and 1. That float value is passed into
- * {@link #update(float)} method.
+ * ParallaxTarget is responsible for updating the target through the {@link #update(float)} method
+ * or the {@link #directUpdate(Number)} method when {@link #isDirectMapping()} is true.
+ * When {@link #isDirectMapping()} is false, {@link ParallaxEffect} transforms the values of
+ * {@link Parallax}, which represents the current state of UI, into a float value between 0 and 1.
+ * That float value is passed into {@link #update(float)} method.
*/
public abstract class ParallaxTarget {
/**
* Implementation class is supposed to update target with the provided fraction
* (between 0 and 1). The fraction represents percentage of completed change (e.g. scroll) on
- * target.
+ * target. Called only when {@link #isDirectMapping()} is false.
*
* @param fraction Fraction between 0 to 1.
+ * @see #isDirectMapping()
*/
- public abstract void update(float fraction);
+ public void update(float fraction) {
+ }
/**
- * Returns the current fraction (between 0 and 1). The fraction represents percentage of
- * completed change (e.g. scroll) on target.
+ * Returns true if the ParallaxTarget is directly mapping from source value,
+ * {@link #directUpdate(Number)} will be used to update value, otherwise update(fraction) will
+ * be called to update value. Default implementation returns false.
*
- * @return Current fraction value.
+ * @return True if direct mapping, false otherwise.
+ * @see #directUpdate(Number)
+ * @see #update(float)
*/
- public abstract float getFraction();
+ public boolean isDirectMapping() {
+ return false;
+ }
+
+ /**
+ * Directly update the target using a float or int value. Called when {@link #isDirectMapping()}
+ * is true.
+ *
+ * @param value Either int or float value.
+ * @see #isDirectMapping()
+ */
+ public void directUpdate(Number value) {
+ }
/**
* PropertyValuesHolderTarget is an implementation of {@link ParallaxTarget} that uses
@@ -72,9 +91,42 @@
mAnimator.setCurrentPlayTime((long) (PSEUDO_DURATION * fraction));
}
+ }
+
+ /**
+ * DirectPropertyTarget is to support direct mapping into either Integer Property or Float
+ * Property. App uses convenient method {@link ParallaxEffect#target(Object, Property)} to
+ * add a direct mapping.
+ * @param <T> Type of target object.
+ * @param <V> Type of value, either Integer or Float.
+ */
+ public static final class DirectPropertyTarget<T extends Object, V extends Number>
+ extends ParallaxTarget {
+
+ Object mObject;
+ Property<T, V> mProperty;
+
+ /**
+ * @param targetObject Target object for perform Parallax
+ * @param property Target property, either an Integer Property or a Float Property.
+ */
+ public DirectPropertyTarget(Object targetObject, Property<T, V> property) {
+ mObject = targetObject;
+ mProperty = property;
+ }
+
+ /**
+ * Returns true as DirectPropertyTarget receives a number to update Property in
+ * {@link #directUpdate(Number)}.
+ */
@Override
- public float getFraction() {
- return mFraction;
+ public boolean isDirectMapping() {
+ return true;
+ }
+
+ @Override
+ public void directUpdate(Number value) {
+ mProperty.set((T) mObject, (V) value);
}
}
}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRow.java b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRow.java
index 83aff47..f54a454 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRow.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRow.java
@@ -13,20 +13,18 @@
*/
package android.support.v17.leanback.widget;
-import android.support.v17.leanback.R;
-import android.support.v17.leanback.util.MathUtil;
-import android.util.TypedValue;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
import android.graphics.Canvas;
-import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.support.v17.leanback.R;
+import android.support.v17.leanback.util.MathUtil;
+import android.util.TypedValue;
import android.view.KeyEvent;
/**
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/RecyclerViewParallax.java b/v17/leanback/src/android/support/v17/leanback/widget/RecyclerViewParallax.java
index 20c40f9..589eef5 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/RecyclerViewParallax.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/RecyclerViewParallax.java
@@ -22,6 +22,7 @@
import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
+import android.util.Property;
import android.view.View;
/**
@@ -29,8 +30,7 @@
* allows users to track position of specific views inside {@link RecyclerView} relative to
* itself. @see {@link ChildPositionProperty} for details.
*/
-public class RecyclerViewParallax extends
- Parallax.IntParallax<RecyclerViewParallax.ChildPositionProperty> {
+public class RecyclerViewParallax extends Parallax<RecyclerViewParallax.ChildPositionProperty> {
RecyclerView mRecylerView;
boolean mIsVertical;
@@ -141,16 +141,16 @@
: recyclerView.findViewHolderForAdapterPosition(mAdapterPosition);
if (viewHolder == null) {
if (recyclerView == null || recyclerView.getLayoutManager().getChildCount() == 0) {
- source.setPropertyValue(getIndex(), IntProperty.UNKNOWN_AFTER);
+ source.setIntPropertyValue(getIndex(), IntProperty.UNKNOWN_AFTER);
return;
}
View firstChild = recyclerView.getLayoutManager().getChildAt(0);
ViewHolder vh = recyclerView.findContainingViewHolder(firstChild);
int firstPosition = vh.getAdapterPosition();
if (firstPosition < mAdapterPosition) {
- source.setPropertyValue(getIndex(), IntProperty.UNKNOWN_AFTER);
+ source.setIntPropertyValue(getIndex(), IntProperty.UNKNOWN_AFTER);
} else {
- source.setPropertyValue(getIndex(), IntProperty.UNKNOWN_BEFORE);
+ source.setIntPropertyValue(getIndex(), IntProperty.UNKNOWN_BEFORE);
}
} else {
View trackingView = viewHolder.itemView.findViewById(mViewId);
@@ -171,10 +171,10 @@
}
rect.offset((int) tx, (int) ty);
if (source.mIsVertical) {
- source.setPropertyValue(getIndex(), rect.top + mOffset
+ source.setIntPropertyValue(getIndex(), rect.top + mOffset
+ (int) (mFraction * rect.height()));
} else {
- source.setPropertyValue(getIndex(), rect.left + mOffset
+ source.setIntPropertyValue(getIndex(), rect.left + mOffset
+ (int) (mFraction * rect.width()));
}
}
@@ -188,7 +188,7 @@
}
@Override
- public int getMaxValue() {
+ public float getMaxValue() {
if (mRecylerView == null) {
return 0;
}
@@ -221,8 +221,8 @@
*/
@Override
public void updateValues() {
- for (ChildPositionProperty prop: getProperties()) {
- prop.updateValue(RecyclerViewParallax.this);
+ for (Property prop: getProperties()) {
+ ((ChildPositionProperty) prop).updateValue(RecyclerViewParallax.this);
}
super.updateValues();
}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/SearchEditText.java b/v17/leanback/src/android/support/v17/leanback/widget/SearchEditText.java
index 56c63cf..51047d3 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/SearchEditText.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/SearchEditText.java
@@ -18,7 +18,6 @@
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
-import android.widget.EditText;
/**
* EditText widget that monitors keyboard changes.
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/StaggeredGrid.java b/v17/leanback/src/android/support/v17/leanback/widget/StaggeredGrid.java
index 1d731db..88d0aad 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/StaggeredGrid.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/StaggeredGrid.java
@@ -17,8 +17,6 @@
import android.support.v4.util.CircularIntArray;
import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
/**
* A dynamic data structure that caches staggered grid position information
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/StaticShadowHelper.java b/v17/leanback/src/android/support/v17/leanback/widget/StaticShadowHelper.java
index 6c6e664..4422d62 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/StaticShadowHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/StaticShadowHelper.java
@@ -16,7 +16,6 @@
package android.support.v17.leanback.widget;
import android.os.Build;
-import android.view.View;
import android.view.ViewGroup;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/StreamingTextView.java b/v17/leanback/src/android/support/v17/leanback/widget/StreamingTextView.java
index 5bc0a8c..0b8781c 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/StreamingTextView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/StreamingTextView.java
@@ -13,13 +13,13 @@
*/
package android.support.v17.leanback.widget;
-import android.support.v17.leanback.R;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
+import android.support.v17.leanback.R;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.SpannedString;
@@ -31,7 +31,6 @@
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.EditText;
-import android.widget.TextView;
import java.util.List;
import java.util.Random;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/TitleViewAdapter.java b/v17/leanback/src/android/support/v17/leanback/widget/TitleViewAdapter.java
index 7156be2..de9db4b 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/TitleViewAdapter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/TitleViewAdapter.java
@@ -13,11 +13,7 @@
*/
package android.support.v17.leanback.widget;
-import android.content.Context;
import android.graphics.drawable.Drawable;
-import android.support.v17.leanback.R;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
import android.view.View;
/**
@@ -96,6 +92,10 @@
* @param listener The listener to call when the search element is clicked.
*/
public void setOnSearchClickedListener(View.OnClickListener listener) {
+ View view = getSearchAffordanceView();
+ if (view != null) {
+ view.setOnClickListener(listener);
+ }
}
/**
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/VerticalGridPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/VerticalGridPresenter.java
index edb3ab2..56b6ed1 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/VerticalGridPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/VerticalGridPresenter.java
@@ -17,11 +17,10 @@
import android.support.v17.leanback.R;
import android.support.v17.leanback.system.Settings;
import android.support.v17.leanback.transition.TransitionHelper;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.util.Log;
/**
* A presenter that renders objects in a {@link VerticalGridView}.
diff --git a/v17/leanback/tests/generatev4.py b/v17/leanback/tests/generatev4.py
index 34ace00..2e228eb 100755
--- a/v17/leanback/tests/generatev4.py
+++ b/v17/leanback/tests/generatev4.py
@@ -136,12 +136,12 @@
line = line.replace('IntEffect', 'FloatEffect')
line = line.replace('IntParallax', 'FloatParallax')
line = line.replace('IntProperty', 'FloatProperty')
- line = line.replace('IntValue', 'FloatValue')
line = line.replace('intValue()', 'floatValue()')
- line = line.replace('int getMaxValue', 'float getMaxValue')
line = line.replace('int screenMax', 'float screenMax')
line = line.replace('assertEquals((int)', 'assertFloatEquals((float)')
line = line.replace('(int)', '(float)')
+ line = line.replace('int[', 'float[')
+ line = line.replace('Integer', 'Float');
outfile.write(line)
file.close()
outfile.close()
@@ -156,9 +156,8 @@
line = line.replace('ParallaxIntTest', 'ParallaxFloatTest')
line = line.replace('IntParallax', 'FloatParallax')
line = line.replace('IntProperty', 'FloatProperty')
- line = line.replace('IntValue', 'FloatValue')
+ line = line.replace('verifyIntProperties', 'verifyFloatProperties')
line = line.replace('intValue()', 'floatValue()')
- line = line.replace('int getMaxValue', 'float getMaxValue')
line = line.replace('int screenMax', 'float screenMax')
line = line.replace('assertEquals((int)', 'assertFloatEquals((float)')
line = line.replace('(int)', '(float)')
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsFragmentTest.java
index 50168a7..b70cc28 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsFragmentTest.java
@@ -30,7 +30,6 @@
import android.os.Bundle;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
-import android.support.test.filters.Suppress;
import android.support.v17.leanback.R;
import android.support.v17.leanback.graphics.FitWidthBitmapDrawable;
import android.support.v17.leanback.media.MediaPlayerGlue;
@@ -125,7 +124,6 @@
assertEquals(0f, frameBottom.getAdapterPosition(), delta);
}
- @Suppress // Disabled due to flakiness.
@Test
public void parallaxTest() throws Throwable {
launchAndWaitActivity(DetailsFragmentParallax.class,
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsSupportFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsSupportFragmentTest.java
index cd6032e..3880a7c 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsSupportFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsSupportFragmentTest.java
@@ -33,7 +33,6 @@
import android.os.Bundle;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
-import android.support.test.filters.Suppress;
import android.support.v17.leanback.R;
import android.support.v17.leanback.graphics.FitWidthBitmapDrawable;
import android.support.v17.leanback.media.MediaPlayerGlue;
@@ -128,7 +127,6 @@
assertEquals(0f, frameBottom.getAdapterPosition(), delta);
}
- @Suppress // Disabled due to flakiness.
@Test
public void parallaxTest() throws Throwable {
launchAndWaitActivity(DetailsSupportFragmentParallax.class,
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
index 326d2be..70c8795 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlGlueTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlGlueTest.java
@@ -597,9 +597,53 @@
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
index 944c1f7..37f5754 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlSupportGlueTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlSupportGlueTest.java
@@ -600,9 +600,53 @@
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/PlaybackFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackFragmentTest.java
index b1c6d14..6f6459a 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackFragmentTest.java
@@ -15,6 +15,8 @@
*/
package android.support.v17.leanback.app;
+import static junit.framework.Assert.assertEquals;
+
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
@@ -22,20 +24,25 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
import android.support.v17.leanback.media.PlaybackControlGlue;
import android.support.v17.leanback.media.PlaybackGlue;
import android.support.v17.leanback.testutils.PollingCheck;
+import android.support.v17.leanback.widget.ControlButtonPresenterSelector;
import android.support.v17.leanback.widget.ListRow;
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.view.KeyEvent;
+import android.view.View;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -106,7 +113,6 @@
verify(selectedListener, times(0)).onItemSelected(any(Presenter.ViewHolder.class),
any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
- Thread.sleep(TRANSITION_LENGTH);
verify(selectedListener, times(1)).onItemSelected(itemVHCaptor.capture(),
itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -114,7 +120,6 @@
assertSame("The selected action should be rewind", rewind, itemCaptor.getValue());
sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
- Thread.sleep(TRANSITION_LENGTH);
verify(selectedListener, times(2)).onItemSelected(itemVHCaptor.capture(),
itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -125,7 +130,7 @@
ListRow listRow0 = (ListRow) fragment.getAdapter().get(1);
sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
- Thread.sleep(TRANSITION_LENGTH);
+ waitForScrollIdle(fragment.getVerticalGridView());
verify(selectedListener, times(3)).onItemSelected(itemVHCaptor.capture(),
itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
assertSame("Same list row should be passed to the listener", listRow0,
@@ -174,7 +179,6 @@
verify(clickedListener, times(0)).onItemClicked(any(Presenter.ViewHolder.class),
any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
- Thread.sleep(TRANSITION_LENGTH);
verify(clickedListener, times(1)).onItemClicked(itemVHCaptor.capture(),
itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -182,11 +186,9 @@
assertSame("The clicked action should be playPause", playPause, itemCaptor.getValue());
sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
- Thread.sleep(TRANSITION_LENGTH);
verify(clickedListener, times(1)).onItemClicked(any(Presenter.ViewHolder.class),
any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
- Thread.sleep(TRANSITION_LENGTH);
verify(clickedListener, times(2)).onItemClicked(itemVHCaptor.capture(),
itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -194,11 +196,9 @@
assertSame("The clicked action should be rewind", rewind, itemCaptor.getValue());
sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
- Thread.sleep(TRANSITION_LENGTH);
verify(clickedListener, times(2)).onItemClicked(any(Presenter.ViewHolder.class),
any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
- Thread.sleep(TRANSITION_LENGTH);
verify(clickedListener, times(3)).onItemClicked(itemVHCaptor.capture(),
itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -209,11 +209,10 @@
ListRow listRow0 = (ListRow) fragment.getAdapter().get(1);
sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
- Thread.sleep(TRANSITION_LENGTH);
+ waitForScrollIdle(fragment.getVerticalGridView());
verify(clickedListener, times(3)).onItemClicked(any(Presenter.ViewHolder.class),
any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
- Thread.sleep(TRANSITION_LENGTH);
verify(clickedListener, times(4)).onItemClicked(itemVHCaptor.capture(),
itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
assertSame("Same list row should be passed to the listener", listRow0,
@@ -224,4 +223,139 @@
listRowItemPassed);
}
+ @Test
+ public void alignmentRowToBottom() throws Throwable {
+ launchAndWaitActivity(PlaybackTestFragment.class, 1000);
+ final PlaybackTestFragment fragment = (PlaybackTestFragment) mActivity.getTestFragment();
+
+ assertTrue(fragment.getAdapter().size() > 2);
+
+ View playRow = fragment.getVerticalGridView().getChildAt(0);
+ assertTrue(playRow.hasFocus());
+ assertEquals(playRow.getResources().getDimensionPixelSize(
+ android.support.v17.leanback.test.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(
+ android.support.v17.leanback.test.R.dimen.lb_playback_controls_padding_bottom),
+ fragment.getVerticalGridView().getHeight() - lastRow.getBottom());
+ }
+
+ public static class PurePlaybackFragment extends PlaybackFragment {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setFadingEnabled(false);
+ PlaybackControlsRow row = new PlaybackControlsRow();
+ SparseArrayObjectAdapter primaryAdapter = new SparseArrayObjectAdapter(
+ new ControlButtonPresenterSelector());
+ primaryAdapter.set(0, new PlaybackControlsRow.SkipPreviousAction(getActivity()));
+ primaryAdapter.set(1, new PlaybackControlsRow.PlayPauseAction(getActivity()));
+ primaryAdapter.set(2, new PlaybackControlsRow.SkipNextAction(getActivity()));
+ row.setPrimaryActionsAdapter(primaryAdapter);
+ row.setSecondaryActionsAdapter(null);
+ setPlaybackRow(row);
+ setPlaybackRowPresenter(new PlaybackControlsRowPresenter());
+ }
+ }
+
+ @Test
+ public void setupRowAndPresenterWithoutGlue() {
+ launchAndWaitActivity(PurePlaybackFragment.class, 1000);
+ final PurePlaybackFragment fragment = (PurePlaybackFragment)
+ mActivity.getTestFragment();
+
+ assertTrue(fragment.getAdapter().size() == 1);
+ View playRow = fragment.getVerticalGridView().getChildAt(0);
+ assertTrue(playRow.hasFocus());
+ assertEquals(playRow.getResources().getDimensionPixelSize(
+ android.support.v17.leanback.test.R.dimen.lb_playback_controls_padding_bottom),
+ fragment.getVerticalGridView().getHeight() - playRow.getBottom());
+ }
+
+ public static class ControlGlueFragment extends PlaybackFragment {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ int[] ffspeeds = new int[] {PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0,
+ PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1};
+ PlaybackGlue glue = new PlaybackControlGlue(
+ getActivity(), ffspeeds) {
+ @Override
+ public boolean hasValidMedia() {
+ return true;
+ }
+
+ @Override
+ public boolean isMediaPlaying() {
+ return false;
+ }
+
+ @Override
+ public CharSequence getMediaTitle() {
+ return "Title";
+ }
+
+ @Override
+ public CharSequence getMediaSubtitle() {
+ return "SubTitle";
+ }
+
+ @Override
+ public int getMediaDuration() {
+ return 100;
+ }
+
+ @Override
+ public Drawable getMediaArt() {
+ return null;
+ }
+
+ @Override
+ public long getSupportedActions() {
+ return PlaybackControlGlue.ACTION_PLAY_PAUSE;
+ }
+
+ @Override
+ public int getCurrentSpeedId() {
+ return PlaybackControlGlue.PLAYBACK_SPEED_PAUSED;
+ }
+
+ @Override
+ public int getCurrentPosition() {
+ return 50;
+ }
+ };
+ glue.setHost(new PlaybackFragmentGlueHost(this));
+ }
+ }
+
+ @Test
+ public void setupWithControlGlue() throws Throwable {
+ launchAndWaitActivity(ControlGlueFragment.class, 1000);
+ final ControlGlueFragment fragment = (ControlGlueFragment)
+ mActivity.getTestFragment();
+
+ assertTrue(fragment.getAdapter().size() == 1);
+
+ View playRow = fragment.getVerticalGridView().getChildAt(0);
+ assertTrue(playRow.hasFocus());
+ assertEquals(playRow.getResources().getDimensionPixelSize(
+ android.support.v17.leanback.test.R.dimen.lb_playback_controls_padding_bottom),
+ fragment.getVerticalGridView().getHeight() - playRow.getBottom());
+ }
}
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
index dfc3458..be78f79 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayFragmentTest.java
@@ -15,12 +15,15 @@
*/
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.MediumTest;
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;
@@ -40,4 +43,38 @@
assertTrue(fragment.getView().hasFocus());
}
+ @Test
+ public void alignmentRowToBottom() throws Throwable {
+ launchAndWaitActivity(PlaybackOverlayTestFragment.class,
+ new Options().activityLayoutId(R.layout.playback_controls_with_video), 0);
+ final PlaybackOverlayTestFragment fragment = (PlaybackOverlayTestFragment)
+ mActivity.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
index 388cfc8..de8ff88 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayTestFragment.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayTestFragment.java
@@ -22,6 +22,7 @@
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;
@@ -62,7 +63,6 @@
private PlaybackControlHelper mGlue;
private PlaybackControlsRowPresenter mPlaybackControlsRowPresenter;
- private ListRowPresenter mListRowPresenter;
private OnItemViewClickedListener mOnItemViewClickedListener = new OnItemViewClickedListener() {
@Override
@@ -136,19 +136,11 @@
mPlaybackControlsRowPresenter = mGlue.createControlsRowAndPresenter();
mPlaybackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
- mListRowPresenter = new ListRowPresenter();
+ ClassPresenterSelector selector = new ClassPresenterSelector();
+ selector.addClassPresenter(ListRow.class, new ListRowPresenter());
+ selector.addClassPresenter(PlaybackControlsRow.class, mPlaybackControlsRowPresenter);
- setAdapter(new SparseArrayObjectAdapter(new PresenterSelector() {
- @Override
- public Presenter getPresenter(Object object) {
- if (object instanceof PlaybackControlsRow) {
- return mPlaybackControlsRowPresenter;
- } else if (object instanceof ListRow) {
- return mListRowPresenter;
- }
- throw new IllegalArgumentException("Unhandled object: " + object);
- }
- }));
+ setAdapter(new SparseArrayObjectAdapter(selector));
// Add the controls row
getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackSupportFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackSupportFragmentTest.java
index b21ea01..fc9867e 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackSupportFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackSupportFragmentTest.java
@@ -18,6 +18,8 @@
*/
package android.support.v17.leanback.app;
+import static junit.framework.Assert.assertEquals;
+
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
@@ -25,20 +27,25 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
import android.support.v17.leanback.media.PlaybackControlGlue;
import android.support.v17.leanback.media.PlaybackGlue;
import android.support.v17.leanback.testutils.PollingCheck;
+import android.support.v17.leanback.widget.ControlButtonPresenterSelector;
import android.support.v17.leanback.widget.ListRow;
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.view.KeyEvent;
+import android.view.View;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -109,7 +116,6 @@
verify(selectedListener, times(0)).onItemSelected(any(Presenter.ViewHolder.class),
any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
- Thread.sleep(TRANSITION_LENGTH);
verify(selectedListener, times(1)).onItemSelected(itemVHCaptor.capture(),
itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -117,7 +123,6 @@
assertSame("The selected action should be rewind", rewind, itemCaptor.getValue());
sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
- Thread.sleep(TRANSITION_LENGTH);
verify(selectedListener, times(2)).onItemSelected(itemVHCaptor.capture(),
itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -128,7 +133,7 @@
ListRow listRow0 = (ListRow) fragment.getAdapter().get(1);
sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
- Thread.sleep(TRANSITION_LENGTH);
+ waitForScrollIdle(fragment.getVerticalGridView());
verify(selectedListener, times(3)).onItemSelected(itemVHCaptor.capture(),
itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
assertSame("Same list row should be passed to the listener", listRow0,
@@ -177,7 +182,6 @@
verify(clickedListener, times(0)).onItemClicked(any(Presenter.ViewHolder.class),
any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
- Thread.sleep(TRANSITION_LENGTH);
verify(clickedListener, times(1)).onItemClicked(itemVHCaptor.capture(),
itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -185,11 +189,9 @@
assertSame("The clicked action should be playPause", playPause, itemCaptor.getValue());
sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
- Thread.sleep(TRANSITION_LENGTH);
verify(clickedListener, times(1)).onItemClicked(any(Presenter.ViewHolder.class),
any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
- Thread.sleep(TRANSITION_LENGTH);
verify(clickedListener, times(2)).onItemClicked(itemVHCaptor.capture(),
itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -197,11 +199,9 @@
assertSame("The clicked action should be rewind", rewind, itemCaptor.getValue());
sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
- Thread.sleep(TRANSITION_LENGTH);
verify(clickedListener, times(2)).onItemClicked(any(Presenter.ViewHolder.class),
any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
- Thread.sleep(TRANSITION_LENGTH);
verify(clickedListener, times(3)).onItemClicked(itemVHCaptor.capture(),
itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -212,11 +212,10 @@
ListRow listRow0 = (ListRow) fragment.getAdapter().get(1);
sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
- Thread.sleep(TRANSITION_LENGTH);
+ waitForScrollIdle(fragment.getVerticalGridView());
verify(clickedListener, times(3)).onItemClicked(any(Presenter.ViewHolder.class),
any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
- Thread.sleep(TRANSITION_LENGTH);
verify(clickedListener, times(4)).onItemClicked(itemVHCaptor.capture(),
itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
assertSame("Same list row should be passed to the listener", listRow0,
@@ -227,4 +226,139 @@
listRowItemPassed);
}
+ @Test
+ public void alignmentRowToBottom() throws Throwable {
+ launchAndWaitActivity(PlaybackTestSupportFragment.class, 1000);
+ final PlaybackTestSupportFragment fragment = (PlaybackTestSupportFragment) mActivity.getTestFragment();
+
+ assertTrue(fragment.getAdapter().size() > 2);
+
+ View playRow = fragment.getVerticalGridView().getChildAt(0);
+ assertTrue(playRow.hasFocus());
+ assertEquals(playRow.getResources().getDimensionPixelSize(
+ android.support.v17.leanback.test.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(
+ android.support.v17.leanback.test.R.dimen.lb_playback_controls_padding_bottom),
+ fragment.getVerticalGridView().getHeight() - lastRow.getBottom());
+ }
+
+ public static class PurePlaybackSupportFragment extends PlaybackSupportFragment {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setFadingEnabled(false);
+ PlaybackControlsRow row = new PlaybackControlsRow();
+ SparseArrayObjectAdapter primaryAdapter = new SparseArrayObjectAdapter(
+ new ControlButtonPresenterSelector());
+ primaryAdapter.set(0, new PlaybackControlsRow.SkipPreviousAction(getActivity()));
+ primaryAdapter.set(1, new PlaybackControlsRow.PlayPauseAction(getActivity()));
+ primaryAdapter.set(2, new PlaybackControlsRow.SkipNextAction(getActivity()));
+ row.setPrimaryActionsAdapter(primaryAdapter);
+ row.setSecondaryActionsAdapter(null);
+ setPlaybackRow(row);
+ setPlaybackRowPresenter(new PlaybackControlsRowPresenter());
+ }
+ }
+
+ @Test
+ public void setupRowAndPresenterWithoutGlue() {
+ launchAndWaitActivity(PurePlaybackSupportFragment.class, 1000);
+ final PurePlaybackSupportFragment fragment = (PurePlaybackSupportFragment)
+ mActivity.getTestFragment();
+
+ assertTrue(fragment.getAdapter().size() == 1);
+ View playRow = fragment.getVerticalGridView().getChildAt(0);
+ assertTrue(playRow.hasFocus());
+ assertEquals(playRow.getResources().getDimensionPixelSize(
+ android.support.v17.leanback.test.R.dimen.lb_playback_controls_padding_bottom),
+ fragment.getVerticalGridView().getHeight() - playRow.getBottom());
+ }
+
+ public static class ControlGlueFragment extends PlaybackSupportFragment {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ int[] ffspeeds = new int[] {PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0,
+ PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1};
+ PlaybackGlue glue = new PlaybackControlGlue(
+ getActivity(), ffspeeds) {
+ @Override
+ public boolean hasValidMedia() {
+ return true;
+ }
+
+ @Override
+ public boolean isMediaPlaying() {
+ return false;
+ }
+
+ @Override
+ public CharSequence getMediaTitle() {
+ return "Title";
+ }
+
+ @Override
+ public CharSequence getMediaSubtitle() {
+ return "SubTitle";
+ }
+
+ @Override
+ public int getMediaDuration() {
+ return 100;
+ }
+
+ @Override
+ public Drawable getMediaArt() {
+ return null;
+ }
+
+ @Override
+ public long getSupportedActions() {
+ return PlaybackControlGlue.ACTION_PLAY_PAUSE;
+ }
+
+ @Override
+ public int getCurrentSpeedId() {
+ return PlaybackControlGlue.PLAYBACK_SPEED_PAUSED;
+ }
+
+ @Override
+ public int getCurrentPosition() {
+ return 50;
+ }
+ };
+ glue.setHost(new PlaybackSupportFragmentGlueHost(this));
+ }
+ }
+
+ @Test
+ public void setupWithControlGlue() throws Throwable {
+ launchAndWaitActivity(ControlGlueFragment.class, 1000);
+ final ControlGlueFragment fragment = (ControlGlueFragment)
+ mActivity.getTestFragment();
+
+ assertTrue(fragment.getAdapter().size() == 1);
+
+ View playRow = fragment.getVerticalGridView().getChildAt(0);
+ assertTrue(playRow.hasFocus());
+ assertEquals(playRow.getResources().getDimensionPixelSize(
+ android.support.v17.leanback.test.R.dimen.lb_playback_controls_padding_bottom),
+ fragment.getVerticalGridView().getHeight() - playRow.getBottom());
+ }
}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackTestFragment.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackTestFragment.java
index 99a7fc6..c9cc5b2 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackTestFragment.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackTestFragment.java
@@ -23,6 +23,7 @@
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.HeaderItem;
import android.support.v17.leanback.widget.ListRow;
import android.support.v17.leanback.widget.ListRowPresenter;
@@ -46,8 +47,6 @@
*/
private static final int BACKGROUND_TYPE = PlaybackFragment.BG_LIGHT;
- private static final int ROW_CONTROLS = 0;
-
/**
* Change this to select hidden
*/
@@ -59,7 +58,6 @@
private static final int RELATED_CONTENT_ROWS = 3;
private android.support.v17.leanback.media.PlaybackControlGlue mGlue;
- private ListRowPresenter mListRowPresenter;
boolean mDestroyCalled;
@Override
@@ -120,23 +118,10 @@
};
mGlue.setHost(new PlaybackFragmentGlueHost(this));
- // mGlue.setOnI
- mListRowPresenter = new ListRowPresenter();
+ ClassPresenterSelector selector = new ClassPresenterSelector();
+ selector.addClassPresenter(ListRow.class, new ListRowPresenter());
- setAdapter(new SparseArrayObjectAdapter(new PresenterSelector() {
- @Override
- public Presenter getPresenter(Object object) {
- if (object instanceof PlaybackControlsRow) {
- return mGlue.getControlsRowPresenter();
- } else if (object instanceof ListRow) {
- return mListRowPresenter;
- }
- throw new IllegalArgumentException("Unhandled object: " + object);
- }
- }));
-
- // Add the controls row
- getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
+ setAdapter(new SparseArrayObjectAdapter(selector));
// Add related content rows
for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
@@ -144,7 +129,7 @@
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));
+ getAdapter().set(1 + i, new ListRow(header, listRowAdapter));
}
}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackTestSupportFragment.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackTestSupportFragment.java
index ef99eb6..4e63522 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackTestSupportFragment.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackTestSupportFragment.java
@@ -26,6 +26,7 @@
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.HeaderItem;
import android.support.v17.leanback.widget.ListRow;
import android.support.v17.leanback.widget.ListRowPresenter;
@@ -49,8 +50,6 @@
*/
private static final int BACKGROUND_TYPE = PlaybackSupportFragment.BG_LIGHT;
- private static final int ROW_CONTROLS = 0;
-
/**
* Change this to select hidden
*/
@@ -62,7 +61,6 @@
private static final int RELATED_CONTENT_ROWS = 3;
private android.support.v17.leanback.media.PlaybackControlGlue mGlue;
- private ListRowPresenter mListRowPresenter;
boolean mDestroyCalled;
@Override
@@ -123,23 +121,10 @@
};
mGlue.setHost(new PlaybackSupportFragmentGlueHost(this));
- // mGlue.setOnI
- mListRowPresenter = new ListRowPresenter();
+ ClassPresenterSelector selector = new ClassPresenterSelector();
+ selector.addClassPresenter(ListRow.class, new ListRowPresenter());
- setAdapter(new SparseArrayObjectAdapter(new PresenterSelector() {
- @Override
- public Presenter getPresenter(Object object) {
- if (object instanceof PlaybackControlsRow) {
- return mGlue.getControlsRowPresenter();
- } else if (object instanceof ListRow) {
- return mListRowPresenter;
- }
- throw new IllegalArgumentException("Unhandled object: " + object);
- }
- }));
-
- // Add the controls row
- getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
+ setAdapter(new SparseArrayObjectAdapter(selector));
// Add related content rows
for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
@@ -147,7 +132,7 @@
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));
+ getAdapter().set(1 + i, new ListRow(header, listRowAdapter));
}
}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/SingleFragmentTestBase.java b/v17/leanback/tests/java/android/support/v17/leanback/app/SingleFragmentTestBase.java
index 561facb..aec79a3 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/SingleFragmentTestBase.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/SingleFragmentTestBase.java
@@ -20,6 +20,7 @@
import android.support.test.InstrumentationRegistry;
import android.support.test.rule.ActivityTestRule;
import android.support.v17.leanback.testutils.PollingCheck;
+import android.support.v7.widget.RecyclerView;
import org.junit.After;
import org.junit.Rule;
@@ -27,6 +28,8 @@
public class SingleFragmentTestBase {
+ private static final long WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS = 60000;
+
@Rule
public TestName mUnitTestName = new TestName();
@@ -105,4 +108,28 @@
mActivity = activityTestRule.launchActivity(intent);
SystemClock.sleep(waitTimeMs);
}
+
+ protected void waitForScrollIdle(RecyclerView recyclerView) throws Throwable {
+ waitForScrollIdle(recyclerView, null);
+ }
+
+ protected void waitForScrollIdle(RecyclerView recyclerView, Runnable verify) throws Throwable {
+ Thread.sleep(100);
+ int total = 0;
+ while (recyclerView.getLayoutManager().isSmoothScrolling()
+ || recyclerView.getScrollState() != recyclerView.SCROLL_STATE_IDLE) {
+ if ((total += 100) >= WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS) {
+ throw new RuntimeException("waitForScrollIdle Timeout");
+ }
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException ex) {
+ break;
+ }
+ if (verify != null) {
+ activityTestRule.runOnUiThread(verify);
+ }
+ }
+ }
+
}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/SingleSupportFragmentTestBase.java b/v17/leanback/tests/java/android/support/v17/leanback/app/SingleSupportFragmentTestBase.java
index 3083ecf..bb2009f 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/SingleSupportFragmentTestBase.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/SingleSupportFragmentTestBase.java
@@ -23,6 +23,7 @@
import android.support.test.InstrumentationRegistry;
import android.support.test.rule.ActivityTestRule;
import android.support.v17.leanback.testutils.PollingCheck;
+import android.support.v7.widget.RecyclerView;
import org.junit.After;
import org.junit.Rule;
@@ -30,6 +31,8 @@
public class SingleSupportFragmentTestBase {
+ private static final long WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS = 60000;
+
@Rule
public TestName mUnitTestName = new TestName();
@@ -108,4 +111,28 @@
mActivity = activityTestRule.launchActivity(intent);
SystemClock.sleep(waitTimeMs);
}
+
+ protected void waitForScrollIdle(RecyclerView recyclerView) throws Throwable {
+ waitForScrollIdle(recyclerView, null);
+ }
+
+ protected void waitForScrollIdle(RecyclerView recyclerView, Runnable verify) throws Throwable {
+ Thread.sleep(100);
+ int total = 0;
+ while (recyclerView.getLayoutManager().isSmoothScrolling()
+ || recyclerView.getScrollState() != recyclerView.SCROLL_STATE_IDLE) {
+ if ((total += 100) >= WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS) {
+ throw new RuntimeException("waitForScrollIdle Timeout");
+ }
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException ex) {
+ break;
+ }
+ if (verify != null) {
+ activityTestRule.runOnUiThread(verify);
+ }
+ }
+ }
+
}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/TestActivity.java b/v17/leanback/tests/java/android/support/v17/leanback/app/TestActivity.java
index 7f9b408..9aa872c 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/TestActivity.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/TestActivity.java
@@ -83,7 +83,7 @@
public static final String EXTRA_PROVIDER = "testActivityProvider";
- static HashMap<String, Provider> sProviders = new HashMap();
+ static HashMap<String, Provider> sProviders = new HashMap<>();
String mProviderName;
Provider mProvider;
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedStepAttributesTestFragment.java b/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedStepAttributesTestFragment.java
index 3819dac..691a9df 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedStepAttributesTestFragment.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedStepAttributesTestFragment.java
@@ -18,7 +18,6 @@
import android.support.v17.leanback.app.GuidedStepFragment;
import android.support.v17.leanback.widget.GuidanceStylist;
import android.support.v17.leanback.widget.GuidedAction;
-import android.util.Log;
import java.util.HashMap;
import java.util.List;
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/graphics/CompositeDrawableTest.java b/v17/leanback/tests/java/android/support/v17/leanback/graphics/CompositeDrawableTest.java
index 132013a..df2c94c 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/graphics/CompositeDrawableTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/graphics/CompositeDrawableTest.java
@@ -28,6 +28,7 @@
import android.support.test.filters.SdkSuppress;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.support.v17.leanback.graphics.BoundsRule.ValueRule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -68,7 +69,7 @@
// inherit from parent
parentDrawable.addChildDrawable(drawable);
- parentDrawable.getChildAt(0).getBoundsRule().bottom = BoundsRule.inheritFromParent(
+ parentDrawable.getChildAt(0).getBoundsRule().bottom = ValueRule.inheritFromParent(
fraction);
parentDrawable.updateBounds(bounds);
@@ -79,7 +80,7 @@
// absolute value
drawable.setBounds(bounds);
- parentDrawable.getChildAt(0).getBoundsRule().bottom = BoundsRule.absoluteValue(200);
+ parentDrawable.getChildAt(0).getBoundsRule().bottom = ValueRule.absoluteValue(200);
parentDrawable.updateBounds(bounds);
adjustedBounds = drawable.getBounds();
@@ -89,7 +90,7 @@
// inherit with offset
parentDrawable.getChildAt(0).getBoundsRule().bottom =
- BoundsRule.inheritFromParentWithOffset(fraction, 100);
+ ValueRule.inheritFromParentWithOffset(fraction, 100);
parentDrawable.updateBounds(bounds);
adjustedBounds = drawable.getBounds();
@@ -100,7 +101,7 @@
// inherit from parent 2
bounds = new Rect(100, 200, WIDTH, HEIGHT);
parentDrawable.getChildAt(0).getBoundsRule().bottom =
- BoundsRule.inheritFromParent(fraction);
+ ValueRule.inheritFromParent(fraction);
parentDrawable.updateBounds(bounds);
adjustedBounds = drawable.getBounds();
@@ -124,8 +125,8 @@
// inherit from parent
BoundsRule boundsRule = parentDrawable.getChildAt(0).getBoundsRule();
- boundsRule.top = BoundsRule.absoluteValue(-200);
- boundsRule.bottom = BoundsRule.inheritFromParent(fraction);
+ boundsRule.top = ValueRule.absoluteValue(-200);
+ boundsRule.bottom = ValueRule.inheritFromParent(fraction);
parentDrawable.getChildAt(0).getBoundsRule().top.setAbsoluteValue(-100);
parentDrawable.updateBounds(bounds);
@@ -133,21 +134,32 @@
Rect adjustedBounds = drawable.getBounds();
Rect expectedBounds = new Rect(bounds);
expectedBounds.top = -100;
- expectedBounds.bottom = bounds.top + (int) (HEIGHT * fraction);
+ expectedBounds.bottom = (int) (HEIGHT * fraction);
assertEquals(expectedBounds, adjustedBounds);
// inherit from parent with offset
- boundsRule.bottom = BoundsRule.absoluteValue(HEIGHT);
+ boundsRule.bottom = ValueRule.inheritFromParentWithOffset(1f, -100);
parentDrawable.updateBounds(bounds);
adjustedBounds = drawable.getBounds();
expectedBounds = new Rect(bounds);
expectedBounds.top = -100;
- expectedBounds.bottom = HEIGHT;
+ expectedBounds.bottom = HEIGHT - 100;
+ assertEquals(expectedBounds, adjustedBounds);
+
+ // using property would change type:
+ CompositeDrawable.ChildDrawable.BOTTOM_ABSOLUTE.set(parentDrawable.getChildAt(0), 0);
+ CompositeDrawable.ChildDrawable.BOTTOM_FRACTION.set(parentDrawable.getChildAt(0), 0.5f);
+ parentDrawable.updateBounds(bounds);
+ adjustedBounds = drawable.getBounds();
+ expectedBounds = new Rect(bounds);
+ expectedBounds.top = -100;
+ expectedBounds.bottom = (int) (0.5f * HEIGHT);
assertEquals(expectedBounds, adjustedBounds);
}
+
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
@Test
public void constantState() {
@@ -184,7 +196,7 @@
FitWidthBitmapDrawable child = new FitWidthBitmapDrawable();
parent.addChildDrawable(child);
parent.getChildAt(0).getBoundsRule().bottom =
- BoundsRule.inheritFromParentWithOffset(.5f, 100);
+ ValueRule.inheritFromParentWithOffset(.5f, 100);
CompositeDrawable.ChildDrawable newChild = new CompositeDrawable.ChildDrawable(
parent.getChildAt(0),
@@ -201,7 +213,7 @@
FitWidthBitmapDrawable child = new FitWidthBitmapDrawable();
parent.addChildDrawable(child);
parent.getChildAt(0).getBoundsRule().bottom =
- BoundsRule.inheritFromParentWithOffset(.5f, 100);
+ ValueRule.inheritFromParentWithOffset(.5f, 100);
CompositeDrawable newDrawable = (CompositeDrawable) parent.getConstantState().newDrawable();
@@ -215,4 +227,5 @@
assertEquals(parent.getChildAt(0).getBoundsRule().bottom.getFraction(),
newChild.getBoundsRule().bottom.getFraction(), delta);
}
+
}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/testutils/PollingCheck.java b/v17/leanback/tests/java/android/support/v17/leanback/testutils/PollingCheck.java
index 2f2fc5d..77a903e 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/testutils/PollingCheck.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/testutils/PollingCheck.java
@@ -18,8 +18,6 @@
import android.app.Activity;
import android.view.View;
-import java.util.concurrent.Callable;
-
import junit.framework.Assert;
public abstract class PollingCheck {
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetTest.java
index 1e314e4..ff87b93 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetTest.java
@@ -224,7 +224,7 @@
*/
protected View[][] sortByRows() {
final HashMap<Integer, ArrayList<View>> rows = new HashMap<Integer, ArrayList<View>>();
- ArrayList<Integer> rowLocations = new ArrayList();
+ ArrayList<Integer> rowLocations = new ArrayList<>();
for (int i = 0; i < mGridView.getChildCount(); i++) {
View v = mGridView.getChildAt(i);
int rowLocation;
@@ -2890,7 +2890,7 @@
mNumRows = 1;
assertEquals(mGridView.getSelectedPosition(), 0);
- final SparseArray states = new SparseArray();
+ final SparseArray<Parcelable> states = new SparseArray<>();
mActivityTestRule.runOnUiThread(new Runnable() {
@Override
public void run() {
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxFloatEffectTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxFloatEffectTest.java
index eca3b9a..046b4c0 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxFloatEffectTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxFloatEffectTest.java
@@ -19,11 +19,14 @@
package android.support.v17.leanback.widget;
+import static junit.framework.Assert.assertEquals;
+
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.util.Property;
import org.junit.Before;
import org.junit.Test;
@@ -36,15 +39,19 @@
@SmallTest
public class ParallaxFloatEffectTest {
- Parallax.FloatParallax mSource;
+ Parallax<Parallax.FloatProperty> mSource;
int mScreenMax;
ParallaxEffect.FloatEffect mEffect;
@Mock ParallaxTarget mTarget;
+ static void assertFloatEquals(float expected, float actual) {
+ org.junit.Assert.assertEquals((double) expected, (double) actual, 0.0001d);
+ }
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mSource = new Parallax.FloatParallax<Parallax.FloatProperty>() {
+ mSource = new Parallax<Parallax.FloatProperty>() {
@Override
public float getMaxValue() {
@@ -68,55 +75,55 @@
mEffect.target(mTarget);
// start
- var1.setFloatValue(mSource, 540);
+ var1.setValue(mSource, 540);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0f);
Mockito.reset(mTarget);
// 25% complete
- var1.setFloatValue(mSource, 405);
+ var1.setValue(mSource, 405);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0.25f);
Mockito.reset(mTarget);
// middle
- var1.setFloatValue(mSource, 270);
+ var1.setValue(mSource, 270);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(.5f);
Mockito.reset(mTarget);
// 75% complete
- var1.setFloatValue(mSource, 135);
+ var1.setValue(mSource, 135);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0.75f);
Mockito.reset(mTarget);
// end
- var1.setFloatValue(mSource, 0);
+ var1.setValue(mSource, 0);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// after end
- var1.setFloatValue(mSource, -1000);
+ var1.setValue(mSource, -1000);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// before start
- var1.setFloatValue(mSource, 1000);
+ var1.setValue(mSource, 1000);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0f);
Mockito.reset(mTarget);
// unknown_before
- var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+ var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// unknown_after
- var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
+ var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0f);
Mockito.reset(mTarget);
@@ -129,7 +136,7 @@
mEffect.setPropertyRanges(var1.atAbsolute(540), var1.atAbsolute(550));
mEffect.target(mTarget);
- var1.setFloatValue(mSource, 0);
+ var1.setValue(mSource, 0);
mEffect.performMapping(mSource);
}
@@ -143,95 +150,137 @@
mEffect.target(mTarget);
// start
- var1.setFloatValue(mSource, 540);
- var2.setFloatValue(mSource, 840);
+ var1.setValue(mSource, 540);
+ var2.setValue(mSource, 840);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0f);
Mockito.reset(mTarget);
// middle
- var1.setFloatValue(mSource, 390);
- var2.setFloatValue(mSource, 690);
+ var1.setValue(mSource, 390);
+ var2.setValue(mSource, 690);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(.5f);
Mockito.reset(mTarget);
// end
- var1.setFloatValue(mSource, 240);
- var2.setFloatValue(mSource, 540);
+ var1.setValue(mSource, 240);
+ var2.setValue(mSource, 540);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// after end
- var1.setFloatValue(mSource, 200);
- var2.setFloatValue(mSource, 500);
+ var1.setValue(mSource, 200);
+ var2.setValue(mSource, 500);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// before start
- var1.setFloatValue(mSource, 1000);
- var2.setFloatValue(mSource, 1300);
+ var1.setValue(mSource, 1000);
+ var2.setValue(mSource, 1300);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0f);
Mockito.reset(mTarget);
// unknown_before
- var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
- var2.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+ var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+ var2.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// unknown_before
- var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
- var2.setFloatValue(mSource, -1000);
+ var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+ var2.setValue(mSource, -1000);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// unknown_after
- var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
- var2.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
+ var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
+ var2.setValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0f);
Mockito.reset(mTarget);
// unknown_after
- var1.setFloatValue(mSource, 1000);
- var2.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
+ var1.setValue(mSource, 1000);
+ var2.setValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0f);
Mockito.reset(mTarget);
// unknown_before and less
- var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
- var2.setFloatValue(mSource, 500);
+ var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+ var2.setValue(mSource, 500);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// unknown_before and hit second
- var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
- var2.setFloatValue(mSource, 540);
+ var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+ var2.setValue(mSource, 540);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// unknown_before with estimation
- var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
- var2.setFloatValue(mSource, 1080);
+ var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+ var2.setValue(mSource, 1080);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0.5f);
Mockito.reset(mTarget);
// unknown_after with estimation
- var1.setFloatValue(mSource, 0);
- var2.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
+ var1.setValue(mSource, 0);
+ var2.setValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0.5f);
Mockito.reset(mTarget);
}
+ @Test
+ public void testDirectMapping() {
+ mScreenMax = 1080;
+ Parallax.FloatProperty var1 = mSource.addProperty("var1");
+
+ mEffect.setPropertyRanges(var1.atAbsolute((float) 540.45), var1.atAbsolute((float) 0.22));
+ Object object = new Object();
+ final float[] properValue = new float[1];
+ Property<Object, Float> property = new Property<Object, Float>(Float.class, "attr") {
+ @Override
+ public void set(Object object, Float value) {
+ properValue[0] = value;
+ }
+
+ @Override
+ public Float get(Object o) {
+ return properValue[0];
+ }
+ };
+ mTarget = new ParallaxTarget.DirectPropertyTarget<>(object, property);
+ mEffect.target(mTarget);
+
+ var1.setValue(mSource, (float) 540.45);
+ mEffect.performMapping(mSource);
+ assertFloatEquals((float) 540.45, properValue[0]);
+
+ var1.setValue(mSource, (float) 405.85);
+ mEffect.performMapping(mSource);
+ assertFloatEquals((float) 405.85, properValue[0]);
+
+ var1.setValue(mSource, 2000);
+ mEffect.performMapping(mSource);
+ assertFloatEquals((float) 540.45, properValue[0]);
+
+ var1.setValue(mSource, (float) 0.22);
+ mEffect.performMapping(mSource);
+ assertFloatEquals((float) 0.22, properValue[0]);
+
+ var1.setValue(mSource, (float) 0.12);
+ mEffect.performMapping(mSource);
+ assertFloatEquals((float) 0.22, properValue[0]);
+ }
}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxFloatTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxFloatTest.java
index 23b8b5c..4b45cc2 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxFloatTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxFloatTest.java
@@ -32,7 +32,7 @@
@SmallTest
public class ParallaxFloatTest {
- Parallax.FloatParallax mSource;
+ Parallax<Parallax.FloatProperty> mSource;
int mScreenMax;
static void assertFloatEquals(float expected, float actual) {
@@ -41,7 +41,7 @@
@Before
public void setUp() throws Exception {
- mSource = new Parallax.FloatParallax<Parallax.FloatProperty>() {
+ mSource = new Parallax<Parallax.FloatProperty>() {
@Override
public float getMaxValue() {
@@ -59,8 +59,8 @@
public void testVariable() {
mScreenMax = 1080;
Parallax.FloatProperty var1 = mSource.addProperty("var1");
- var1.setFloatValue(mSource, 54);
- assertFloatEquals((float) 54, var1.getFloatValue(mSource));
+ var1.setValue(mSource, 54);
+ assertFloatEquals((float) 54, var1.getValue(mSource));
assertEquals(var1.getName(), "var1");
var1.set(mSource, (float) 2000);
assertFloatEquals((float) 2000, var1.get(mSource).floatValue());
@@ -71,7 +71,8 @@
mScreenMax = 1080;
Parallax.FloatProperty var1 = mSource.addProperty("var1");
- Parallax.FloatPropertyMarkerValue keyValue = var1.atAbsolute(1000);
+ Parallax.FloatPropertyMarkerValue keyValue = (Parallax.FloatPropertyMarkerValue)
+ var1.atAbsolute(1000);
assertSame(keyValue.getProperty(), var1);
assertFloatEquals((float) 1000, keyValue.getMarkerValue(mSource));
}
@@ -81,7 +82,8 @@
mScreenMax = 1080;
Parallax.FloatProperty var1 = mSource.addProperty("var1");
- Parallax.FloatPropertyMarkerValue keyValue = var1.at(0, 0.5f);
+ Parallax.FloatPropertyMarkerValue keyValue = (Parallax.FloatPropertyMarkerValue)
+ var1.at(0, 0.5f);
assertSame(keyValue.getProperty(), var1);
assertFloatEquals((float) 540, keyValue.getMarkerValue(mSource));
}
@@ -91,11 +93,13 @@
mScreenMax = 1080;
Parallax.FloatProperty var1 = mSource.addProperty("var1");
- Parallax.FloatPropertyMarkerValue keyValue = var1.at(-100, 0.5f);
+ Parallax.FloatPropertyMarkerValue keyValue = (Parallax.FloatPropertyMarkerValue)
+ var1.at(-100, 0.5f);
assertSame(keyValue.getProperty(), var1);
assertFloatEquals((float) 440, keyValue.getMarkerValue(mSource));
- Parallax.FloatPropertyMarkerValue keyValue2 = var1.at(100, 0.5f);
+ Parallax.FloatPropertyMarkerValue keyValue2 = (Parallax.FloatPropertyMarkerValue)
+ var1.at(100, 0.5f);
assertSame(keyValue2.getProperty(), var1);
assertFloatEquals((float) 640, keyValue2.getMarkerValue(mSource));
}
@@ -105,10 +109,10 @@
Parallax.FloatProperty var1 = mSource.addProperty("var1");
Parallax.FloatProperty var2 = mSource.addProperty("var2");
- var1.setFloatValue(mSource, (float) 500);
- var2.setFloatValue(mSource, (float) 499);
+ var1.setValue(mSource, (float) 500);
+ var2.setValue(mSource, (float) 499);
- mSource.verifyProperties();
+ mSource.verifyFloatProperties();
}
@Test(expected = IllegalStateException.class)
@@ -116,10 +120,10 @@
Parallax.FloatProperty var1 = mSource.addProperty("var1");
Parallax.FloatProperty var2 = mSource.addProperty("var2");
- var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
- var2.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
+ var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+ var2.setValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
- mSource.verifyProperties();
+ mSource.verifyFloatProperties();
}
@Test
@@ -127,19 +131,19 @@
Parallax.FloatProperty var1 = mSource.addProperty("var1");
Parallax.FloatProperty var2 = mSource.addProperty("var2");
- var1.setFloatValue(mSource, (float) 499);
- var2.setFloatValue(mSource, (float) 500);
+ var1.setValue(mSource, (float) 499);
+ var2.setValue(mSource, (float) 500);
- mSource.verifyProperties();
+ mSource.verifyFloatProperties();
- var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
- var2.setFloatValue(mSource, (float) 500);
+ var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+ var2.setValue(mSource, (float) 500);
- mSource.verifyProperties();
+ mSource.verifyFloatProperties();
- var1.setFloatValue(mSource, (float) 499);
- var2.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
+ var1.setValue(mSource, (float) 499);
+ var2.setValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
- mSource.verifyProperties();
+ mSource.verifyFloatProperties();
}
}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxIntEffectTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxIntEffectTest.java
index 398a0a8..4311fa6 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxIntEffectTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxIntEffectTest.java
@@ -16,11 +16,14 @@
package android.support.v17.leanback.widget;
+import static junit.framework.Assert.assertEquals;
+
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.util.Property;
import org.junit.Before;
import org.junit.Test;
@@ -33,18 +36,22 @@
@SmallTest
public class ParallaxIntEffectTest {
- Parallax.IntParallax mSource;
+ Parallax<Parallax.IntProperty> mSource;
int mScreenMax;
ParallaxEffect.IntEffect mEffect;
@Mock ParallaxTarget mTarget;
+ static void assertFloatEquals(float expected, float actual) {
+ org.junit.Assert.assertEquals((double) expected, (double) actual, 0.0001d);
+ }
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mSource = new Parallax.IntParallax<Parallax.IntProperty>() {
+ mSource = new Parallax<Parallax.IntProperty>() {
@Override
- public int getMaxValue() {
+ public float getMaxValue() {
return mScreenMax;
}
@@ -65,55 +72,55 @@
mEffect.target(mTarget);
// start
- var1.setIntValue(mSource, 540);
+ var1.setValue(mSource, 540);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0f);
Mockito.reset(mTarget);
// 25% complete
- var1.setIntValue(mSource, 405);
+ var1.setValue(mSource, 405);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0.25f);
Mockito.reset(mTarget);
// middle
- var1.setIntValue(mSource, 270);
+ var1.setValue(mSource, 270);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(.5f);
Mockito.reset(mTarget);
// 75% complete
- var1.setIntValue(mSource, 135);
+ var1.setValue(mSource, 135);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0.75f);
Mockito.reset(mTarget);
// end
- var1.setIntValue(mSource, 0);
+ var1.setValue(mSource, 0);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// after end
- var1.setIntValue(mSource, -1000);
+ var1.setValue(mSource, -1000);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// before start
- var1.setIntValue(mSource, 1000);
+ var1.setValue(mSource, 1000);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0f);
Mockito.reset(mTarget);
// unknown_before
- var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+ var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// unknown_after
- var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
+ var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0f);
Mockito.reset(mTarget);
@@ -126,7 +133,7 @@
mEffect.setPropertyRanges(var1.atAbsolute(540), var1.atAbsolute(550));
mEffect.target(mTarget);
- var1.setIntValue(mSource, 0);
+ var1.setValue(mSource, 0);
mEffect.performMapping(mSource);
}
@@ -140,95 +147,137 @@
mEffect.target(mTarget);
// start
- var1.setIntValue(mSource, 540);
- var2.setIntValue(mSource, 840);
+ var1.setValue(mSource, 540);
+ var2.setValue(mSource, 840);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0f);
Mockito.reset(mTarget);
// middle
- var1.setIntValue(mSource, 390);
- var2.setIntValue(mSource, 690);
+ var1.setValue(mSource, 390);
+ var2.setValue(mSource, 690);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(.5f);
Mockito.reset(mTarget);
// end
- var1.setIntValue(mSource, 240);
- var2.setIntValue(mSource, 540);
+ var1.setValue(mSource, 240);
+ var2.setValue(mSource, 540);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// after end
- var1.setIntValue(mSource, 200);
- var2.setIntValue(mSource, 500);
+ var1.setValue(mSource, 200);
+ var2.setValue(mSource, 500);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// before start
- var1.setIntValue(mSource, 1000);
- var2.setIntValue(mSource, 1300);
+ var1.setValue(mSource, 1000);
+ var2.setValue(mSource, 1300);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0f);
Mockito.reset(mTarget);
// unknown_before
- var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
- var2.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+ var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+ var2.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// unknown_before
- var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
- var2.setIntValue(mSource, -1000);
+ var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+ var2.setValue(mSource, -1000);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// unknown_after
- var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
- var2.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
+ var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
+ var2.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0f);
Mockito.reset(mTarget);
// unknown_after
- var1.setIntValue(mSource, 1000);
- var2.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
+ var1.setValue(mSource, 1000);
+ var2.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0f);
Mockito.reset(mTarget);
// unknown_before and less
- var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
- var2.setIntValue(mSource, 500);
+ var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+ var2.setValue(mSource, 500);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// unknown_before and hit second
- var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
- var2.setIntValue(mSource, 540);
+ var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+ var2.setValue(mSource, 540);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(1f);
Mockito.reset(mTarget);
// unknown_before with estimation
- var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
- var2.setIntValue(mSource, 1080);
+ var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+ var2.setValue(mSource, 1080);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0.5f);
Mockito.reset(mTarget);
// unknown_after with estimation
- var1.setIntValue(mSource, 0);
- var2.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
+ var1.setValue(mSource, 0);
+ var2.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
mEffect.performMapping(mSource);
verify(mTarget, times(1)).update(0.5f);
Mockito.reset(mTarget);
}
+ @Test
+ public void testDirectMapping() {
+ mScreenMax = 1080;
+ Parallax.IntProperty var1 = mSource.addProperty("var1");
+
+ mEffect.setPropertyRanges(var1.atAbsolute((int) 540.45), var1.atAbsolute((int) 0.22));
+ Object object = new Object();
+ final int[] properValue = new int[1];
+ Property<Object, Integer> property = new Property<Object, Integer>(Integer.class, "attr") {
+ @Override
+ public void set(Object object, Integer value) {
+ properValue[0] = value;
+ }
+
+ @Override
+ public Integer get(Object o) {
+ return properValue[0];
+ }
+ };
+ mTarget = new ParallaxTarget.DirectPropertyTarget<>(object, property);
+ mEffect.target(mTarget);
+
+ var1.setValue(mSource, (int) 540.45);
+ mEffect.performMapping(mSource);
+ assertEquals((int) 540.45, properValue[0]);
+
+ var1.setValue(mSource, (int) 405.85);
+ mEffect.performMapping(mSource);
+ assertEquals((int) 405.85, properValue[0]);
+
+ var1.setValue(mSource, 2000);
+ mEffect.performMapping(mSource);
+ assertEquals((int) 540.45, properValue[0]);
+
+ var1.setValue(mSource, (int) 0.22);
+ mEffect.performMapping(mSource);
+ assertEquals((int) 0.22, properValue[0]);
+
+ var1.setValue(mSource, (int) 0.12);
+ mEffect.performMapping(mSource);
+ assertEquals((int) 0.22, properValue[0]);
+ }
}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxIntTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxIntTest.java
index e8269ad..a49acbd 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxIntTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxIntTest.java
@@ -29,7 +29,7 @@
@SmallTest
public class ParallaxIntTest {
- Parallax.IntParallax mSource;
+ Parallax<Parallax.IntProperty> mSource;
int mScreenMax;
static void assertFloatEquals(float expected, float actual) {
@@ -38,10 +38,10 @@
@Before
public void setUp() throws Exception {
- mSource = new Parallax.IntParallax<Parallax.IntProperty>() {
+ mSource = new Parallax<Parallax.IntProperty>() {
@Override
- public int getMaxValue() {
+ public float getMaxValue() {
return mScreenMax;
}
@@ -56,8 +56,8 @@
public void testVariable() {
mScreenMax = 1080;
Parallax.IntProperty var1 = mSource.addProperty("var1");
- var1.setIntValue(mSource, 54);
- assertEquals((int) 54, var1.getIntValue(mSource));
+ var1.setValue(mSource, 54);
+ assertEquals((int) 54, var1.getValue(mSource));
assertEquals(var1.getName(), "var1");
var1.set(mSource, (int) 2000);
assertEquals((int) 2000, var1.get(mSource).intValue());
@@ -68,7 +68,8 @@
mScreenMax = 1080;
Parallax.IntProperty var1 = mSource.addProperty("var1");
- Parallax.IntPropertyMarkerValue keyValue = var1.atAbsolute(1000);
+ Parallax.IntPropertyMarkerValue keyValue = (Parallax.IntPropertyMarkerValue)
+ var1.atAbsolute(1000);
assertSame(keyValue.getProperty(), var1);
assertEquals((int) 1000, keyValue.getMarkerValue(mSource));
}
@@ -78,7 +79,8 @@
mScreenMax = 1080;
Parallax.IntProperty var1 = mSource.addProperty("var1");
- Parallax.IntPropertyMarkerValue keyValue = var1.at(0, 0.5f);
+ Parallax.IntPropertyMarkerValue keyValue = (Parallax.IntPropertyMarkerValue)
+ var1.at(0, 0.5f);
assertSame(keyValue.getProperty(), var1);
assertEquals((int) 540, keyValue.getMarkerValue(mSource));
}
@@ -88,11 +90,13 @@
mScreenMax = 1080;
Parallax.IntProperty var1 = mSource.addProperty("var1");
- Parallax.IntPropertyMarkerValue keyValue = var1.at(-100, 0.5f);
+ Parallax.IntPropertyMarkerValue keyValue = (Parallax.IntPropertyMarkerValue)
+ var1.at(-100, 0.5f);
assertSame(keyValue.getProperty(), var1);
assertEquals((int) 440, keyValue.getMarkerValue(mSource));
- Parallax.IntPropertyMarkerValue keyValue2 = var1.at(100, 0.5f);
+ Parallax.IntPropertyMarkerValue keyValue2 = (Parallax.IntPropertyMarkerValue)
+ var1.at(100, 0.5f);
assertSame(keyValue2.getProperty(), var1);
assertEquals((int) 640, keyValue2.getMarkerValue(mSource));
}
@@ -102,10 +106,10 @@
Parallax.IntProperty var1 = mSource.addProperty("var1");
Parallax.IntProperty var2 = mSource.addProperty("var2");
- var1.setIntValue(mSource, (int) 500);
- var2.setIntValue(mSource, (int) 499);
+ var1.setValue(mSource, (int) 500);
+ var2.setValue(mSource, (int) 499);
- mSource.verifyProperties();
+ mSource.verifyIntProperties();
}
@Test(expected = IllegalStateException.class)
@@ -113,10 +117,10 @@
Parallax.IntProperty var1 = mSource.addProperty("var1");
Parallax.IntProperty var2 = mSource.addProperty("var2");
- var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
- var2.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
+ var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+ var2.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
- mSource.verifyProperties();
+ mSource.verifyIntProperties();
}
@Test
@@ -124,19 +128,19 @@
Parallax.IntProperty var1 = mSource.addProperty("var1");
Parallax.IntProperty var2 = mSource.addProperty("var2");
- var1.setIntValue(mSource, (int) 499);
- var2.setIntValue(mSource, (int) 500);
+ var1.setValue(mSource, (int) 499);
+ var2.setValue(mSource, (int) 500);
- mSource.verifyProperties();
+ mSource.verifyIntProperties();
- var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
- var2.setIntValue(mSource, (int) 500);
+ var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+ var2.setValue(mSource, (int) 500);
- mSource.verifyProperties();
+ mSource.verifyIntProperties();
- var1.setIntValue(mSource, (int) 499);
- var2.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
+ var1.setValue(mSource, (int) 499);
+ var2.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
- mSource.verifyProperties();
+ mSource.verifyIntProperties();
}
}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/TitleViewAdapterTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/TitleViewAdapterTest.java
new file mode 100644
index 0000000..d038be7
--- /dev/null
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/TitleViewAdapterTest.java
@@ -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 android.support.v17.leanback.widget;
+
+import android.content.Context;
+import android.graphics.drawable.GradientDrawable;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TitleViewAdapterTest {
+
+
+ public static class CustomTitle extends LinearLayout implements TitleViewAdapter.Provider {
+
+ final View mSearchOrbView;
+
+ public CustomTitle(Context context, AttributeSet set) {
+ this(context, set, 0);
+ }
+
+ public CustomTitle(Context context, AttributeSet set, int s) {
+ super(context, set, s);
+ mSearchOrbView = new View(context);
+ addView(mSearchOrbView, 10, 10);
+ }
+
+ TitleViewAdapter mTitleViewAdapter = new TitleViewAdapter() {
+ @Override
+ public View getSearchAffordanceView() {
+ return mSearchOrbView;
+ }
+ };
+
+ @Override
+ public TitleViewAdapter getTitleViewAdapter() {
+ return mTitleViewAdapter;
+ }
+ }
+
+ @Test
+ public void customTitle() {
+ CustomTitle t = new CustomTitle(InstrumentationRegistry.getTargetContext(), null);
+ TitleViewAdapter adapter = t.getTitleViewAdapter();
+ adapter.setTitle("title");
+ adapter.setBadgeDrawable(new GradientDrawable());
+ View.OnClickListener listener = Mockito.mock(View.OnClickListener.class);
+ adapter.setOnSearchClickedListener(listener);
+ adapter.getSearchAffordanceView().performClick();
+ Mockito.verify(listener).onClick(Mockito.any(View.class));
+ }
+}
diff --git a/v7/appcompat/res/anim/tooltip_enter.xml b/v7/appcompat/res/anim/tooltip_enter.xml
new file mode 100644
index 0000000..134d9d7
--- /dev/null
+++ b/v7/appcompat/res/anim/tooltip_enter.xml
@@ -0,0 +1,21 @@
+<?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.
+ -->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:interpolator/decelerate_quad"
+ android:fromAlpha="0.0" android:toAlpha="1.0"
+ android:duration="@integer/config_tooltipAnimTime" />
diff --git a/v7/appcompat/res/anim/tooltip_exit.xml b/v7/appcompat/res/anim/tooltip_exit.xml
new file mode 100644
index 0000000..67f6af8
--- /dev/null
+++ b/v7/appcompat/res/anim/tooltip_exit.xml
@@ -0,0 +1,21 @@
+<?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.
+ -->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:interpolator/accelerate_quad"
+ android:fromAlpha="1.0" android:toAlpha="0.0"
+ android:duration="@integer/config_tooltipAnimTime" />
diff --git a/v7/appcompat/res/color-v23/abc_tint_switch_thumb.xml b/v7/appcompat/res/color-v23/abc_tint_switch_thumb.xml
deleted file mode 100644
index f589fdf..0000000
--- a/v7/appcompat/res/color-v23/abc_tint_switch_thumb.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="false" android:color="?attr/colorSwitchThumbNormal" android:alpha="?android:attr/disabledAlpha"/>
- <item android:state_checked="true" android:color="?attr/colorControlActivated"/>
- <item android:color="?attr/colorSwitchThumbNormal"/>
-</selector>
\ No newline at end of file
diff --git a/v7/appcompat/res/color/abc_tint_switch_thumb.xml b/v7/appcompat/res/color/abc_tint_switch_thumb.xml
deleted file mode 100644
index fc8bd24..0000000
--- a/v7/appcompat/res/color/abc_tint_switch_thumb.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto">
- <item android:state_enabled="false" android:color="?attr/colorSwitchThumbNormal" app:alpha="?android:attr/disabledAlpha"/>
- <item android:state_checked="true" android:color="?attr/colorControlActivated"/>
- <item android:color="?attr/colorSwitchThumbNormal"/>
-</selector>
\ No newline at end of file
diff --git a/v7/appcompat/res/drawable/tooltip_frame_dark.xml b/v7/appcompat/res/drawable/tooltip_frame_dark.xml
new file mode 100644
index 0000000..43c2f99
--- /dev/null
+++ b/v7/appcompat/res/drawable/tooltip_frame_dark.xml
@@ -0,0 +1,22 @@
+<?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.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="@color/tooltip_background_dark" />
+ <corners android:radius="@dimen/tooltip_corner_radius" />
+</shape>
\ No newline at end of file
diff --git a/v7/appcompat/res/drawable/tooltip_frame_light.xml b/v7/appcompat/res/drawable/tooltip_frame_light.xml
new file mode 100644
index 0000000..20966d5
--- /dev/null
+++ b/v7/appcompat/res/drawable/tooltip_frame_light.xml
@@ -0,0 +1,22 @@
+<?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.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="@color/tooltip_background_light" />
+ <corners android:radius="@dimen/tooltip_corner_radius" />
+</shape>
\ No newline at end of file
diff --git a/v7/appcompat/res/layout/tooltip.xml b/v7/appcompat/res/layout/tooltip.xml
new file mode 100644
index 0000000..1421cd4
--- /dev/null
+++ b/v7/appcompat/res/layout/tooltip.xml
@@ -0,0 +1,42 @@
+<?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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="@dimen/tooltip_margin"
+ android:paddingLeft="@dimen/tooltip_horizontal_padding"
+ android:paddingStart="@dimen/tooltip_horizontal_padding"
+ android:paddingRight="@dimen/tooltip_horizontal_padding"
+ android:paddingEnd="@dimen/tooltip_horizontal_padding"
+ android:paddingTop="@dimen/tooltip_vertical_padding"
+ android:paddingBottom="@dimen/tooltip_vertical_padding"
+ android:maxWidth="256dp"
+ android:background="?attr/tooltipFrameBackground"
+ android:textAppearance="@style/TextAppearance.AppCompat.Tooltip"
+ android:textColor="?attr/tooltipForegroundColor"
+ android:maxLines="3"
+ android:ellipsize="end"
+ />
+
+</LinearLayout>
diff --git a/v7/appcompat/res/values-v16/styles.xml b/v7/appcompat/res/values-v16/styles.xml
new file mode 100644
index 0000000..1b865d4
--- /dev/null
+++ b/v7/appcompat/res/values-v16/styles.xml
@@ -0,0 +1,25 @@
+<?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.
+ -->
+
+<resources>
+
+ <style name="TextAppearance.AppCompat.Tooltip">
+ <item name="android:fontFamily">sans-serif</item>
+ <item name="android:textSize">14sp</item>
+ </style>
+
+</resources>
\ No newline at end of file
diff --git a/v7/appcompat/res/values/attrs.xml b/v7/appcompat/res/values/attrs.xml
index c140a67..dfefd6e 100644
--- a/v7/appcompat/res/values/attrs.xml
+++ b/v7/appcompat/res/values/attrs.xml
@@ -392,6 +392,16 @@
<!-- Default menu-style ListView style. -->
<attr name="listMenuViewStyle" format="reference" />
+
+ <!-- ===================== -->
+ <!-- Tooltip styles -->
+ <!-- ===================== -->
+ <eat-comment />
+
+ <!-- Background to use for tooltips -->
+ <attr name="tooltipFrameBackground" format="reference" />
+ <!-- Foreground color to use for tooltips -->
+ <attr name="tooltipForegroundColor" format="reference|color" />
</declare-styleable>
@@ -634,10 +644,32 @@
with alphabetic keys. -->
<attr name="android:alphabeticShortcut" />
+ <!-- The alphabetic modifier key. This is the modifier when using a keyboard
+ with alphabetic keys. The values should be kept in sync with KeyEvent -->
+ <attr name="alphabeticModifiers">
+ <flag name="META" value="0x10000" />
+ <flag name="CTRL" value="0x1000" />
+ <flag name="ALT" value="0x02" />
+ <flag name="SHIFT" value="0x1" />
+ <flag name="SYM" value="0x4" />
+ <flag name="FUNCTION" value="0x8" />
+ </attr>
+
<!-- The numeric shortcut key. This is the shortcut when using a numeric (e.g., 12-key)
keyboard. -->
<attr name="android:numericShortcut" />
+ <!-- The numeric modifier key. This is the modifier when using a numeric (e.g., 12-key)
+ keyboard. The values should be kept in sync with KeyEvent -->
+ <attr name="numericModifiers">
+ <flag name="META" value="0x10000" />
+ <flag name="CTRL" value="0x1000" />
+ <flag name="ALT" value="0x02" />
+ <flag name="SHIFT" value="0x1" />
+ <flag name="SYM" value="0x4" />
+ <flag name="FUNCTION" value="0x8" />
+ </attr>
+
<!-- Whether the item is capable of displaying a check mark. -->
<attr name="android:checkable" />
diff --git a/v7/appcompat/res/values/colors.xml b/v7/appcompat/res/values/colors.xml
index 92c91fd..e6bab86 100644
--- a/v7/appcompat/res/values/colors.xml
+++ b/v7/appcompat/res/values/colors.xml
@@ -28,4 +28,8 @@
<!-- The color of the material notification background for media notifications when no custom
color is specified -->
<color name="notification_material_background_media_default_color">#ff424242</color>
+
+ <!-- Tooltip specific colors -->
+ <color name="tooltip_background_dark">#e6616161</color>
+ <color name="tooltip_background_light">#e6FFFFFF</color>
</resources>
\ No newline at end of file
diff --git a/v7/appcompat/res/values/config.xml b/v7/appcompat/res/values/config.xml
index 6d986ea..96916a8 100644
--- a/v7/appcompat/res/values/config.xml
+++ b/v7/appcompat/res/values/config.xml
@@ -40,4 +40,7 @@
<integer name="status_bar_notification_info_maxnum">999</integer>
<integer name="cancel_button_image_alpha">127</integer>
+
+ <!-- The duration (in milliseconds) of the tooltip show/hide animations. -->
+ <integer name="config_tooltipAnimTime">150</integer>
</resources>
diff --git a/v7/appcompat/res/values/dimens.xml b/v7/appcompat/res/values/dimens.xml
index e055eed..284bdf1 100644
--- a/v7/appcompat/res/values/dimens.xml
+++ b/v7/appcompat/res/values/dimens.xml
@@ -140,4 +140,23 @@
<!-- the paddingtop on the right side of the notification (for time etc.) -->
<dimen name="notification_right_side_padding_top">2dp</dimen>
+
+ <!-- Tooltip dimensions. -->
+ <!-- Vertical offset from the edge of the anchor view for a touch-triggered tooltip. -->
+ <dimen name="tooltip_y_offset_touch">16dp</dimen>
+ <!-- Vertical offset from the edge of the anchor view for a non-touch-triggered tooltip. -->
+ <dimen name="tooltip_y_offset_non_touch">0dp</dimen>
+ <!-- The tooltip does not get closer than this to the window edge -->
+ <dimen name="tooltip_margin">8dp</dimen>
+ <!-- Left/right padding of the tooltip text. -->
+ <dimen name="tooltip_horizontal_padding">16dp</dimen>
+ <!-- Top/bottom padding of the tooltip text. -->
+ <dimen name="tooltip_vertical_padding">6.5dp</dimen>
+ <!-- Border corner radius of the tooltip window. -->
+ <dimen name="tooltip_corner_radius">2dp</dimen>
+ <!-- View with the height equal or above this threshold will have a tooltip anchored
+ to the mouse/touch position -->
+ <dimen name="tooltip_precise_anchor_threshold">96dp</dimen>
+ <!-- Extra tooltip offset used when anchoring to the mouse/touch position -->
+ <dimen name="tooltip_precise_anchor_extra_offset">8dp</dimen>
</resources>
diff --git a/v7/appcompat/res/values/styles.xml b/v7/appcompat/res/values/styles.xml
index 7595d74..394b1ec 100644
--- a/v7/appcompat/res/values/styles.xml
+++ b/v7/appcompat/res/values/styles.xml
@@ -241,6 +241,7 @@
<eat-comment />
<style name="Animation.AppCompat.Dialog" parent="Base.Animation.AppCompat.Dialog" />
<style name="Animation.AppCompat.DropDownUp" parent="Base.Animation.AppCompat.DropDownUp" />
+ <style name="Animation.AppCompat.Tooltip" parent="Base.Animation.AppCompat.Tooltip" />
<!-- Text styles -->
@@ -302,6 +303,8 @@
<style name="TextAppearance.AppCompat.Widget.Button.Borderless.Colored" parent="Base.TextAppearance.AppCompat.Widget.Button.Borderless.Colored" />
+ <style name="TextAppearance.AppCompat.Tooltip" parent="Base.TextAppearance.AppCompat.Tooltip"/>
+
<!--
The following themes are deprecated.
-->
diff --git a/v7/appcompat/res/values/styles_base.xml b/v7/appcompat/res/values/styles_base.xml
index a760b78..ca250d5 100644
--- a/v7/appcompat/res/values/styles_base.xml
+++ b/v7/appcompat/res/values/styles_base.xml
@@ -522,4 +522,9 @@
<style name="Base.AlertDialog.AppCompat.Light" parent="Base.AlertDialog.AppCompat" />
+ <style name="Base.Animation.AppCompat.Tooltip" parent="android:Animation">
+ <item name="android:windowEnterAnimation">@anim/tooltip_enter</item>
+ <item name="android:windowExitAnimation">@anim/tooltip_exit</item>
+ </style>
+
</resources>
diff --git a/v7/appcompat/res/values/styles_base_text.xml b/v7/appcompat/res/values/styles_base_text.xml
index 6a43144..11de1e6 100644
--- a/v7/appcompat/res/values/styles_base_text.xml
+++ b/v7/appcompat/res/values/styles_base_text.xml
@@ -102,6 +102,10 @@
<item name="android:textColor">?android:textColorPrimaryInverse</item>
</style>
+ <style name="Base.TextAppearance.AppCompat.Tooltip">
+ <item name="android:textSize">14sp</item>
+ </style>
+
<!-- Deprecated text styles -->
<style name="Base.TextAppearance.AppCompat.Inverse">
diff --git a/v7/appcompat/res/values/themes_base.xml b/v7/appcompat/res/values/themes_base.xml
index 92e7bce..2844d2b 100644
--- a/v7/appcompat/res/values/themes_base.xml
+++ b/v7/appcompat/res/values/themes_base.xml
@@ -276,6 +276,10 @@
<item name="windowFixedWidthMinor">@null</item>
<item name="windowFixedHeightMajor">@null</item>
<item name="windowFixedHeightMinor">@null</item>
+
+ <!-- Tooltip attributes -->
+ <item name="tooltipFrameBackground">@drawable/tooltip_frame_light</item>
+ <item name="tooltipForegroundColor">@color/foreground_material_light</item>
</style>
<!-- Base platform-dependent theme providing an action bar in a light-themed activity. -->
@@ -437,6 +441,10 @@
<item name="windowFixedWidthMinor">@null</item>
<item name="windowFixedHeightMajor">@null</item>
<item name="windowFixedHeightMinor">@null</item>
+
+ <!-- Tooltip attributes -->
+ <item name="tooltipFrameBackground">@drawable/tooltip_frame_dark</item>
+ <item name="tooltipForegroundColor">@color/foreground_material_dark</item>
</style>
<style name="Base.Theme.AppCompat" parent="Base.V7.Theme.AppCompat">
diff --git a/v7/appcompat/src/android/support/v7/app/AlertController.java b/v7/appcompat/src/android/support/v7/app/AlertController.java
index ee7ea8e..d0f8fd6 100644
--- a/v7/appcompat/src/android/support/v7/app/AlertController.java
+++ b/v7/appcompat/src/android/support/v7/app/AlertController.java
@@ -16,6 +16,8 @@
package android.support.v7.app;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
@@ -28,6 +30,7 @@
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.NestedScrollView;
import android.support.v7.appcompat.R;
+import android.support.v7.widget.LinearLayoutCompat;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;
@@ -58,8 +61,6 @@
import java.lang.ref.WeakReference;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-
class AlertController {
private final Context mContext;
final AppCompatDialog mDialog;
@@ -652,7 +653,7 @@
}
if (mListView != null) {
- ((LinearLayout.LayoutParams) customPanel.getLayoutParams()).weight = 0;
+ ((LinearLayoutCompat.LayoutParams) customPanel.getLayoutParams()).weight = 0;
}
} else {
customPanel.setVisibility(View.GONE);
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatActivity.java b/v7/appcompat/src/android/support/v7/app/AppCompatActivity.java
index e4d951c..6c0f125 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatActivity.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatActivity.java
@@ -40,6 +40,7 @@
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.Window;
/**
* Base class for activities that use the
@@ -547,4 +548,32 @@
}
return mResources == null ? super.getResources() : mResources;
}
+
+ /**
+ * KeyEvents with non-default modifiers are not dispatched to menu's performShortcut in API 24
+ * or lower. Here, we check if the keypress corresponds to a menuitem's shortcut combination
+ * and perform the corresponding action.
+ */
+ private boolean performMenuItemShortcut(int keycode, KeyEvent event) {
+ if (!KeyEvent.metaStateHasNoModifiers(event.getMetaState())
+ && event.getRepeatCount() == 0
+ && !KeyEvent.isModifierKey(event.getKeyCode())) {
+ final Window currentWindow = getWindow();
+ if (currentWindow != null && currentWindow.getDecorView() != null) {
+ final View decorView = currentWindow.getDecorView();
+ if (decorView.dispatchKeyShortcutEvent(event)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (performMenuItemShortcut(keyCode, event)) {
+ return true;
+ }
+ return super.onKeyDown(keyCode, event);
+ }
}
diff --git a/v7/appcompat/src/android/support/v7/app/WindowDecorActionBar.java b/v7/appcompat/src/android/support/v7/app/WindowDecorActionBar.java
index 39ff508..c412d59 100644
--- a/v7/appcompat/src/android/support/v7/app/WindowDecorActionBar.java
+++ b/v7/appcompat/src/android/support/v7/app/WindowDecorActionBar.java
@@ -51,6 +51,8 @@
import android.support.v7.widget.Toolbar;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -1401,4 +1403,19 @@
setDisplayHomeAsUpEnabled(enable);
}
}
+
+ @Override
+ public boolean onKeyShortcut(int keyCode, KeyEvent event) {
+ if (mActionMode == null) {
+ return false;
+ }
+ Menu menu = mActionMode.getMenu();
+ if (menu != null) {
+ final KeyCharacterMap kmap = KeyCharacterMap.load(
+ event != null ? event.getDeviceId() : KeyCharacterMap.VIRTUAL_KEYBOARD);
+ menu.setQwertyMode(kmap.getKeyboardType() != KeyCharacterMap.NUMERIC);
+ return menu.performShortcut(keyCode, event, 0);
+ }
+ return false;
+ }
}
diff --git a/v7/appcompat/src/android/support/v7/view/SupportActionModeWrapper.java b/v7/appcompat/src/android/support/v7/view/SupportActionModeWrapper.java
index 3ab5f81..fa7fe1b 100644
--- a/v7/appcompat/src/android/support/v7/view/SupportActionModeWrapper.java
+++ b/v7/appcompat/src/android/support/v7/view/SupportActionModeWrapper.java
@@ -19,7 +19,6 @@
import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
import android.content.Context;
-import android.os.Build;
import android.support.annotation.RestrictTo;
import android.support.v4.internal.view.SupportMenu;
import android.support.v4.internal.view.SupportMenuItem;
diff --git a/v7/appcompat/src/android/support/v7/view/SupportMenuInflater.java b/v7/appcompat/src/android/support/v7/view/SupportMenuInflater.java
index 60f0f9e..003c986 100644
--- a/v7/appcompat/src/android/support/v7/view/SupportMenuInflater.java
+++ b/v7/appcompat/src/android/support/v7/view/SupportMenuInflater.java
@@ -34,6 +34,7 @@
import android.util.Log;
import android.util.Xml;
import android.view.InflateException;
+import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -293,7 +294,9 @@
private CharSequence itemTitleCondensed;
private int itemIconResId;
private char itemAlphabeticShortcut;
+ private int itemAlphabeticModifiers;
private char itemNumericShortcut;
+ private int itemNumericModifiers;
/**
* Sync to attrs.xml enum:
* - 0: none
@@ -384,8 +387,12 @@
itemIconResId = a.getResourceId(R.styleable.MenuItem_android_icon, 0);
itemAlphabeticShortcut =
getShortcut(a.getString(R.styleable.MenuItem_android_alphabeticShortcut));
+ itemAlphabeticModifiers =
+ a.getInt(R.styleable.MenuItem_alphabeticModifiers, KeyEvent.META_CTRL_ON);
itemNumericShortcut =
getShortcut(a.getString(R.styleable.MenuItem_android_numericShortcut));
+ itemNumericModifiers =
+ a.getInt(R.styleable.MenuItem_numericModifiers, KeyEvent.META_CTRL_ON);
if (a.hasValue(R.styleable.MenuItem_android_checkable)) {
// Item has attribute checkable, use it
itemCheckable = a.getBoolean(R.styleable.MenuItem_android_checkable, false) ? 1 : 0;
@@ -438,9 +445,7 @@
.setEnabled(itemEnabled)
.setCheckable(itemCheckable >= 1)
.setTitleCondensed(itemTitleCondensed)
- .setIcon(itemIconResId)
- .setAlphabeticShortcut(itemAlphabeticShortcut)
- .setNumericShortcut(itemNumericShortcut);
+ .setIcon(itemIconResId);
if (itemShowAsAction >= 0) {
item.setShowAsAction(itemShowAsAction);
@@ -486,6 +491,9 @@
MenuItemCompat.setContentDescription(item, itemContentDescription);
MenuItemCompat.setTooltipText(item, itemTooltipText);
+ MenuItemCompat.setAlphabeticShortcut(item, itemAlphabeticShortcut,
+ itemAlphabeticModifiers);
+ MenuItemCompat.setNumericShortcut(item, itemNumericShortcut, itemNumericModifiers);
}
public void addItem() {
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItem.java b/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItem.java
index b3278a4..d190df3 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItem.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItem.java
@@ -26,6 +26,7 @@
import android.support.v4.internal.view.SupportMenuItem;
import android.support.v4.view.ActionProvider;
import android.view.ContextMenu.ContextMenuInfo;
+import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
@@ -45,7 +46,9 @@
private CharSequence mTitleCondensed;
private Intent mIntent;
private char mShortcutNumericChar;
+ private int mShortcutNumericModifiers = KeyEvent.META_CTRL_ON;
private char mShortcutAlphabeticChar;
+ private int mShortcutAlphabeticModifiers = KeyEvent.META_CTRL_ON;
private Drawable mIconDrawable;
private int mIconResId = NO_ICON;
@@ -82,6 +85,11 @@
}
@Override
+ public int getAlphabeticModifiers() {
+ return mShortcutAlphabeticModifiers;
+ }
+
+ @Override
public int getGroupId() {
return mGroup;
}
@@ -112,6 +120,11 @@
}
@Override
+ public int getNumericModifiers() {
+ return mShortcutNumericModifiers;
+ }
+
+ @Override
public int getOrder() {
return mOrdering;
}
@@ -158,7 +171,14 @@
@Override
public MenuItem setAlphabeticShortcut(char alphaChar) {
- mShortcutAlphabeticChar = alphaChar;
+ mShortcutAlphabeticChar = Character.toLowerCase(alphaChar);
+ return this;
+ }
+
+ @Override
+ public MenuItem setAlphabeticShortcut(char alphaChar, int alphaModifiers) {
+ mShortcutAlphabeticChar = Character.toLowerCase(alphaChar);
+ mShortcutAlphabeticModifiers = KeyEvent.normalizeMetaState(alphaModifiers);
return this;
}
@@ -212,6 +232,13 @@
}
@Override
+ public MenuItem setNumericShortcut(char numericChar, int numericModifiers) {
+ mShortcutNumericChar = numericChar;
+ mShortcutNumericModifiers = KeyEvent.normalizeMetaState(numericModifiers);
+ return this;
+ }
+
+ @Override
public MenuItem setOnMenuItemClickListener(OnMenuItemClickListener menuItemClickListener) {
mClickListener = menuItemClickListener;
return this;
@@ -220,7 +247,17 @@
@Override
public MenuItem setShortcut(char numericChar, char alphaChar) {
mShortcutNumericChar = numericChar;
- mShortcutAlphabeticChar = alphaChar;
+ mShortcutAlphabeticChar = Character.toLowerCase(alphaChar);
+ return this;
+ }
+
+ @Override
+ public MenuItem setShortcut(char numericChar, char alphaChar, int numericModifiers,
+ int alphaModifiers) {
+ mShortcutNumericChar = numericChar;
+ mShortcutNumericModifiers = KeyEvent.normalizeMetaState(numericModifiers);
+ mShortcutAlphabeticChar = Character.toLowerCase(alphaChar);
+ mShortcutAlphabeticModifiers = KeyEvent.normalizeMetaState(alphaModifiers);
return this;
}
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItemView.java b/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItemView.java
index 989e609..259ae07 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItemView.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItemView.java
@@ -25,11 +25,11 @@
import android.graphics.drawable.Drawable;
import android.os.Parcelable;
import android.support.annotation.RestrictTo;
-import android.support.v4.view.ViewCompat;
import android.support.v7.appcompat.R;
import android.support.v7.widget.ActionMenuView;
import android.support.v7.widget.AppCompatTextView;
import android.support.v7.widget.ForwardingListener;
+import android.support.v7.widget.TooltipCompat;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -202,9 +202,9 @@
final CharSequence tooltipText = mItemData.getTooltipText();
if (TextUtils.isEmpty(tooltipText)) {
// Use the uncondensed title for tooltip, but only if the title is not shown already.
- ViewCompat.setTooltipText(this, visible ? null : mItemData.getTitle());
+ TooltipCompat.setTooltipText(this, visible ? null : mItemData.getTitle());
} else {
- ViewCompat.setTooltipText(this, tooltipText);
+ TooltipCompat.setTooltipText(this, tooltipText);
}
}
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuBuilder.java b/v7/appcompat/src/android/support/v7/view/menu/MenuBuilder.java
index 3adfd87..e6dee8d 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuBuilder.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuBuilder.java
@@ -868,7 +868,7 @@
@SuppressWarnings("deprecation")
void findItemsWithShortcutForKey(List<MenuItemImpl> items, int keyCode, KeyEvent event) {
final boolean qwerty = isQwertyMode();
- final int metaState = event.getMetaState();
+ final int modifierState = event.getModifiers();
final KeyCharacterMap.KeyData possibleChars = new KeyCharacterMap.KeyData();
// Get the chars associated with the keyCode (i.e using any chording combo)
final boolean isKeyCodeMapped = event.getKeyData(possibleChars);
@@ -884,14 +884,18 @@
if (item.hasSubMenu()) {
((MenuBuilder)item.getSubMenu()).findItemsWithShortcutForKey(items, keyCode, event);
}
- final char shortcutChar = qwerty ? item.getAlphabeticShortcut() : item.getNumericShortcut();
- if (((metaState & (KeyEvent.META_SHIFT_ON | KeyEvent.META_SYM_ON)) == 0) &&
- (shortcutChar != 0) &&
- (shortcutChar == possibleChars.meta[0]
- || shortcutChar == possibleChars.meta[2]
- || (qwerty && shortcutChar == '\b' &&
- keyCode == KeyEvent.KEYCODE_DEL)) &&
- item.isEnabled()) {
+ final char shortcutChar =
+ qwerty ? item.getAlphabeticShortcut() : item.getNumericShortcut();
+ final int shortcutModifiers =
+ qwerty ? item.getAlphabeticModifiers() : item.getNumericModifiers();
+ final boolean isModifiersExactMatch = (modifierState & SUPPORTED_MODIFIERS_MASK)
+ == (shortcutModifiers & SUPPORTED_MODIFIERS_MASK);
+ if (isModifiersExactMatch && (shortcutChar != 0)
+ && (shortcutChar == possibleChars.meta[0]
+ || shortcutChar == possibleChars.meta[2]
+ || (qwerty && shortcutChar == '\b'
+ && keyCode == KeyEvent.KEYCODE_DEL))
+ && item.isEnabled()) {
items.add(item);
}
}
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuItemImpl.java b/v7/appcompat/src/android/support/v7/view/menu/MenuItemImpl.java
index 510034a..a476d05 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuItemImpl.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuItemImpl.java
@@ -29,6 +29,7 @@
import android.support.v7.content.res.AppCompatResources;
import android.util.Log;
import android.view.ContextMenu.ContextMenuInfo;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.SubMenu;
@@ -56,7 +57,9 @@
private CharSequence mTitleCondensed;
private Intent mIntent;
private char mShortcutNumericChar;
+ private int mShortcutNumericModifiers = KeyEvent.META_CTRL_ON;
private char mShortcutAlphabeticChar;
+ private int mShortcutAlphabeticModifiers = KeyEvent.META_CTRL_ON;
/** The icon's drawable which is only created as needed */
private Drawable mIconDrawable;
@@ -257,11 +260,35 @@
}
@Override
+ public MenuItem setAlphabeticShortcut(char alphaChar, int alphaModifiers) {
+ if (mShortcutAlphabeticChar == alphaChar
+ && mShortcutAlphabeticModifiers == alphaModifiers) {
+ return this;
+ }
+
+ mShortcutAlphabeticChar = Character.toLowerCase(alphaChar);
+ mShortcutAlphabeticModifiers = KeyEvent.normalizeMetaState(alphaModifiers);
+
+ mMenu.onItemsChanged(false);
+ return this;
+ }
+
+ @Override
+ public int getAlphabeticModifiers() {
+ return mShortcutAlphabeticModifiers;
+ }
+
+ @Override
public char getNumericShortcut() {
return mShortcutNumericChar;
}
@Override
+ public int getNumericModifiers() {
+ return mShortcutNumericModifiers;
+ }
+
+ @Override
public MenuItem setNumericShortcut(char numericChar) {
if (mShortcutNumericChar == numericChar) {
return this;
@@ -275,6 +302,20 @@
}
@Override
+ public MenuItem setNumericShortcut(char numericChar, int numericModifiers) {
+ if (mShortcutNumericChar == numericChar && mShortcutNumericModifiers == numericModifiers) {
+ return this;
+ }
+
+ mShortcutNumericChar = numericChar;
+ mShortcutNumericModifiers = KeyEvent.normalizeMetaState(numericModifiers);
+
+ mMenu.onItemsChanged(false);
+
+ return this;
+ }
+
+ @Override
public MenuItem setShortcut(char numericChar, char alphaChar) {
mShortcutNumericChar = numericChar;
mShortcutAlphabeticChar = Character.toLowerCase(alphaChar);
@@ -284,6 +325,19 @@
return this;
}
+ @Override
+ public MenuItem setShortcut(char numericChar, char alphaChar, int numericModifiers,
+ int alphaModifiers) {
+ mShortcutNumericChar = numericChar;
+ mShortcutNumericModifiers = KeyEvent.normalizeMetaState(numericModifiers);
+ mShortcutAlphabeticChar = Character.toLowerCase(alphaChar);
+ mShortcutAlphabeticModifiers = KeyEvent.normalizeMetaState(alphaModifiers);
+
+ mMenu.onItemsChanged(false);
+
+ return this;
+ }
+
/**
* @return The active shortcut (based on QWERTY-mode of the menu).
*/
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperICS.java b/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperICS.java
index 386c43a..7f1266e 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperICS.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperICS.java
@@ -129,28 +129,57 @@
}
@Override
+ public MenuItem setShortcut(char numericChar, char alphaChar, int numericModifiers,
+ int alphaModifiers) {
+ mWrappedObject.setShortcut(numericChar, alphaChar, numericModifiers, alphaModifiers);
+ return this;
+ }
+
+ @Override
public MenuItem setNumericShortcut(char numericChar) {
mWrappedObject.setNumericShortcut(numericChar);
return this;
}
@Override
+ public MenuItem setNumericShortcut(char numericChar, int numericModifiers) {
+ mWrappedObject.setNumericShortcut(numericChar, numericModifiers);
+ return this;
+ }
+
+ @Override
public char getNumericShortcut() {
return mWrappedObject.getNumericShortcut();
}
@Override
+ public int getNumericModifiers() {
+ return mWrappedObject.getNumericModifiers();
+ }
+
+ @Override
public MenuItem setAlphabeticShortcut(char alphaChar) {
mWrappedObject.setAlphabeticShortcut(alphaChar);
return this;
}
@Override
+ public MenuItem setAlphabeticShortcut(char alphaChar, int alphaModifiers) {
+ mWrappedObject.setAlphabeticShortcut(alphaChar, alphaModifiers);
+ return this;
+ }
+
+ @Override
public char getAlphabeticShortcut() {
return mWrappedObject.getAlphabeticShortcut();
}
@Override
+ public int getAlphabeticModifiers() {
+ return mWrappedObject.getAlphabeticModifiers();
+ }
+
+ @Override
public MenuItem setCheckable(boolean checkable) {
mWrappedObject.setCheckable(checkable);
return this;
diff --git a/v7/appcompat/src/android/support/v7/view/menu/StandardMenuPopup.java b/v7/appcompat/src/android/support/v7/view/menu/StandardMenuPopup.java
index 2ab1a0c..bcb589b 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/StandardMenuPopup.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/StandardMenuPopup.java
@@ -25,7 +25,6 @@
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.View.OnAttachStateChangeListener;
import android.view.View.OnKeyListener;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java b/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java
index 888d33b..030c3db 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java
@@ -27,7 +27,6 @@
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v4.view.ActionProvider;
import android.support.v4.view.GravityCompat;
-import android.support.v4.view.ViewCompat;
import android.support.v7.appcompat.R;
import android.support.v7.transition.ActionBarTransition;
import android.support.v7.view.ActionBarPolicy;
@@ -652,7 +651,7 @@
setVisibility(VISIBLE);
setEnabled(true);
- ViewCompat.setTooltipText(this, getContentDescription());
+ TooltipCompat.setTooltipText(this, getContentDescription());
setOnTouchListener(new ForwardingListener(this) {
@Override
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java b/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java
index 70e241d..34e2f4e 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java
@@ -532,7 +532,7 @@
} else if (resId == R.drawable.abc_switch_track_mtrl_alpha) {
tint = getColorStateList(context, R.color.abc_tint_switch_track);
} else if (resId == R.drawable.abc_switch_thumb_material) {
- tint = getColorStateList(context, R.color.abc_tint_switch_thumb);
+ tint = createSwitchThumbColorStateList(context);
} else if (resId == R.drawable.abc_btn_default_mtrl_shape) {
tint = createDefaultButtonColorStateList(context);
} else if (resId == R.drawable.abc_btn_borderless_material) {
@@ -625,6 +625,52 @@
return new ColorStateList(states, colors);
}
+ private ColorStateList createSwitchThumbColorStateList(Context context) {
+ final int[][] states = new int[3][];
+ final int[] colors = new int[3];
+ int i = 0;
+
+ final ColorStateList thumbColor = getThemeAttrColorStateList(context,
+ R.attr.colorSwitchThumbNormal);
+
+ if (thumbColor != null && thumbColor.isStateful()) {
+ // If colorSwitchThumbNormal is a valid ColorStateList, extract the default and
+ // disabled colors from it
+
+ // Disabled state
+ states[i] = ThemeUtils.DISABLED_STATE_SET;
+ colors[i] = thumbColor.getColorForState(states[i], 0);
+ i++;
+
+ states[i] = ThemeUtils.CHECKED_STATE_SET;
+ colors[i] = getThemeAttrColor(context, R.attr.colorControlActivated);
+ i++;
+
+ // Default enabled state
+ states[i] = ThemeUtils.EMPTY_STATE_SET;
+ colors[i] = thumbColor.getDefaultColor();
+ i++;
+ } else {
+ // Else we'll use an approximation using the default disabled alpha
+
+ // Disabled state
+ states[i] = ThemeUtils.DISABLED_STATE_SET;
+ colors[i] = getDisabledThemeAttrColor(context, R.attr.colorSwitchThumbNormal);
+ i++;
+
+ states[i] = ThemeUtils.CHECKED_STATE_SET;
+ colors[i] = getThemeAttrColor(context, R.attr.colorControlActivated);
+ i++;
+
+ // Default enabled state
+ states[i] = ThemeUtils.EMPTY_STATE_SET;
+ colors[i] = getThemeAttrColor(context, R.attr.colorSwitchThumbNormal);
+ i++;
+ }
+
+ return new ColorStateList(states, colors);
+ }
+
private static class ColorFilterLruCache extends LruCache<Integer, PorterDuffColorFilter> {
public ColorFilterLruCache(int maxSize) {
diff --git a/v7/appcompat/src/android/support/v7/widget/ScrollingTabContainerView.java b/v7/appcompat/src/android/support/v7/widget/ScrollingTabContainerView.java
index a8b4257..7512631 100644
--- a/v7/appcompat/src/android/support/v7/widget/ScrollingTabContainerView.java
+++ b/v7/appcompat/src/android/support/v7/widget/ScrollingTabContainerView.java
@@ -25,7 +25,6 @@
import android.os.Build;
import android.support.annotation.RestrictTo;
import android.support.v4.view.GravityCompat;
-import android.support.v4.view.ViewCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.appcompat.R;
import android.support.v7.view.ActionBarPolicy;
@@ -511,7 +510,7 @@
if (mIconView != null) {
mIconView.setContentDescription(tab.getContentDescription());
}
- ViewCompat.setTooltipText(this, hasText ? null : tab.getContentDescription());
+ TooltipCompat.setTooltipText(this, hasText ? null : tab.getContentDescription());
}
}
diff --git a/v7/appcompat/src/android/support/v7/widget/SearchView.java b/v7/appcompat/src/android/support/v7/widget/SearchView.java
index 2dac3d9..0af462f 100644
--- a/v7/appcompat/src/android/support/v7/widget/SearchView.java
+++ b/v7/appcompat/src/android/support/v7/widget/SearchView.java
@@ -323,7 +323,7 @@
mSearchHintIcon = a.getDrawable(R.styleable.SearchView_searchHintIcon);
- ViewCompat.setTooltipText(mSearchButton,
+ TooltipCompat.setTooltipText(mSearchButton,
getResources().getString(R.string.abc_searchview_description_search));
// Extract dropdown layout resource IDs for later use.
diff --git a/v7/appcompat/src/android/support/v7/widget/TooltipCompat.java b/v7/appcompat/src/android/support/v7/widget/TooltipCompat.java
new file mode 100644
index 0000000..f7466bc
--- /dev/null
+++ b/v7/appcompat/src/android/support/v7/widget/TooltipCompat.java
@@ -0,0 +1,73 @@
+/*
+ * 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.v7.widget;
+
+import android.annotation.TargetApi;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.os.BuildCompat;
+import android.view.View;
+
+/**
+ * Helper class used to emulate the behavior of {@link View#setTooltipText(CharSequence)} prior
+ * to API level 26.
+ *
+ */
+public class TooltipCompat {
+ private interface ViewCompatImpl {
+ void setTooltipText(@NonNull View view, @Nullable CharSequence tooltipText);
+ }
+
+ private static class BaseViewCompatImpl implements ViewCompatImpl {
+ @Override
+ public void setTooltipText(@NonNull View view, @Nullable CharSequence tooltipText) {
+ TooltipCompatHandler.setTooltipText(view, tooltipText);
+ }
+ }
+
+ @TargetApi(26)
+ private static class Api26ViewCompatImpl implements ViewCompatImpl {
+ @Override
+ public void setTooltipText(@NonNull View view, @Nullable CharSequence tooltipText) {
+ view.setTooltipText(tooltipText);
+ }
+ }
+
+ private static final ViewCompatImpl IMPL;
+ static {
+ if (BuildCompat.isAtLeastO()) {
+ IMPL = new Api26ViewCompatImpl();
+ } else {
+ IMPL = new BaseViewCompatImpl();
+ }
+ }
+
+ /**
+ * Sets the tooltip text for the view.
+ * <p> Prior to API 26 this method sets or clears (when tooltip is null) the view's
+ * OnLongClickListener and OnHoverListener. A toast-like subpanel will be created on long click
+ * or mouse hover.
+ *
+ * @param view the view to set the tooltip text on
+ * @param tooltipText the tooltip text
+ */
+ public static void setTooltipText(@NonNull View view, @Nullable CharSequence tooltipText) {
+ IMPL.setTooltipText(view, tooltipText);
+ }
+
+ private TooltipCompat() {}
+}
diff --git a/v7/appcompat/src/android/support/v7/widget/TooltipCompatHandler.java b/v7/appcompat/src/android/support/v7/widget/TooltipCompatHandler.java
new file mode 100644
index 0000000..4670534
--- /dev/null
+++ b/v7/appcompat/src/android/support/v7/widget/TooltipCompatHandler.java
@@ -0,0 +1,196 @@
+/*
+ * 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.v7.widget;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+import static android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE;
+
+import android.content.Context;
+import android.support.annotation.RestrictTo;
+import android.support.v4.view.ViewCompat;
+import android.support.v4.view.accessibility.AccessibilityManagerCompat;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.accessibility.AccessibilityManager;
+
+/**
+ * Event handler used used to emulate the behavior of {@link View#setTooltipText(CharSequence)}
+ * prior to API level 26.
+ *
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+class TooltipCompatHandler implements View.OnLongClickListener, View.OnHoverListener,
+ View.OnAttachStateChangeListener {
+ private static final String TAG = "TooltipCompatHandler";
+
+ private static final long LONG_CLICK_HIDE_TIMEOUT_MS = 2500;
+ private static final long HOVER_HIDE_TIMEOUT_MS = 15000;
+ private static final long HOVER_HIDE_TIMEOUT_SHORT_MS = 3000;
+
+ private final View mAnchor;
+ private final CharSequence mTooltipText;
+
+ private final Runnable mShowRunnable = new Runnable() {
+ @Override
+ public void run() {
+ show(false /* not from touch*/);
+ }
+ };
+ private final Runnable mHideRunnable = new Runnable() {
+ @Override
+ public void run() {
+ hide();
+ }
+ };
+
+ private int mAnchorX;
+ private int mAnchorY;
+
+ private TooltipPopup mPopup;
+ private boolean mFromTouch;
+
+ // The handler currently showing a tooltip (there can be only one).
+ private static TooltipCompatHandler sActiveHandler;
+
+ /**
+ * Set the tooltip text for the view.
+ *
+ * @param view view to set the tooltip on
+ * @param tooltipText the tooltip text
+ */
+ public static void setTooltipText(View view, CharSequence tooltipText) {
+ if (TextUtils.isEmpty(tooltipText)) {
+ if (sActiveHandler != null && sActiveHandler.mAnchor == view) {
+ sActiveHandler.hide();
+ }
+ view.setOnLongClickListener(null);
+ view.setLongClickable(false);
+ view.setOnHoverListener(null);
+ } else {
+ if (sActiveHandler != null && sActiveHandler.mAnchor == view) {
+ sActiveHandler.update(tooltipText);
+ } else {
+ new TooltipCompatHandler(view, tooltipText);
+ }
+ }
+ }
+
+ private TooltipCompatHandler(View anchor, CharSequence tooltipText) {
+ mAnchor = anchor;
+ mTooltipText = tooltipText;
+
+ mAnchor.setOnLongClickListener(this);
+ mAnchor.setOnHoverListener(this);
+ }
+
+ @Override
+ public boolean onLongClick(View v) {
+ mAnchorX = v.getWidth() / 2;
+ mAnchorY = v.getHeight() / 2;
+ show(true /* from touch */);
+ return true;
+ }
+
+ @Override
+ public boolean onHover(View v, MotionEvent event) {
+ if (mPopup != null && mFromTouch) {
+ return false;
+ }
+ AccessibilityManager manager = (AccessibilityManager)
+ mAnchor.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
+ if (manager.isEnabled()
+ && AccessibilityManagerCompat.isTouchExplorationEnabled(manager)) {
+ return false;
+ }
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_HOVER_MOVE:
+ if (mAnchor.isEnabled() && mPopup == null) {
+ mAnchorX = (int) event.getX();
+ mAnchorY = (int) event.getY();
+ mAnchor.removeCallbacks(mShowRunnable);
+ mAnchor.postDelayed(mShowRunnable, ViewConfiguration.getLongPressTimeout());
+ }
+ break;
+ case MotionEvent.ACTION_HOVER_EXIT:
+ hide();
+ break;
+ }
+
+ return false;
+ }
+
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ // no-op.
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ hide();
+ }
+
+ private void show(boolean fromTouch) {
+ if (!ViewCompat.isAttachedToWindow(mAnchor)) {
+ return;
+ }
+ if (sActiveHandler != null) {
+ sActiveHandler.hide();
+ }
+ sActiveHandler = this;
+
+ mFromTouch = fromTouch;
+ mPopup = new TooltipPopup(mAnchor.getContext());
+ mPopup.show(mAnchor, mAnchorX, mAnchorY, mFromTouch, mTooltipText);
+ // Only listen for attach state change while the popup is being shown.
+ mAnchor.addOnAttachStateChangeListener(this);
+
+ final long timeout;
+ if (mFromTouch) {
+ timeout = LONG_CLICK_HIDE_TIMEOUT_MS;
+ } else if ((ViewCompat.getWindowSystemUiVisibility(mAnchor)
+ & SYSTEM_UI_FLAG_LOW_PROFILE) == SYSTEM_UI_FLAG_LOW_PROFILE) {
+ timeout = HOVER_HIDE_TIMEOUT_SHORT_MS - ViewConfiguration.getLongPressTimeout();
+ } else {
+ timeout = HOVER_HIDE_TIMEOUT_MS - ViewConfiguration.getLongPressTimeout();
+ }
+ mAnchor.removeCallbacks(mHideRunnable);
+ mAnchor.postDelayed(mHideRunnable, timeout);
+ }
+
+ private void hide() {
+ if (sActiveHandler == this) {
+ sActiveHandler = null;
+ if (mPopup != null) {
+ mPopup.hide();
+ mPopup = null;
+ mAnchor.removeOnAttachStateChangeListener(this);
+ } else {
+ Log.e(TAG, "sActiveHandler.mPopup == null");
+ }
+ }
+ mAnchor.removeCallbacks(mShowRunnable);
+ mAnchor.removeCallbacks(mHideRunnable);
+ }
+
+ private void update(CharSequence tooltipText) {
+ mPopup.updateContent(tooltipText);
+ }
+}
diff --git a/v7/appcompat/src/android/support/v7/widget/TooltipPopup.java b/v7/appcompat/src/android/support/v7/widget/TooltipPopup.java
new file mode 100644
index 0000000..26bd9df
--- /dev/null
+++ b/v7/appcompat/src/android/support/v7/widget/TooltipPopup.java
@@ -0,0 +1,198 @@
+/*
+ * 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.v7.widget;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.support.annotation.RestrictTo;
+import android.support.v7.appcompat.R;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+/**
+ * A popup window displaying a text message aligned to a specified view.
+ *
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+class TooltipPopup {
+ private static final String TAG = "TooltipPopup";
+
+ private final Context mContext;
+
+ private final View mContentView;
+ private final TextView mMessageView;
+
+ private final WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams();
+ private final Rect mTmpDisplayFrame = new Rect();
+ private final int[] mTmpAnchorPos = new int[2];
+ private final int[] mTmpAppPos = new int[2];
+
+ TooltipPopup(Context context) {
+ mContext = context;
+
+ mContentView = LayoutInflater.from(mContext).inflate(R.layout.tooltip, null);
+ mMessageView = (TextView) mContentView.findViewById(R.id.message);
+
+ mLayoutParams.setTitle(getClass().getSimpleName());
+ mLayoutParams.packageName = mContext.getPackageName();
+ mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
+ mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
+ mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
+ mLayoutParams.format = PixelFormat.TRANSLUCENT;
+ mLayoutParams.windowAnimations = R.style.Animation_AppCompat_Tooltip;
+ mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+ }
+
+ void show(View anchorView, int anchorX, int anchorY, boolean fromTouch,
+ CharSequence tooltipText) {
+ if (isShowing()) {
+ hide();
+ }
+
+ mMessageView.setText(tooltipText);
+
+ computePosition(anchorView, anchorX, anchorY, fromTouch, mLayoutParams);
+
+ WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+ wm.addView(mContentView, mLayoutParams);
+ }
+
+ void hide() {
+ if (!isShowing()) {
+ return;
+ }
+
+ WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+ wm.removeView(mContentView);
+ }
+
+ boolean isShowing() {
+ return mContentView.getParent() != null;
+ }
+
+ void updateContent(CharSequence tooltipText) {
+ mMessageView.setText(tooltipText);
+ }
+
+ private void computePosition(View anchorView, int anchorX, int anchorY, boolean fromTouch,
+ WindowManager.LayoutParams outParams) {
+ final int tooltipPreciseAnchorThreshold = mContext.getResources().getDimensionPixelOffset(
+ R.dimen.tooltip_precise_anchor_threshold);
+
+ final int offsetX;
+ if (anchorView.getWidth() >= tooltipPreciseAnchorThreshold) {
+ // Wide view. Align the tooltip horizontally to the precise X position.
+ offsetX = anchorX;
+ } else {
+ // Otherwise anchor the tooltip to the view center.
+ offsetX = anchorView.getWidth() / 2; // Center on the view horizontally.
+ }
+
+ final int offsetBelow;
+ final int offsetAbove;
+ if (anchorView.getHeight() >= tooltipPreciseAnchorThreshold) {
+ // Tall view. Align the tooltip vertically to the precise Y position.
+ final int offsetExtra = mContext.getResources().getDimensionPixelOffset(
+ R.dimen.tooltip_precise_anchor_extra_offset);
+ offsetBelow = anchorY + offsetExtra;
+ offsetAbove = anchorY - offsetExtra;
+ } else {
+ // Otherwise anchor the tooltip to the view center.
+ offsetBelow = anchorView.getHeight(); // Place below the view in most cases.
+ offsetAbove = 0; // Place above the view if the tooltip does not fit below.
+ }
+
+ outParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
+
+ final int tooltipOffset = mContext.getResources().getDimensionPixelOffset(
+ fromTouch ? R.dimen.tooltip_y_offset_touch : R.dimen.tooltip_y_offset_non_touch);
+
+ final View appView = getAppRootView(anchorView);
+ if (appView == null) {
+ Log.e(TAG, "Cannot find app view");
+ return;
+ }
+ appView.getWindowVisibleDisplayFrame(mTmpDisplayFrame);
+ if (mTmpDisplayFrame.left < 0 && mTmpDisplayFrame.top < 0) {
+ // No meaningful display frame, the anchor view is probably in a subpanel
+ // (such as a popup window). Use the screen frame as a reasonable approximation.
+ final Resources res = mContext.getResources();
+ final int statusBarHeight;
+ int resourceId = res.getIdentifier("status_bar_height", "dimen", "android");
+ if (resourceId > 0) {
+ statusBarHeight = res.getDimensionPixelSize(resourceId);
+ } else {
+ statusBarHeight = 0;
+ }
+ final DisplayMetrics metrics = res.getDisplayMetrics();
+ mTmpDisplayFrame.set(0, statusBarHeight, metrics.widthPixels, metrics.heightPixels);
+ }
+ appView.getLocationOnScreen(mTmpAppPos);
+
+ anchorView.getLocationOnScreen(mTmpAnchorPos);
+ mTmpAnchorPos[0] -= mTmpAppPos[0];
+ mTmpAnchorPos[1] -= mTmpAppPos[1];
+ // mTmpAnchorPos is now relative to the main app window.
+
+ outParams.x = mTmpAnchorPos[0] + offsetX - mTmpDisplayFrame.width() / 2;
+
+ final int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
+ mContentView.measure(spec, spec);
+ final int tooltipHeight = mContentView.getMeasuredHeight();
+
+ final int yAbove = mTmpAnchorPos[1] + offsetAbove - tooltipOffset - tooltipHeight;
+ final int yBelow = mTmpAnchorPos[1] + offsetBelow + tooltipOffset;
+ if (fromTouch) {
+ if (yAbove >= 0) {
+ outParams.y = yAbove;
+ } else {
+ outParams.y = yBelow;
+ }
+ } else {
+ if (yBelow + tooltipHeight <= mTmpDisplayFrame.height()) {
+ outParams.y = yBelow;
+ } else {
+ outParams.y = yAbove;
+ }
+ }
+ }
+
+ private static View getAppRootView(View anchorView) {
+ Context context = anchorView.getContext();
+ while (context instanceof ContextWrapper) {
+ if (context instanceof Activity) {
+ return ((Activity) context).getWindow().getDecorView();
+ } else {
+ context = ((ContextWrapper) context).getBaseContext();
+ }
+ }
+ return anchorView.getRootView();
+ }
+}
diff --git a/v7/appcompat/tests/AndroidManifest.xml b/v7/appcompat/tests/AndroidManifest.xml
index 00febff..0401a19 100644
--- a/v7/appcompat/tests/AndroidManifest.xml
+++ b/v7/appcompat/tests/AndroidManifest.xml
@@ -30,6 +30,8 @@
<activity
android:name="android.support.v7.app.AppCompatActivity"/>
+ <activity android:name="android.support.v7.app.AppCompatMenuItemShortcutsTestActivity"/>
+
<activity
android:name="android.support.v7.app.WindowDecorAppCompatActivity"/>
<activity
@@ -56,6 +58,8 @@
android:label="@string/alert_dialog_activity"
android:theme="@style/Theme.AppCompat.Light" />
+ <activity android:name="android.support.v7.view.SupportMenuInflaterTestActivity" />
+
<activity
android:name="android.support.v7.widget.PopupTestActivity"
android:label="@string/popup_activity"
diff --git a/v7/appcompat/tests/res/menu/appcompat_menu_shortcut.xml b/v7/appcompat/tests/res/menu/appcompat_menu_shortcut.xml
new file mode 100644
index 0000000..95cdece
--- /dev/null
+++ b/v7/appcompat/tests/res/menu/appcompat_menu_shortcut.xml
@@ -0,0 +1,39 @@
+<?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
+ -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+
+ <item android:id="@+id/no_modifiers"
+ android:onClick="handleMenuItem"
+ android:alphabeticShortcut="a" />
+
+ <item android:id="@+id/default_modifiers"
+ android:onClick="handleMenuItem"
+ android:alphabeticShortcut="b"
+ app:alphabeticModifiers="CTRL" />
+
+ <item android:id="@+id/single_modifier"
+ android:onClick="handleMenuItem"
+ android:alphabeticShortcut="c"
+ app:alphabeticModifiers="SHIFT" />
+
+ <item android:id="@+id/multiple_modifiers"
+ android:onClick="handleMenuItem"
+ android:alphabeticShortcut="d"
+ app:alphabeticModifiers="CTRL|SHIFT" />
+
+</menu>
diff --git a/v7/appcompat/tests/res/menu/shortcut.xml b/v7/appcompat/tests/res/menu/shortcut.xml
new file mode 100644
index 0000000..b22c06c
--- /dev/null
+++ b/v7/appcompat/tests/res/menu/shortcut.xml
@@ -0,0 +1,41 @@
+<?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.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+
+ <item android:id="@+id/no_modifiers"
+ android:alphabeticShortcut="a"
+ android:numericShortcut="1" />
+
+ <item android:id="@+id/default_modifiers"
+ android:alphabeticShortcut="b"
+ android:numericShortcut="2"
+ app:alphabeticModifiers="CTRL"
+ app:numericModifiers="CTRL" />
+
+ <item android:id="@+id/single_modifier"
+ android:alphabeticShortcut="c"
+ android:numericShortcut="3"
+ app:alphabeticModifiers="SHIFT"
+ app:numericModifiers="SHIFT" />
+
+ <item android:id="@+id/multiple_modifiers"
+ android:alphabeticShortcut="d"
+ android:numericShortcut="4"
+ app:alphabeticModifiers="CTRL|SHIFT"
+ app:numericModifiers="CTRL|SHIFT" />
+
+</menu>
diff --git a/v7/appcompat/tests/src/android/support/v7/app/AppCompatMenuItemShortcutsTest.java b/v7/appcompat/tests/src/android/support/v7/app/AppCompatMenuItemShortcutsTest.java
new file mode 100644
index 0000000..6d4830a
--- /dev/null
+++ b/v7/appcompat/tests/src/android/support/v7/app/AppCompatMenuItemShortcutsTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.v7.app;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.os.SystemClock;
+import android.support.test.filters.SmallTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v7.appcompat.test.R;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuInflater;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test shortcut trigger in case of MenuItems with non-default modifiers.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AppCompatMenuItemShortcutsTest {
+
+ private AppCompatMenuItemShortcutsTestActivity mActivity;
+ private MenuInflater mMenuInflater;
+ private Menu mMenu;
+
+ @Rule
+ public ActivityTestRule<AppCompatMenuItemShortcutsTestActivity> mActivityTestRule =
+ new ActivityTestRule<>(AppCompatMenuItemShortcutsTestActivity.class);
+
+ @Before
+ public void setup() {
+ mActivity = mActivityTestRule.getActivity();
+ }
+
+ @Test
+ public void testPerformShortcut() {
+ final long downTime = SystemClock.uptimeMillis();
+ int keyCodeToSend, metaState;
+ KeyEvent keyEventToSend;
+
+ // Test shortcut trigger in case of non-default single modifier
+ keyCodeToSend = KeyEvent.KEYCODE_C;
+ metaState = KeyEvent.META_SHIFT_ON;
+ keyEventToSend = new KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+ keyCodeToSend, 0, metaState);
+ assertTrue(mActivity.onKeyDown(keyCodeToSend, keyEventToSend));
+ assertEquals(mActivity.getMenuItemIdTracker(), R.id.single_modifier);
+
+ // Test shortcut trigger in case of multiple modifiers
+ keyCodeToSend = KeyEvent.KEYCODE_D;
+ metaState = KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON;
+ keyEventToSend = new KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+ keyCodeToSend, 0, metaState);
+ assertTrue(mActivity.onKeyDown(keyCodeToSend, keyEventToSend));
+ assertEquals(mActivity.getMenuItemIdTracker(), R.id.multiple_modifiers);
+
+ // Test no shortcut trigger in case of incorrect modifier
+ keyCodeToSend = KeyEvent.KEYCODE_E;
+ metaState = KeyEvent.META_CTRL_ON;
+ keyEventToSend = new KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+ keyCodeToSend, 0, metaState);
+ assertFalse(mActivity.onKeyDown(keyCodeToSend, keyEventToSend));
+ }
+}
diff --git a/v7/appcompat/tests/src/android/support/v7/app/AppCompatMenuItemShortcutsTestActivity.java b/v7/appcompat/tests/src/android/support/v7/app/AppCompatMenuItemShortcutsTestActivity.java
new file mode 100644
index 0000000..26638f2
--- /dev/null
+++ b/v7/appcompat/tests/src/android/support/v7/app/AppCompatMenuItemShortcutsTestActivity.java
@@ -0,0 +1,42 @@
+/*
+ * 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.v7.app;
+
+import android.support.v7.appcompat.test.R;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+public class AppCompatMenuItemShortcutsTestActivity extends AppCompatActivity {
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.appcompat_menu_shortcut, menu);
+ return true;
+ }
+
+ private int mMenuItemIdTracker;
+
+ public int getMenuItemIdTracker() {
+ return mMenuItemIdTracker;
+ }
+
+ public boolean handleMenuItem(MenuItem item) {
+ mMenuItemIdTracker = item.getItemId();
+ return true;
+ }
+}
diff --git a/v7/appcompat/tests/src/android/support/v7/app/DrawerDynamicLayoutActivity.java b/v7/appcompat/tests/src/android/support/v7/app/DrawerDynamicLayoutActivity.java
index 90a9b59..92d97f4 100644
--- a/v7/appcompat/tests/src/android/support/v7/app/DrawerDynamicLayoutActivity.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/DrawerDynamicLayoutActivity.java
@@ -18,7 +18,6 @@
import android.support.v7.appcompat.test.R;
import android.support.v7.testutils.BaseTestActivity;
-import android.util.Log;
/**
* Test activity for testing presence of single and multiple drawers in <code>DrawerLayout</code>.
diff --git a/v7/appcompat/tests/src/android/support/v7/app/DrawerLayoutDoubleActivity.java b/v7/appcompat/tests/src/android/support/v7/app/DrawerLayoutDoubleActivity.java
index b2e0abc..a1c1558 100644
--- a/v7/appcompat/tests/src/android/support/v7/app/DrawerLayoutDoubleActivity.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/DrawerLayoutDoubleActivity.java
@@ -16,15 +16,12 @@
package android.support.v7.app;
-import android.content.res.Configuration;
-import android.os.Bundle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.appcompat.test.R;
import android.support.v7.testutils.BaseTestActivity;
import android.support.v7.testutils.Shakespeare;
import android.support.v7.widget.Toolbar;
-import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
diff --git a/v7/appcompat/tests/src/android/support/v7/custom/CustomDrawerLayout.java b/v7/appcompat/tests/src/android/support/v7/custom/CustomDrawerLayout.java
index dc202cd..6305301 100644
--- a/v7/appcompat/tests/src/android/support/v7/custom/CustomDrawerLayout.java
+++ b/v7/appcompat/tests/src/android/support/v7/custom/CustomDrawerLayout.java
@@ -16,12 +16,9 @@
package android.support.v7.custom;
import android.content.Context;
-import android.os.Build;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.WindowInsets;
-
import android.support.v4.widget.DrawerLayout;
+import android.util.AttributeSet;
+import android.view.WindowInsets;
public class CustomDrawerLayout extends DrawerLayout {
private int mSystemWindowInsetTop;
diff --git a/v7/appcompat/tests/src/android/support/v7/testutils/AppCompatTintableViewActions.java b/v7/appcompat/tests/src/android/support/v7/testutils/AppCompatTintableViewActions.java
index de36207..bce67aa 100644
--- a/v7/appcompat/tests/src/android/support/v7/testutils/AppCompatTintableViewActions.java
+++ b/v7/appcompat/tests/src/android/support/v7/testutils/AppCompatTintableViewActions.java
@@ -16,22 +16,20 @@
package android.support.v7.testutils;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+
+import static org.hamcrest.core.AllOf.allOf;
+
import android.content.res.ColorStateList;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.support.annotation.DrawableRes;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
-import android.support.v4.view.TintableBackgroundView;
import android.support.v4.view.ViewCompat;
-import android.support.v7.widget.AppCompatTextView;
import android.view.View;
-import org.hamcrest.Matcher;
-import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayingAtLeast;
-import static org.hamcrest.core.AllOf.allOf;
+import org.hamcrest.Matcher;
public class AppCompatTintableViewActions {
/**
diff --git a/v7/appcompat/tests/src/android/support/v7/testutils/TestUtilsMatchers.java b/v7/appcompat/tests/src/android/support/v7/testutils/TestUtilsMatchers.java
index 3e092c4..e3f25a9 100644
--- a/v7/appcompat/tests/src/android/support/v7/testutils/TestUtilsMatchers.java
+++ b/v7/appcompat/tests/src/android/support/v7/testutils/TestUtilsMatchers.java
@@ -25,10 +25,9 @@
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewParent;
import android.widget.CheckedTextView;
import android.widget.ImageView;
-import junit.framework.Assert;
+
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
diff --git a/v7/appcompat/tests/src/android/support/v7/view/SupportMenuInflaterTest.java b/v7/appcompat/tests/src/android/support/v7/view/SupportMenuInflaterTest.java
new file mode 100644
index 0000000..bfcb80b
--- /dev/null
+++ b/v7/appcompat/tests/src/android/support/v7/view/SupportMenuInflaterTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.v7.view;
+
+import static org.junit.Assert.assertEquals;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v4.internal.view.SupportMenuItem;
+import android.support.v7.appcompat.test.R;
+import android.support.v7.widget.PopupMenu;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuInflater;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test SupportMenuInflater
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SupportMenuInflaterTest {
+
+ private SupportMenuInflaterTestActivity mActivity;
+ private MenuInflater mMenuInflater;
+ private Menu mMenu;
+
+ @Rule
+ public ActivityTestRule<SupportMenuInflaterTestActivity> mActivityTestRule =
+ new ActivityTestRule<>(SupportMenuInflaterTestActivity.class);
+
+ @Before
+ public void setup() {
+ mActivity = mActivityTestRule.getActivity();
+ mMenuInflater = mActivity.getMenuInflater();
+ mMenu = new PopupMenu(mActivity, null).getMenu();
+ }
+
+ @Test
+ public void testInflateFromXml() {
+ mMenuInflater.inflate(R.menu.shortcut, mMenu);
+ SupportMenuItem mMenuItem;
+
+ mMenuItem = (SupportMenuItem) mMenu.findItem(R.id.no_modifiers);
+ assertEquals('a', mMenuItem.getAlphabeticShortcut());
+ assertEquals(KeyEvent.META_CTRL_ON, mMenuItem.getAlphabeticModifiers());
+ assertEquals('1', mMenuItem.getNumericShortcut());
+ assertEquals(KeyEvent.META_CTRL_ON, mMenuItem.getNumericModifiers());
+
+ mMenuItem = (SupportMenuItem) mMenu.findItem(R.id.default_modifiers);
+ assertEquals('b', mMenuItem.getAlphabeticShortcut());
+ assertEquals(KeyEvent.META_CTRL_ON, mMenuItem.getAlphabeticModifiers());
+ assertEquals('2', mMenuItem.getNumericShortcut());
+ assertEquals(KeyEvent.META_CTRL_ON, mMenuItem.getNumericModifiers());
+
+ mMenuItem = (SupportMenuItem) mMenu.findItem(R.id.single_modifier);
+ assertEquals('c', mMenuItem.getAlphabeticShortcut());
+ assertEquals(KeyEvent.META_SHIFT_ON, mMenuItem.getAlphabeticModifiers());
+ assertEquals('3', mMenuItem.getNumericShortcut());
+ assertEquals(KeyEvent.META_SHIFT_ON, mMenuItem.getNumericModifiers());
+
+ mMenuItem = (SupportMenuItem) mMenu.findItem(R.id.multiple_modifiers);
+ assertEquals('d', mMenuItem.getAlphabeticShortcut());
+ assertEquals(KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON,
+ mMenuItem.getAlphabeticModifiers());
+ assertEquals('4', mMenuItem.getNumericShortcut());
+ assertEquals(KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON,
+ mMenuItem.getNumericModifiers());
+ }
+}
diff --git a/v7/appcompat/tests/src/android/support/v7/view/SupportMenuInflaterTestActivity.java b/v7/appcompat/tests/src/android/support/v7/view/SupportMenuInflaterTestActivity.java
new file mode 100644
index 0000000..45ad0d9
--- /dev/null
+++ b/v7/appcompat/tests/src/android/support/v7/view/SupportMenuInflaterTestActivity.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.support.v7.view;
+
+import android.support.v7.appcompat.test.R;
+import android.support.v7.testutils.BaseTestActivity;
+
+public class SupportMenuInflaterTestActivity extends BaseTestActivity {
+
+ @Override
+ protected int getContentViewLayoutResId() {
+ return R.layout.appcompat_textview_activity;
+ }
+}
diff --git a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatButtonTest.java b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatButtonTest.java
index bfc2bc1..e663ef2 100644
--- a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatButtonTest.java
+++ b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatButtonTest.java
@@ -21,7 +21,6 @@
import static org.junit.Assert.assertEquals;
-import android.support.test.filters.SdkSuppress;
import android.support.test.filters.SmallTest;
import android.support.v7.appcompat.test.R;
diff --git a/v7/cardview/gingerbread/android/support/v7/widget/CardViewGingerbread.java b/v7/cardview/gingerbread/android/support/v7/widget/CardViewGingerbread.java
index 298505b..b779326 100644
--- a/v7/cardview/gingerbread/android/support/v7/widget/CardViewGingerbread.java
+++ b/v7/cardview/gingerbread/android/support/v7/widget/CardViewGingerbread.java
@@ -21,7 +21,6 @@
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.support.annotation.ColorInt;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
diff --git a/v7/mediarouter/jellybean/android/support/v7/media/MediaRouterJellybean.java b/v7/mediarouter/jellybean/android/support/v7/media/MediaRouterJellybean.java
index 0a090a5..51bd498 100644
--- a/v7/mediarouter/jellybean/android/support/v7/media/MediaRouterJellybean.java
+++ b/v7/mediarouter/jellybean/android/support/v7/media/MediaRouterJellybean.java
@@ -23,7 +23,6 @@
import android.support.annotation.RequiresApi;
import android.util.Log;
-import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
diff --git a/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java b/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java
index 6cc8c5d..95b5f5d 100644
--- a/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java
+++ b/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java
@@ -28,10 +28,10 @@
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.graphics.drawable.DrawableCompat;
-import android.support.v4.view.ViewCompat;
import android.support.v7.media.MediaRouteSelector;
import android.support.v7.media.MediaRouter;
import android.support.v7.mediarouter.R;
+import android.support.v7.widget.TooltipCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SoundEffectConstants;
@@ -274,7 +274,7 @@
* button when the button is long pressed.
*/
void setCheatSheetEnabled(boolean enable) {
- ViewCompat.setTooltipText(this,
+ TooltipCompat.setTooltipText(this,
enable ? getContext().getString(R.string.mr_button_content_description) : null);
}
diff --git a/v7/mediarouter/src/android/support/v7/app/MediaRouteVolumeSlider.java b/v7/mediarouter/src/android/support/v7/app/MediaRouteVolumeSlider.java
index a7a0dd3..4278028 100644
--- a/v7/mediarouter/src/android/support/v7/app/MediaRouteVolumeSlider.java
+++ b/v7/mediarouter/src/android/support/v7/app/MediaRouteVolumeSlider.java
@@ -20,7 +20,6 @@
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
-import android.support.v7.mediarouter.R;
import android.support.v7.widget.AppCompatSeekBar;
import android.util.AttributeSet;
import android.util.Log;
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderDescriptor.java b/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderDescriptor.java
index ec2f7ba..f6daeff 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderDescriptor.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderDescriptor.java
@@ -15,7 +15,6 @@
*/
package android.support.v7.media;
-import android.content.IntentFilter;
import android.os.Bundle;
import java.util.ArrayList;
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouter.java b/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
index fe16de8..1a17ef5 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
@@ -2289,7 +2289,7 @@
mRoutes.add(route);
// 2. Create the route's contents.
if (isGroup) {
- addedGroups.add(new Pair(route, routeDescriptor));
+ addedGroups.add(new Pair<>(route, routeDescriptor));
} else {
route.maybeUpdateDescriptor(routeDescriptor);
// 3. Notify clients about addition.
@@ -2309,7 +2309,7 @@
sourceIndex, targetIndex++);
// 2. Update the route's contents.
if (route instanceof RouteGroup) {
- updatedGroups.add(new Pair(route, routeDescriptor));
+ updatedGroups.add(new Pair<>(route, routeDescriptor));
} else {
// 3. Notify clients about changes.
if (updateRouteDescriptorAndNotify(route, routeDescriptor)
@@ -2413,7 +2413,7 @@
String componentName = provider.getComponentName().flattenToShortString();
String uniqueId = componentName + ":" + routeDescriptorId;
if (findRouteByUniqueId(uniqueId) < 0) {
- mUniqueIdMap.put(new Pair(componentName, routeDescriptorId), uniqueId);
+ mUniqueIdMap.put(new Pair<>(componentName, routeDescriptorId), uniqueId);
return uniqueId;
}
Log.w(TAG, "Either " + routeDescriptorId + " isn't unique in " + componentName
@@ -2421,7 +2421,7 @@
for (int i = 2; ; i++) {
String newUniqueId = String.format(Locale.US, "%s_%d", uniqueId, i);
if (findRouteByUniqueId(newUniqueId) < 0) {
- mUniqueIdMap.put(new Pair(componentName, routeDescriptorId), newUniqueId);
+ mUniqueIdMap.put(new Pair<>(componentName, routeDescriptorId), newUniqueId);
return newUniqueId;
}
}
@@ -2439,7 +2439,7 @@
private String getUniqueId(ProviderInfo provider, String routeDescriptorId) {
String componentName = provider.getComponentName().flattenToShortString();
- return mUniqueIdMap.get(new Pair(componentName, routeDescriptorId));
+ return mUniqueIdMap.get(new Pair<>(componentName, routeDescriptorId));
}
private void updateSelectedRouteIfNeeded(boolean selectedRouteDescriptorChanged) {
@@ -2494,7 +2494,7 @@
if (mSelectedRoute instanceof RouteGroup) {
List<RouteInfo> routes = ((RouteGroup) mSelectedRoute).getRoutes();
// Build a set of descriptor IDs for the new route group.
- Set idSet = new HashSet<String>();
+ Set<String> idSet = new HashSet<>();
for (RouteInfo route : routes) {
idSet.add(route.mDescriptorId);
}
diff --git a/v7/mediarouter/src/android/support/v7/media/RemotePlaybackClient.java b/v7/mediarouter/src/android/support/v7/media/RemotePlaybackClient.java
index 1dc556b..8e09889 100644
--- a/v7/mediarouter/src/android/support/v7/media/RemotePlaybackClient.java
+++ b/v7/mediarouter/src/android/support/v7/media/RemotePlaybackClient.java
@@ -24,8 +24,6 @@
import android.os.Bundle;
import android.util.Log;
-import java.util.Iterator;
-
/**
* A helper class for playing media on remote routes using the remote playback protocol
* defined by {@link MediaControlIntent}.
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 0c35828..b7fb054 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
@@ -540,7 +540,7 @@
final int darkTitleAlpha = ColorUtils.calculateMinimumAlpha(
Color.BLACK, mRgb, MIN_CONTRAST_TITLE_TEXT);
- if (darkBodyAlpha != -1 && darkBodyAlpha != -1) {
+ if (darkBodyAlpha != -1 && darkTitleAlpha != -1) {
// If we found valid dark values, use them and return
mBodyTextColor = ColorUtils.setAlphaComponent(Color.BLACK, darkBodyAlpha);
mTitleTextColor = ColorUtils.setAlphaComponent(Color.BLACK, darkTitleAlpha);
diff --git a/v7/recyclerview/build.gradle b/v7/recyclerview/build.gradle
index 2e4cfcf..b94876f 100644
--- a/v7/recyclerview/build.gradle
+++ b/v7/recyclerview/build.gradle
@@ -15,6 +15,7 @@
androidTestCompile libs.mockito_core
androidTestCompile libs.dexmaker
androidTestCompile libs.dexmaker_mockito
+ androidTestCompile project(':support-testutils')
testCompile libs.junit
testCompile libs.mockito_core
diff --git a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
index b8caca5..6e9ea69 100644
--- a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
+++ b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
@@ -486,7 +486,7 @@
* the View's state is undefined.
*/
@VisibleForTesting
- final List<ViewHolder> mPendingAccessibilityImportanceChange = new ArrayList();
+ final List<ViewHolder> mPendingAccessibilityImportanceChange = new ArrayList<>();
private Runnable mItemAnimatorRunner = new Runnable() {
@Override
@@ -5104,7 +5104,7 @@
public void putRecycledView(ViewHolder scrap) {
final int viewType = scrap.getItemViewType();
- final ArrayList scrapHeap = getScrapDataForType(viewType).mScrapHeap;
+ final ArrayList<ViewHolder> scrapHeap = getScrapDataForType(viewType).mScrapHeap;
if (mScrap.get(viewType).mMaxScrap <= scrapHeap.size()) {
return;
}
@@ -6209,7 +6209,7 @@
continue;
}
- final int pos = holder.getLayoutPosition();
+ final int pos = holder.mPosition;
if (pos >= positionStart && pos < positionEnd) {
holder.addFlags(ViewHolder.FLAG_UPDATE);
recycleCachedViewAt(i);
diff --git a/v7/recyclerview/tests/src/android/support/v7/util/PollingCheck.java b/v7/recyclerview/tests/src/android/support/v7/util/PollingCheck.java
deleted file mode 100644
index 796a4ae..0000000
--- a/v7/recyclerview/tests/src/android/support/v7/util/PollingCheck.java
+++ /dev/null
@@ -1,94 +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.v7.util;
-
-import junit.framework.Assert;
-
-import java.util.concurrent.Callable;
-
-public abstract class PollingCheck {
- private static final long TIME_SLICE = 50;
- private long mTimeout = 3000;
-
- public interface PollingCheckCondition {
- boolean canProceed();
- }
-
- public PollingCheck() {
- }
-
- public PollingCheck(long timeout) {
- mTimeout = timeout;
- }
-
- protected abstract boolean check();
-
- public void run() {
- if (check()) {
- return;
- }
-
- long timeout = mTimeout;
- while (timeout > 0) {
- try {
- Thread.sleep(TIME_SLICE);
- } catch (InterruptedException e) {
- Assert.fail("unexpected InterruptedException");
- }
-
- if (check()) {
- return;
- }
-
- timeout -= TIME_SLICE;
- }
-
- Assert.fail("unexpected timeout");
- }
-
- public static void check(CharSequence message, long timeout, Callable<Boolean> condition)
- throws Exception {
- while (timeout > 0) {
- if (condition.call()) {
- return;
- }
-
- Thread.sleep(TIME_SLICE);
- timeout -= TIME_SLICE;
- }
-
- Assert.fail(message.toString());
- }
-
- public static void waitFor(final PollingCheckCondition condition) {
- new PollingCheck() {
- @Override
- protected boolean check() {
- return condition.canProceed();
- }
- }.run();
- }
-
- public static void waitFor(long timeout, final PollingCheckCondition condition) {
- new PollingCheck(timeout) {
- @Override
- protected boolean check() {
- return condition.canProceed();
- }
- }.run();
- }
-}
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/BaseRecyclerViewInstrumentationTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/BaseRecyclerViewInstrumentationTest.java
index 5f7bf48..8ca5f4e 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/BaseRecyclerViewInstrumentationTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/BaseRecyclerViewInstrumentationTest.java
@@ -765,7 +765,7 @@
int mAdapterIndex;
- final String mText;
+ String mText;
int mType = 0;
boolean mFocusable;
@@ -882,7 +882,12 @@
assertEquals(log, shouldHavePosition, adapterPosition != RecyclerView.NO_POSITION);
if (shouldHavePosition) {
assertTrue(log, mItems.size() > adapterPosition);
- assertSame(log, holder.mBoundItem, mItems.get(adapterPosition));
+ // TODO: fix b/36042615 getAdapterPosition() is wrong in
+ // consumePendingUpdatesInOnePass where it applies pending change to already
+ // modified position.
+ if (holder.mPreLayoutPosition == RecyclerView.NO_POSITION) {
+ assertSame(log, holder.mBoundItem, mItems.get(adapterPosition));
+ }
}
}
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewAccessibilityLifecycleTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewAccessibilityLifecycleTest.java
index 6a2a175..bd14d2c 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewAccessibilityLifecycleTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewAccessibilityLifecycleTest.java
@@ -43,7 +43,7 @@
@MediumTest
@RunWith(AndroidJUnit4.class)
public class RecyclerViewAccessibilityLifecycleTest extends BaseRecyclerViewInstrumentationTest {
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
@Test
public void dontDispatchChangeDuringLayout() throws Throwable {
LayoutAllLayoutManager lm = new LayoutAllLayoutManager();
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java
index 786df47..2142832 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java
@@ -906,6 +906,61 @@
}
@Test
+ public void moveAndUpdateCachedViews() throws Throwable {
+ final RecyclerView recyclerView = new RecyclerView(getActivity());
+ recyclerView.setItemViewCacheSize(3);
+ recyclerView.setItemAnimator(null);
+ final TestAdapter adapter = new TestAdapter(1000);
+ final CountDownLatch layoutLatch = new CountDownLatch(1);
+ LinearLayoutManager tlm = new LinearLayoutManager(recyclerView.getContext()) {
+ @Override
+ public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
+ super.onLayoutChildren(recycler, state);
+ layoutLatch.countDown();
+ }
+ };
+ tlm.setItemPrefetchEnabled(false);
+ recyclerView.setLayoutManager(tlm);
+ recyclerView.setAdapter(adapter);
+ setRecyclerView(recyclerView);
+ // wait first layout pass
+ layoutLatch.await();
+ // scroll and hide 0 and 1
+ mActivityRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ recyclerView.smoothScrollBy(0, recyclerView.getChildAt(2).getTop() + 5);
+ }
+ });
+ waitForIdleScroll(recyclerView);
+ assertNull(recyclerView.findViewHolderForAdapterPosition(0));
+ assertNull(recyclerView.findViewHolderForAdapterPosition(1));
+ // swap 1 and 0 and update 0
+ mActivityRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ // swap 1 and 0
+ adapter.moveInUIThread(1, 0);
+ adapter.notifyItemMoved(1, 0);
+ // update 0
+ adapter.mItems.get(0).mText = "updated";
+ adapter.notifyItemChanged(0);
+ } catch (Throwable throwable) {
+ postExceptionToInstrumentation(throwable);
+ }
+ }
+ });
+ // scroll back to 0
+ smoothScrollToPosition(0);
+ waitForIdleScroll(recyclerView);
+ TestViewHolder vh = (TestViewHolder) recyclerView.findViewHolderForAdapterPosition(0);
+ // assert updated right item
+ assertTrue((((TextView) (vh.itemView)).getText()).toString().contains("updated"));
+ checkForMainThreadException();
+ }
+
+ @Test
public void noLayoutIf0ItemsAreChanged() throws Throwable {
unnecessaryNotifyEvents(new AdapterRunnable() {
@Override
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/WrappedRecyclerView.java b/v7/recyclerview/tests/src/android/support/v7/widget/WrappedRecyclerView.java
index c95f9ab..aa66b8f 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/WrappedRecyclerView.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/WrappedRecyclerView.java
@@ -16,12 +16,10 @@
package android.support.v7.widget;
-import android.app.Instrumentation;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
-import android.view.View;
import org.hamcrest.CoreMatchers;
import org.hamcrest.MatcherAssert;
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/helper/ItemTouchHelperTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/helper/ItemTouchHelperTest.java
index 604bf71..18af47b 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/helper/ItemTouchHelperTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/helper/ItemTouchHelperTest.java
@@ -31,7 +31,7 @@
import android.support.test.filters.SdkSuppress;
import android.support.test.filters.Suppress;
import android.support.test.runner.AndroidJUnit4;
-import android.support.v7.util.PollingCheck;
+import android.support.testutils.PollingCheck;
import android.support.v7.util.TouchUtils;
import android.support.v7.widget.BaseRecyclerViewInstrumentationTest;
import android.support.v7.widget.RecyclerView;
diff --git a/wearable/Android.mk b/wearable/Android.mk
index 98ea45a..7339f55 100644
--- a/wearable/Android.mk
+++ b/wearable/Android.mk
@@ -19,7 +19,8 @@
#
# LOCAL_STATIC_ANDROID_LIBRARIES := \
# android-support-wearable \
-# android-support-core-ui
+# android-support-core-ui \
+# android-support-v7-recyclerview
#
# in their makefiles to include the resources and their dependencies in their package.
include $(CLEAR_VARS)
@@ -29,9 +30,10 @@
LOCAL_SRC_FILES := $(call all-java-files-under,src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_SHARED_ANDROID_LIBRARIES := \
- android-support-core-ui \
- android-support-annotations \
- android-support-v7-recyclerview
+ android-support-core-ui \
+ android-support-annotations \
+ android-support-v7-recyclerview \
+ android-support-v4
LOCAL_JAR_EXCLUDE_FILES := none
LOCAL_JAVA_LANGUAGE_VERSION := 1.7
LOCAL_AAPT_FLAGS := --add-javadoc-annotation doconly
diff --git a/wearable/build.gradle b/wearable/build.gradle
index 74b4c89..81ec665 100644
--- a/wearable/build.gradle
+++ b/wearable/build.gradle
@@ -5,13 +5,15 @@
compile project(':support-annotations')
compile project(':support-core-ui')
compile project(':support-recyclerview-v7')
-
androidTestCompile (libs.test_runner) {
exclude module: 'support-annotations'
}
androidTestCompile (libs.espresso_core) {
exclude module: 'support-annotations'
}
+ androidTestCompile libs.mockito_core
+ androidTestCompile libs.dexmaker
+ androidTestCompile libs.dexmaker_mockito
}
android {
diff --git a/wearable/res-public/values/public_attrs.xml b/wearable/res-public/values/public_attrs.xml
index afb7bfe..a8a2909 100644
--- a/wearable/res-public/values/public_attrs.xml
+++ b/wearable/res-public/values/public_attrs.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
+<!-- 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.
@@ -16,5 +16,11 @@
<!-- Definitions of attributes to be exposed as public -->
<resources>
+ <!-- BoxInsetLayout -->
<public type="attr" name="boxedEdges" />
+
+ <!-- WearableRecyclerView -->
+ <public type="attr" name="bezelWidth" />
+ <public type="attr" name="circularScrollingGestureEnabled" />
+ <public type="attr" name="scrollDegreesPerScreen" />
</resources>
\ No newline at end of file
diff --git a/wearable/res/values/attrs.xml b/wearable/res/values/attrs.xml
index e52dee9..bdf3675 100644
--- a/wearable/res/values/attrs.xml
+++ b/wearable/res/values/attrs.xml
@@ -47,4 +47,21 @@
<flag name="all" value="0x0F" />
</attr>
</declare-styleable>
+
+ <!-- Attributes that can be used with any
+ {@link android.support.wearable.view.WearableRecyclerView}.
+ These attributes relate to the circular scrolling gesture of the view. -->
+ <declare-styleable name="WearableRecyclerView">
+ <!-- Taps within this radius and the radius of the screen are considered close enough to the
+ bezel to be candidates for circular scrolling. Expressed as a fraction of the screen's
+ radius. The default is the whole screen i.e 1.0f -->
+ <attr name="bezelWidth" format="fraction" />
+ <!-- Enables/disables circular touch scrolling for this view. When enabled, circular touch
+ gestures around the edge of the screen will cause the view to scroll up or down. -->
+ <attr name="circularScrollingGestureEnabled" format="boolean" />
+ <!-- Sets how many degrees the user has to rotate by to scroll through one screen height
+ when they are using the circular scrolling gesture. The default value equates 180
+ degrees scroll to one screen.-->
+ <attr name="scrollDegreesPerScreen" format="float" />
+ </declare-styleable>
</resources>
diff --git a/dynamic-animation/AndroidManifest-make.xml b/wearable/res/values/dimens.xml
similarity index 78%
copy from dynamic-animation/AndroidManifest-make.xml
copy to wearable/res/values/dimens.xml
index bfe97cc..4b95511 100644
--- a/dynamic-animation/AndroidManifest-make.xml
+++ b/wearable/res/values/dimens.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.support.dynamicanimation">
- <uses-sdk android:minSdkVersion="16"/>
-</manifest>
+<resources>
+ <!-- Values for the WearableRecyclerView. -->
+ <dimen name="wrv_curve_default_x_offset">24dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/wearable/src/android/support/wearable/view/CurvedOffsettingHelper.java b/wearable/src/android/support/wearable/view/CurvedOffsettingHelper.java
new file mode 100644
index 0000000..a1f4e3b
--- /dev/null
+++ b/wearable/src/android/support/wearable/view/CurvedOffsettingHelper.java
@@ -0,0 +1,141 @@
+/*
+ * 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.wearable.view;
+
+import android.graphics.Path;
+import android.graphics.PathMeasure;
+import android.support.wearable.R;
+import android.view.View;
+
+/**
+ * This implementation of the {@link WearableRecyclerView.OffsettingHelper} provides basic
+ * offsetting logic for updating child layout. For round devices it offsets the children
+ * horizontally to make them appear to travel around a circle. For square devices it aligns them
+ * in a straight list.
+ */
+public class CurvedOffsettingHelper extends WearableRecyclerView.OffsettingHelper {
+ private static final float EPSILON = 0.001f;
+
+ private final Path mCurvePath;
+ private final PathMeasure mPathMeasure;
+ private int mCurvePathHeight;
+ private int mXCurveOffset;
+ private float mPathLength;
+ private float mCurveBottom;
+ private float mCurveTop;
+ private float mLineGradient;
+ private final float[] mPathPoints = new float[2];
+ private final float[] mPathTangent = new float[2];
+ private final float[] mAnchorOffsetXY = new float[2];
+
+ private WearableRecyclerView mParentView;
+ private boolean mIsScreenRound;
+ private int mLayoutWidth;
+ private int mLayoutHeight;
+
+ public CurvedOffsettingHelper() {
+ mCurvePath = new Path();
+ mPathMeasure = new PathMeasure();
+ }
+
+ @Override
+ public void updateChild(View child, WearableRecyclerView parent) {
+ if (mParentView != parent || (mParentView != null
+ && (mParentView.getWidth() != parent.getWidth()
+ || mParentView.getHeight() != parent.getHeight()))) {
+ mParentView = parent;
+ mIsScreenRound =
+ mParentView.getContext().getResources().getConfiguration().isScreenRound();
+ mXCurveOffset =
+ mParentView.getResources().getDimensionPixelSize(
+ R.dimen.wrv_curve_default_x_offset);
+ mLayoutWidth = mParentView.getWidth();
+ mLayoutHeight = mParentView.getHeight();
+ }
+ if (mIsScreenRound) {
+ maybeSetUpCircularInitialLayout(mLayoutWidth, mLayoutHeight);
+ mAnchorOffsetXY[0] = mXCurveOffset;
+ mAnchorOffsetXY[1] = child.getHeight() / 2.0f;
+ adjustAnchorOffsetXY(child, mAnchorOffsetXY);
+ float minCenter = -(float) child.getHeight() / 2;
+ float maxCenter = mLayoutHeight + (float) child.getHeight() / 2;
+ float range = maxCenter - minCenter;
+ float verticalAnchor = (float) child.getTop() + mAnchorOffsetXY[1];
+ float mYScrollProgress = (verticalAnchor + Math.abs(minCenter)) / range;
+
+ mPathMeasure.getPosTan(mYScrollProgress * mPathLength, mPathPoints, mPathTangent);
+
+ boolean topClusterRisk =
+ Math.abs(mPathPoints[1] - mCurveBottom) < EPSILON && minCenter < mPathPoints[1];
+ boolean bottomClusterRisk =
+ Math.abs(mPathPoints[1] - mCurveTop) < EPSILON && maxCenter > mPathPoints[1];
+ // Continue offsetting the child along the straight-line part of the curve, if it has
+ // not gone off the screen when it reached the end of the original curve.
+ if (topClusterRisk || bottomClusterRisk) {
+ mPathPoints[1] = verticalAnchor;
+ mPathPoints[0] = (Math.abs(verticalAnchor) * mLineGradient);
+ }
+
+ // Offset the View to match the provided anchor point.
+ int newLeft = (int) (mPathPoints[0] - mAnchorOffsetXY[0]);
+ child.offsetLeftAndRight(newLeft - child.getLeft());
+ float verticalTranslation = mPathPoints[1] - verticalAnchor;
+ child.setTranslationY(verticalTranslation);
+ }
+ }
+
+ /**
+ * Override this method if you wish to adjust the anchor coordinates for each child view during
+ * a layout pass. In the override set the new desired anchor coordinates in the provided array.
+ * The coordinates should be provided in relation to the child view.
+ *
+ * @param child The child view to which the anchor coordinates will apply.
+ * @param anchorOffsetXY The anchor coordinates for the provided child view, by default set to
+ * a pre-defined constant on the horizontal axis and half of the child
+ * height on the vertical axis (vertical center).
+ */
+ public void adjustAnchorOffsetXY(View child, float[] anchorOffsetXY) {
+ return;
+ }
+
+ /** Set up the initial layout for round screens. */
+ private void maybeSetUpCircularInitialLayout(int width, int height) {
+ // The values in this function are custom to the curve we use.
+ if (mCurvePathHeight != height) {
+ mCurvePathHeight = height;
+ mCurveBottom = -0.048f * height;
+ mCurveTop = 1.048f * height;
+ mLineGradient = 0.5f / 0.048f;
+ mCurvePath.reset();
+ mCurvePath.moveTo(0.5f * width, mCurveBottom);
+ mCurvePath.lineTo(0.34f * width, 0.075f * height);
+ mCurvePath.cubicTo(
+ 0.22f * width, 0.17f * height, 0.13f * width, 0.32f * height, 0.13f * width,
+ height / 2);
+ mCurvePath.cubicTo(
+ 0.13f * width,
+ 0.68f * height,
+ 0.22f * width,
+ 0.83f * height,
+ 0.34f * width,
+ 0.925f * height);
+ mCurvePath.lineTo(width / 2, mCurveTop);
+ mPathMeasure.setPath(mCurvePath, false);
+ mPathLength = mPathMeasure.getLength();
+ }
+ }
+}
diff --git a/wearable/src/android/support/wearable/view/ScrollManager.java b/wearable/src/android/support/wearable/view/ScrollManager.java
new file mode 100644
index 0000000..4699d4b
--- /dev/null
+++ b/wearable/src/android/support/wearable/view/ScrollManager.java
@@ -0,0 +1,236 @@
+/*
+ * 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.wearable.view;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.support.annotation.RestrictTo;
+import android.support.v7.widget.RecyclerView;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+
+/**
+ * Class adding circular scrolling support to {@link WearableRecyclerView}.
+ *
+ * @hide
+ */
+@TargetApi(Build.VERSION_CODES.M)
+@RestrictTo(LIBRARY_GROUP)
+class ScrollManager {
+ // One second in milliseconds.
+ private static final int ONE_SEC_IN_MS = 1000;
+ private static final float VELOCITY_MULTIPLIER = 1.5f;
+ private static final float FLING_EDGE_RATIO = 1.5f;
+
+ /**
+ * Taps beyond this radius fraction are considered close enough to the bezel to be candidates
+ * for circular scrolling.
+ */
+ private float mMinRadiusFraction = 0.0f;
+
+ private float mMinRadiusFractionSquared = mMinRadiusFraction * mMinRadiusFraction;
+
+ /** How many degrees you have to drag along the bezel to scroll one screen height. */
+ private float mScrollDegreesPerScreen = 180;
+
+ private float mScrollRadiansPerScreen = (float) Math.toRadians(mScrollDegreesPerScreen);
+
+ /** Radius of screen in pixels, ignoring insets, if any. */
+ private float mScreenRadiusPx;
+
+ private float mScreenRadiusPxSquared;
+
+ /** How many pixels to scroll for each radian of bezel scrolling. */
+ private float mScrollPixelsPerRadian;
+
+ /** Whether an {@link MotionEvent#ACTION_DOWN} was received near the bezel. */
+ private boolean mDown;
+
+ /**
+ * Whether the user tapped near the bezel and dragged approximately tangentially to initiate
+ * bezel scrolling.
+ */
+ private boolean mScrolling;
+ /**
+ * The angle of the user's finger relative to the center of the screen for the last {@link
+ * MotionEvent} during bezel scrolling.
+ */
+ private float mLastAngleRadians;
+
+ private RecyclerView mRecyclerView;
+ VelocityTracker mVelocityTracker;
+
+ /** Should be called after the window is attached to the view. */
+ void setRecyclerView(RecyclerView recyclerView, int width, int height) {
+ mRecyclerView = recyclerView;
+ mScreenRadiusPx = Math.max(width, height) / 2f;
+ mScreenRadiusPxSquared = mScreenRadiusPx * mScreenRadiusPx;
+ mScrollPixelsPerRadian = height / mScrollRadiansPerScreen;
+ mVelocityTracker = VelocityTracker.obtain();
+ }
+
+ /** Remove the binding with a {@link RecyclerView} */
+ void clearRecyclerView() {
+ mRecyclerView = null;
+ }
+
+ /**
+ * Method dealing with touch events intercepted from the attached {@link RecyclerView}.
+ *
+ * @param event the intercepted touch event.
+ * @return true if the even was handled, false otherwise.
+ */
+ boolean onTouchEvent(MotionEvent event) {
+ float deltaX = event.getRawX() - mScreenRadiusPx;
+ float deltaY = event.getRawY() - mScreenRadiusPx;
+ float radiusSquared = deltaX * deltaX + deltaY * deltaY;
+ final MotionEvent vtev = MotionEvent.obtain(event);
+ mVelocityTracker.addMovement(vtev);
+ vtev.recycle();
+
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ if (radiusSquared / mScreenRadiusPxSquared > mMinRadiusFractionSquared) {
+ mDown = true;
+ return true; // Consume the event.
+ }
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ if (mScrolling) {
+ float angleRadians = (float) Math.atan2(deltaY, deltaX);
+ float deltaRadians = angleRadians - mLastAngleRadians;
+ deltaRadians = normalizeAngleRadians(deltaRadians);
+ int scrollPixels = Math.round(deltaRadians * mScrollPixelsPerRadian);
+ if (scrollPixels != 0) {
+ mRecyclerView.scrollBy(0 /* x */, scrollPixels /* y */);
+ // Recompute deltaRadians in terms of rounded scrollPixels.
+ deltaRadians = scrollPixels / mScrollPixelsPerRadian;
+ mLastAngleRadians += deltaRadians;
+ mLastAngleRadians = normalizeAngleRadians(mLastAngleRadians);
+ }
+ // Always consume the event so that we never break the circular scrolling
+ // gesture.
+ return true;
+ }
+
+ if (mDown) {
+ float deltaXFromCenter = event.getRawX() - mScreenRadiusPx;
+ float deltaYFromCenter = event.getRawY() - mScreenRadiusPx;
+ float distFromCenter = (float) Math.hypot(deltaXFromCenter, deltaYFromCenter);
+ if (distFromCenter != 0) {
+ deltaXFromCenter /= distFromCenter;
+ deltaYFromCenter /= distFromCenter;
+
+ mScrolling = true;
+ mRecyclerView.invalidate();
+ mLastAngleRadians = (float) Math.atan2(deltaYFromCenter, deltaXFromCenter);
+ return true; // Consume the event.
+ }
+ } else {
+ // Double check we're not missing an event we should really be handling.
+ if (radiusSquared / mScreenRadiusPxSquared > mMinRadiusFractionSquared) {
+ mDown = true;
+ return true; // Consume the event.
+ }
+ }
+ break;
+
+ case MotionEvent.ACTION_UP:
+ mDown = false;
+ mScrolling = false;
+ mVelocityTracker.computeCurrentVelocity(ONE_SEC_IN_MS,
+ mRecyclerView.getMaxFlingVelocity());
+ int velocityY = (int) mVelocityTracker.getYVelocity();
+ if (event.getX() < FLING_EDGE_RATIO * mScreenRadiusPx) {
+ velocityY = -velocityY;
+ }
+ mVelocityTracker.clear();
+ if (Math.abs(velocityY) > mRecyclerView.getMinFlingVelocity()) {
+ return mRecyclerView.fling(0, (int) (VELOCITY_MULTIPLIER * velocityY));
+ }
+ break;
+
+ case MotionEvent.ACTION_CANCEL:
+ if (mDown) {
+ mDown = false;
+ mScrolling = false;
+ mRecyclerView.invalidate();
+ return true; // Consume the event.
+ }
+ break;
+ }
+
+ return false;
+ }
+
+ /**
+ * Normalizes an angle to be in the range [-pi, pi] by adding or subtracting 2*pi if necessary.
+ *
+ * @param angleRadians an angle in radians. Must be no more than 2*pi out of normal range.
+ * @return an angle in radians in the range [-pi, pi]
+ */
+ private static float normalizeAngleRadians(float angleRadians) {
+ if (angleRadians < -Math.PI) {
+ angleRadians = (float) (angleRadians + Math.PI * 2);
+ }
+ if (angleRadians > Math.PI) {
+ angleRadians = (float) (angleRadians - Math.PI * 2);
+ }
+ return angleRadians;
+ }
+
+ /**
+ * Set how many degrees you have to drag along the bezel to scroll one screen height.
+ *
+ * @param degreesPerScreen desired degrees per screen scroll.
+ */
+ public void setScrollDegreesPerScreen(float degreesPerScreen) {
+ mScrollDegreesPerScreen = degreesPerScreen;
+ mScrollRadiansPerScreen = (float) Math.toRadians(mScrollDegreesPerScreen);
+ }
+
+ /**
+ * Sets the width of a virtual 'bezel' close to the edge of the screen within which taps can be
+ * recognized as belonging to a rotary scrolling gesture.
+ *
+ * @param fraction desired fraction of the width of the screen to be treated as a valid rotary
+ * scrolling target.
+ */
+ public void setBezelWidth(float fraction) {
+ mMinRadiusFraction = 1 - fraction;
+ mMinRadiusFractionSquared = mMinRadiusFraction * mMinRadiusFraction;
+ }
+
+ /**
+ * Returns how many degrees you have to drag along the bezel to scroll one screen height. See
+ * {@link #setScrollDegreesPerScreen(float)} for details.
+ */
+ public float getScrollDegreesPerScreen() {
+ return mScrollDegreesPerScreen;
+ }
+
+ /**
+ * Returns the current bezel width for circular scrolling. See {@link #setBezelWidth(float)}
+ * for details.
+ */
+ public float getBezelWidth() {
+ return 1 - mMinRadiusFraction;
+ }
+}
diff --git a/wearable/src/android/support/wearable/view/WearableRecyclerView.java b/wearable/src/android/support/wearable/view/WearableRecyclerView.java
new file mode 100644
index 0000000..5531417
--- /dev/null
+++ b/wearable/src/android/support/wearable/view/WearableRecyclerView.java
@@ -0,0 +1,334 @@
+/*
+ * 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.wearable.view;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Point;
+import android.os.Build;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.wearable.R;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+/**
+ * Wearable specific implementation of the {@link RecyclerView} enabling {@link
+ * #setCircularScrollingGestureEnabled(boolean)} circular scrolling} and semi-circular layouts.
+ *
+ * @see #setCircularScrollingGestureEnabled(boolean)
+ * @see #setOffsettingHelper(OffsettingHelper)
+ */
+@TargetApi(Build.VERSION_CODES.M)
+public class WearableRecyclerView extends RecyclerView {
+ private static final String TAG = "WearableRecyclerView";
+
+ private static final int NO_VALUE = Integer.MIN_VALUE;
+
+ /**
+ * This class defines the offsetting logic for updating layout of children in a
+ * WearableRecyclerView.
+ */
+ public abstract static class OffsettingHelper {
+
+ /**
+ * Override this method if you wish to implement custom child layout behavior on scroll.
+ *
+ * @param child the current child to be affected.
+ * @param parent the {@link WearableRecyclerView} parent that this helper is attached to.
+ */
+ public abstract void updateChild(View child, WearableRecyclerView parent);
+ }
+
+ private final ScrollManager mScrollManager = new ScrollManager();
+ private OffsettingHelper mOffsettingHelper;
+ private boolean mCircularScrollingEnabled;
+ private boolean mEdgeItemsCenteringEnabled;
+
+ private int mOriginalPaddingTop = NO_VALUE;
+ private int mOriginalPaddingBottom = NO_VALUE;
+
+ public WearableRecyclerView(Context context) {
+ this(context, null);
+ }
+
+ public WearableRecyclerView(Context context, @Nullable AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public WearableRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
+ this(context, attrs, defStyle, 0);
+ }
+
+ public WearableRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle,
+ int defStyleRes) {
+ super(context, attrs, defStyle);
+
+ setHasFixedSize(true);
+ // Padding is used to center the top and bottom items in the list, don't clip to padding to
+ // allows the items to draw in that space.
+ setClipToPadding(false);
+
+ if (attrs != null) {
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.WearableRecyclerView,
+ defStyle, defStyleRes);
+
+ setCircularScrollingGestureEnabled(
+ a.getBoolean(
+ R.styleable.WearableRecyclerView_circularScrollingGestureEnabled,
+ mCircularScrollingEnabled));
+ setBezelWidthFraction(
+ a.getFloat(R.styleable.WearableRecyclerView_bezelWidth,
+ mScrollManager.getBezelWidth()));
+ setScrollDegreesPerScreen(
+ a.getFloat(
+ R.styleable.WearableRecyclerView_scrollDegreesPerScreen,
+ mScrollManager.getScrollDegreesPerScreen()));
+ a.recycle();
+ }
+
+ setLayoutManager(new OffsettingLinearLayoutManager(getContext()));
+ }
+
+ private void setupCenteredPadding() {
+ if (getChildCount() < 1 || !mEdgeItemsCenteringEnabled) {
+ return;
+ }
+ // All the children in the view are the same size, as we set setHasFixedSize
+ // to true, so the height of the first child is the same as all of them.
+ View child = getChildAt(0);
+ int height = child.getHeight();
+ // This is enough padding to center the child view in the parent.
+ int desiredPadding = (int) ((getHeight() * 0.5f) - (height * 0.5f));
+
+ if (getPaddingTop() != desiredPadding) {
+ mOriginalPaddingTop = getPaddingTop();
+ mOriginalPaddingBottom = getPaddingBottom();
+ // The view is symmetric along the vertical axis, so the top and bottom
+ // can be the same.
+ setPadding(getPaddingLeft(), desiredPadding, getPaddingRight(), desiredPadding);
+
+ // The focused child should be in the center, so force a scroll to it.
+ View focusedChild = getFocusedChild();
+ int focusedPosition =
+ (focusedChild != null) ? getLayoutManager().getPosition(
+ focusedChild) : 0;
+ getLayoutManager().scrollToPosition(focusedPosition);
+ }
+ }
+
+ private void setupOriginalPadding() {
+ if (mOriginalPaddingTop == NO_VALUE) {
+ return;
+ } else {
+ setPadding(getPaddingLeft(), mOriginalPaddingTop, getPaddingRight(),
+ mOriginalPaddingBottom);
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (mCircularScrollingEnabled && mScrollManager.onTouchEvent(event)) {
+ return true;
+ }
+ return super.onTouchEvent(event);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ Point screenSize = new Point();
+ getDisplay().getSize(screenSize);
+ mScrollManager.setRecyclerView(this, screenSize.x, screenSize.y);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mScrollManager.clearRecyclerView();
+ }
+
+ @Override
+ public void setLayoutManager(LayoutManager layoutManager) {
+ if (!(layoutManager instanceof OffsettingLinearLayoutManager)) {
+ throw new UnsupportedOperationException(
+ "This class implements its own layout manager and does not take custom ones");
+ } else {
+ super.setLayoutManager(layoutManager);
+ }
+ }
+
+ /**
+ * Enables/disables circular touch scrolling for this view. When enabled, circular touch
+ * gestures around the edge of the screen will cause the view to scroll up or down. Related
+ * methods let you specify the characteristics of the scrolling, like the speed of the scroll
+ * or the are considered for the start of this scrolling gesture.
+ *
+ * @see #setScrollDegreesPerScreen(float)
+ * @see #setBezelWidthFraction(float)
+ */
+ public void setCircularScrollingGestureEnabled(boolean circularScrollingGestureEnabled) {
+ mCircularScrollingEnabled = circularScrollingGestureEnabled;
+ }
+
+ /**
+ * Returns whether circular scrolling is enabled for this view.
+ *
+ * @see #setCircularScrollingGestureEnabled(boolean)
+ */
+ public boolean isCircularScrollingGestureEnabled() {
+ return mCircularScrollingEnabled;
+ }
+
+ /**
+ * Sets how many degrees the user has to rotate by to scroll through one screen height when they
+ * are using the circular scrolling gesture.The default value equates 180 degrees scroll to one
+ * screen.
+ *
+ * @see #setCircularScrollingGestureEnabled(boolean)
+ *
+ * @param degreesPerScreen the number of degrees to rotate by to scroll through one whole
+ * height of the screen,
+ */
+ public void setScrollDegreesPerScreen(float degreesPerScreen) {
+ mScrollManager.setScrollDegreesPerScreen(degreesPerScreen);
+ }
+
+ /**
+ * Returns how many degrees does the user have to rotate for to scroll through one screen
+ * height.
+ *
+ * @see #setCircularScrollingGestureEnabled(boolean)
+ * @see #setScrollDegreesPerScreen(float).
+ */
+ public float getScrollDegreesPerScreen() {
+ return mScrollManager.getScrollDegreesPerScreen();
+ }
+
+ /**
+ * Taps within this radius and the radius of the screen are considered close enough to the
+ * bezel to be candidates for circular scrolling. Expressed as a fraction of the screen's
+ * radius. The default is the whole screen i.e 1.0f.
+ */
+ public void setBezelWidthFraction(float fraction) {
+ mScrollManager.setBezelWidth(fraction);
+ }
+
+ /**
+ * Returns the current bezel width for circular scrolling as a fraction of the screen's
+ * radius.
+ *
+ * @see #setBezelWidthFraction(float)
+ */
+ public float getBezelWidthFraction() {
+ return mScrollManager.getBezelWidth();
+ }
+
+ /**
+ * Sets the {@link WearableRecyclerView.OffsettingHelper} that this {@link
+ * WearableRecyclerView} will use.
+ *
+ * @param offsettingHelper the instance of {@link OffsettingHelper} to use. Pass null if you
+ * wish to clear the instance used.
+ */
+ public void setOffsettingHelper(@Nullable OffsettingHelper offsettingHelper) {
+ mOffsettingHelper = offsettingHelper;
+ }
+
+ /**
+ * Return the {@link WearableRecyclerView.OffsettingHelper} currently responsible for
+ * offsetting logic for this {@link WearableRecyclerView}.
+ *
+ * @return the currently used {@link OffsettingHelper} instance.
+ */
+ @Nullable
+ public OffsettingHelper getOffsettingHelper() {
+ return mOffsettingHelper;
+ }
+
+ /**
+ * Use this method to configure the {@link WearableRecyclerView} to always align the first and
+ * last items with the vertical center of the screen. This effectively moves the start and end
+ * of the list to the middle of the screen if the user has scrolled so far. It takes the height
+ * of the children into account so that they are correctly centered.
+ *
+ * @param isEnabled set to true if you wish to align the edge children (first and last)
+ * with the center of the screen.
+ */
+ public void setEdgeItemsCenteringEnabled(boolean isEnabled) {
+ mEdgeItemsCenteringEnabled = isEnabled;
+ if (mEdgeItemsCenteringEnabled) {
+ setupCenteredPadding();
+ } else {
+ setupOriginalPadding();
+ }
+ }
+
+ /**
+ * Returns whether the view is currently configured to center the edge children. See {@link
+ * #setEdgeItemsCenteringEnabled} for details.
+ */
+ public boolean getEdgeItemsCenteringEnabled() {
+ return mEdgeItemsCenteringEnabled;
+ }
+
+ /**
+ * Helper class which implements a vertical linear layout manager that encapsulates the logic
+ * for updating layout of children of a WearableRecyclerView.
+ */
+ private final class OffsettingLinearLayoutManager extends LinearLayoutManager {
+ /**
+ * Creates a vertical OffsettingLinearLayoutManager
+ *
+ * @param context Current context, will be used to access resources.
+ */
+ OffsettingLinearLayoutManager(Context context) {
+ super(context, VERTICAL, false);
+ }
+
+ @Override
+ public int scrollVerticallyBy(
+ int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
+ int scrolled = super.scrollVerticallyBy(dy, recycler, state);
+
+ updateLayout();
+ return scrolled;
+ }
+
+ @Override
+ public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
+ super.onLayoutChildren(recycler, state);
+ if (getChildCount() == 0) {
+ return;
+ }
+
+ updateLayout();
+ }
+
+ private void updateLayout() {
+ if (mOffsettingHelper != null) {
+ for (int count = 0; count < getChildCount(); count++) {
+ View child = getChildAt(count);
+ mOffsettingHelper.updateChild(child, WearableRecyclerView.this);
+ }
+ }
+ }
+ }
+}
diff --git a/wearable/tests/Android.mk b/wearable/tests/Android.mk
deleted file mode 100644
index 41e00fb..0000000
--- a/wearable/tests/Android.mk
+++ /dev/null
@@ -1,38 +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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_RESOURCE_DIR := \
- $(LOCAL_PATH)/res \
- $(LOCAL_PATH)/../res
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-wearable \
- android-support-annotations
-
-LOCAL_PACKAGE_NAME := WearableViewTests
-LOCAL_AAPT_FLAGS := \
- --auto-add-overlay \
- --extra-packages android.support.wearable.view
-
-include $(BUILD_PACKAGE)
diff --git a/wearable/tests/AndroidManifest.xml b/wearable/tests/AndroidManifest.xml
index a0ab292..638532d 100644
--- a/wearable/tests/AndroidManifest.xml
+++ b/wearable/tests/AndroidManifest.xml
@@ -19,13 +19,12 @@
package="android.support.wearable.test">
<uses-sdk android:minSdkVersion="20"
android:targetSdkVersion="23"
- tools:overrideLibrary="android.support.test,
- android.app, android.support.test.rule, android.support.test.espresso,
- android.support.test.espresso.idling"/>
+ tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
+ android.support.test.espresso, android.support.test.espresso.idling"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
- <application android:supportsRtl="true" >
+ <application android:supportsRtl="true">
<activity android:name="android.support.wearable.view.LayoutTestActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -38,5 +37,12 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+
+ <activity android:name="android.support.wearable.view.WearableRecyclerViewTestActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
</application>
</manifest>
diff --git a/wearable/tests/res/layout/curved_offsetting_helper_child.xml b/wearable/tests/res/layout/curved_offsetting_helper_child.xml
new file mode 100644
index 0000000..781d6b3
--- /dev/null
+++ b/wearable/tests/res/layout/curved_offsetting_helper_child.xml
@@ -0,0 +1,21 @@
+<?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.
+ -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/content1"
+ android:layout_width="100dp"
+ android:layout_height="50dp"
+ android:text="Test Case 1"/>
\ No newline at end of file
diff --git a/wearable/tests/res/layout/wearable_recycler_view_basic.xml b/wearable/tests/res/layout/wearable_recycler_view_basic.xml
new file mode 100644
index 0000000..3f2c255
--- /dev/null
+++ b/wearable/tests/res/layout/wearable_recycler_view_basic.xml
@@ -0,0 +1,24 @@
+<?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.
+ -->
+
+<android.support.wearable.view.WearableRecyclerView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/wrv">
+
+</android.support.wearable.view.WearableRecyclerView>
diff --git a/wearable/tests/src/android/support/wearable/view/BoxInsetLayoutTest.java b/wearable/tests/src/android/support/wearable/view/BoxInsetLayoutTest.java
index 98fa0f0..16d92d11 100644
--- a/wearable/tests/src/android/support/wearable/view/BoxInsetLayoutTest.java
+++ b/wearable/tests/src/android/support/wearable/view/BoxInsetLayoutTest.java
@@ -359,6 +359,6 @@
}
private abstract class ViewFetchingRunnable implements Runnable {
- Map<Integer, View> mIdViewMap = new HashMap();
+ Map<Integer, View> mIdViewMap = new HashMap<>();
}
}
diff --git a/wearable/tests/src/android/support/wearable/view/CurvedOffsettingHelperTest.java b/wearable/tests/src/android/support/wearable/view/CurvedOffsettingHelperTest.java
new file mode 100644
index 0000000..69d86ce
--- /dev/null
+++ b/wearable/tests/src/android/support/wearable/view/CurvedOffsettingHelperTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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.wearable.view;
+
+import static junit.framework.Assert.assertEquals;
+
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.wearable.test.R;
+import android.support.wearable.view.util.WakeLockRule;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class CurvedOffsettingHelperTest {
+
+ @Rule
+ public final WakeLockRule wakeLock = new WakeLockRule();
+
+ @Rule
+ public final ActivityTestRule<WearableRecyclerViewTestActivity> mActivityRule =
+ new ActivityTestRule<>(WearableRecyclerViewTestActivity.class, true, true);
+
+ CurvedOffsettingHelper mCurvedOffsettingHelperUnderTest;
+
+ @Before
+ public void setUp() throws Throwable {
+ MockitoAnnotations.initMocks(this);
+ mCurvedOffsettingHelperUnderTest = new CurvedOffsettingHelper();
+ }
+
+ @Test
+ public void testOffsetting() throws Throwable {
+ ViewFetchingRunnable customRunnable = new ViewFetchingRunnable(){
+ @Override
+ public void run() {
+ WearableRecyclerView wrv =
+ (WearableRecyclerView) mActivityRule.getActivity().findViewById(R.id.wrv);
+ wrv.setLayoutParams(new FrameLayout.LayoutParams(390, 390));
+ wrv.invalidate();
+ mIdViewMap.put(R.id.wrv, wrv);
+ }
+ };
+ mActivityRule.runOnUiThread(customRunnable);
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ WearableRecyclerView wrv = (WearableRecyclerView) customRunnable.mIdViewMap.get(R.id.wrv);
+ int offset = wrv.getResources().getDimensionPixelSize(R.dimen.wrv_curve_default_x_offset);
+ View child1 = wrv.getChildAt(0);
+ View child2 = wrv.getChildAt(1);
+ View child3 = wrv.getChildAt(2);
+ View child4 = wrv.getChildAt(3);
+ View child5 = wrv.getChildAt(4);
+
+ // When the child is updated by the curved offsetting helper
+ if (child1 != null) {
+ mCurvedOffsettingHelperUnderTest.updateChild(child1, wrv);
+ }
+ if (child2 != null) {
+ mCurvedOffsettingHelperUnderTest.updateChild(child2, wrv);
+ }
+ if (child3 != null) {
+ mCurvedOffsettingHelperUnderTest.updateChild(child3, wrv);
+ }
+ if (child4 != null) {
+ mCurvedOffsettingHelperUnderTest.updateChild(child4, wrv);
+ }
+ if (child5 != null) {
+ mCurvedOffsettingHelperUnderTest.updateChild(child5, wrv);
+ }
+ if (wrv.getResources().getConfiguration().isScreenRound()) {
+ // Then the left position and the translation of the child is modified if the screen is
+ // round
+ if (child1 != null) {
+ assertEquals(162 - offset, child1.getLeft(), 1);
+ assertEquals(-9.5, child1.getTranslationY(), 1);
+ }
+ if (child2 != null) {
+ assertEquals(129 - offset, child2.getLeft(), 1);
+ assertEquals(-16.7, child2.getTranslationY(), 1);
+ }
+ if (child3 != null) {
+ assertEquals(99 - offset, child3.getLeft(), 1);
+ assertEquals(-19.9, child3.getTranslationY(), 1);
+ }
+ if (child4 != null) {
+ assertEquals(76 - offset, child4.getLeft(), 1);
+ assertEquals(-17.9, child4.getTranslationY(), 1);
+ }
+ if (child5 != null) {
+ assertEquals(59 - offset, child5.getLeft(), 1);
+ assertEquals(-13, child5.getTranslationY(), 1);
+ }
+ } else {
+ // Then the child is not modified if the screen is not round.
+ if (child1 != null) {
+ assertEquals(0, child1.getLeft());
+ assertEquals(0.0f, child1.getTranslationY());
+ }
+ if (child2 != null) {
+ assertEquals(0, child2.getLeft());
+ assertEquals(0.0f, child2.getTranslationY());
+ }
+ if (child3 != null) {
+ assertEquals(0, child3.getLeft());
+ assertEquals(0.0f, child3.getTranslationY());
+ }
+ if (child4 != null) {
+ assertEquals(0, child4.getLeft());
+ assertEquals(0.0f, child4.getTranslationY());
+ }
+ if (child5 != null) {
+ assertEquals(0, child5.getLeft());
+ assertEquals(0.0f, child5.getTranslationY());
+ }
+ }
+ }
+
+ private abstract class ViewFetchingRunnable implements Runnable {
+ Map<Integer, View> mIdViewMap = new HashMap();
+ }
+}
diff --git a/wearable/tests/src/android/support/wearable/view/ScrollManagerTest.java b/wearable/tests/src/android/support/wearable/view/ScrollManagerTest.java
new file mode 100644
index 0000000..73b2bd0
--- /dev/null
+++ b/wearable/tests/src/android/support/wearable/view/ScrollManagerTest.java
@@ -0,0 +1,202 @@
+/*
+ * 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.wearable.view;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import static java.lang.Math.cos;
+import static java.lang.Math.sin;
+
+import android.os.SystemClock;
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.wearable.view.util.WakeLockRule;
+import android.view.MotionEvent;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class ScrollManagerTest {
+ private static final int TEST_WIDTH = 400;
+ private static final int TEST_HEIGHT = 400;
+ private static final int STEP_COUNT = 300;
+
+ private static final int EXPECTED_SCROLLS_FOR_STRAIGHT_GESTURE = 36;
+ private static final int EXPECTED_SCROLLS_FOR_CIRCULAR_GESTURE = 199;
+
+ @Rule
+ public final WakeLockRule wakeLock = new WakeLockRule();
+
+ @Rule
+ public final ActivityTestRule<WearableRecyclerViewTestActivity> mActivityRule =
+ new ActivityTestRule<>(WearableRecyclerViewTestActivity.class, true, true);
+
+ @Mock
+ WearableRecyclerView mMockWearableRecyclerView;
+
+ ScrollManager mScrollManagerUnderTest;
+
+ @Before
+ public void setUp() throws Throwable {
+ MockitoAnnotations.initMocks(this);
+ mScrollManagerUnderTest = new ScrollManager();
+ mScrollManagerUnderTest.setRecyclerView(mMockWearableRecyclerView, TEST_WIDTH, TEST_HEIGHT);
+ }
+
+ @Test
+ public void testStraightUpScrollingGestureLeft() throws Throwable {
+ // Pretend to scroll in a straight line from center left to upper left
+ scroll(mScrollManagerUnderTest, 30, 30, 200, 150);
+ // The scroll manager should require the recycler view to scroll up and only up
+ verify(mMockWearableRecyclerView, times(EXPECTED_SCROLLS_FOR_STRAIGHT_GESTURE))
+ .scrollBy(0, 1);
+ }
+
+ @Test
+ public void testStraightDownScrollingGestureLeft() throws Throwable {
+ // Pretend to scroll in a straight line upper left to center left
+ scroll(mScrollManagerUnderTest, 30, 30, 150, 200);
+ // The scroll manager should require the recycler view to scroll down and only down
+ verify(mMockWearableRecyclerView, times(EXPECTED_SCROLLS_FOR_STRAIGHT_GESTURE))
+ .scrollBy(0, -1);
+ }
+
+ @Test
+ public void testStraightUpScrollingGestureRight() throws Throwable {
+ // Pretend to scroll in a straight line from center right to upper right
+ scroll(mScrollManagerUnderTest, 370, 370, 200, 150);
+ // The scroll manager should require the recycler view to scroll down and only down
+ verify(mMockWearableRecyclerView, times(EXPECTED_SCROLLS_FOR_STRAIGHT_GESTURE))
+ .scrollBy(0, -1);
+ }
+
+ @Test
+ public void testStraightDownScrollingGestureRight() throws Throwable {
+ // Pretend to scroll in a straight line upper right to center right
+ scroll(mScrollManagerUnderTest, 370, 370, 150, 200);
+ // The scroll manager should require the recycler view to scroll up and only up
+ verify(mMockWearableRecyclerView, times(EXPECTED_SCROLLS_FOR_STRAIGHT_GESTURE))
+ .scrollBy(0, 1);
+ }
+
+ @Test
+ public void testCircularScrollingGestureLeft() throws Throwable {
+ // Pretend to scroll in an arch from center left to center right
+ scrollOnArch(mScrollManagerUnderTest, 30, 200, 180.0f);
+ // The scroll manager should never reverse the scroll direction and scroll up
+ verify(mMockWearableRecyclerView, times(EXPECTED_SCROLLS_FOR_CIRCULAR_GESTURE))
+ .scrollBy(0, 1);
+ }
+
+ @Test
+ public void testCircularScrollingGestureRight() throws Throwable {
+ // Pretend to scroll in an arch from center left to center right
+ scrollOnArch(mScrollManagerUnderTest, 370, 200, -180.0f);
+ // The scroll manager should never reverse the scroll direction and scroll down.
+ verify(mMockWearableRecyclerView, times(EXPECTED_SCROLLS_FOR_CIRCULAR_GESTURE))
+ .scrollBy(0, -1);
+ }
+
+ private static void scroll(ScrollManager scrollManager, float fromX, float toX, float fromY,
+ float toY) {
+ long downTime = SystemClock.uptimeMillis();
+ long eventTime = SystemClock.uptimeMillis();
+
+ float y = fromY;
+ float x = fromX;
+
+ float yStep = (toY - fromY) / STEP_COUNT;
+ float xStep = (toX - fromX) / STEP_COUNT;
+
+ MotionEvent event = MotionEvent.obtain(downTime, eventTime,
+ MotionEvent.ACTION_DOWN, x, y, 0);
+ scrollManager.onTouchEvent(event);
+ for (int i = 0; i < STEP_COUNT; ++i) {
+ y += yStep;
+ x += xStep;
+ eventTime = SystemClock.uptimeMillis();
+ event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 0);
+ scrollManager.onTouchEvent(event);
+ }
+
+ eventTime = SystemClock.uptimeMillis();
+ event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
+ scrollManager.onTouchEvent(event);
+ }
+
+ private static void scrollOnArch(ScrollManager scrollManager, float fromX, float fromY,
+ float deltaAngle) {
+ long downTime = SystemClock.uptimeMillis();
+ long eventTime = SystemClock.uptimeMillis();
+
+ float stepAngle = deltaAngle / STEP_COUNT;
+ double relativeX = fromX - (TEST_WIDTH / 2);
+ double relativeY = fromY - (TEST_HEIGHT / 2);
+ float radius = (float) Math.sqrt(relativeX * relativeX + relativeY * relativeY);
+ float angle = getAngle(fromX, fromY, TEST_WIDTH, TEST_HEIGHT);
+
+ float y = fromY;
+ float x = fromX;
+
+ MotionEvent event = MotionEvent.obtain(downTime, eventTime,
+ MotionEvent.ACTION_DOWN, x, y, 0);
+ scrollManager.onTouchEvent(event);
+ for (int i = 0; i < STEP_COUNT; ++i) {
+ angle += stepAngle;
+ x = getX(angle, radius, TEST_WIDTH);
+ y = getY(angle, radius, TEST_HEIGHT);
+ eventTime = SystemClock.uptimeMillis();
+ event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 0);
+ scrollManager.onTouchEvent(event);
+ }
+
+ eventTime = SystemClock.uptimeMillis();
+ event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
+ scrollManager.onTouchEvent(event);
+ }
+
+ private static float getX(double angle, double radius, double viewWidth) {
+ double radianAngle = Math.toRadians(angle - 90);
+ double relativeX = cos(radianAngle) * radius;
+ return (float) (relativeX + (viewWidth / 2));
+ }
+
+ private static float getY(double angle, double radius, double viewHeight) {
+ double radianAngle = Math.toRadians(angle - 90);
+ double relativeY = sin(radianAngle) * radius;
+ return (float) (relativeY + (viewHeight / 2));
+ }
+
+ private static float getAngle(double x, double y, double viewWidth, double viewHeight) {
+ double relativeX = x - (viewWidth / 2);
+ double relativeY = y - (viewHeight / 2);
+ double rowAngle = Math.atan2(relativeX, relativeY);
+ double angle = -Math.toDegrees(rowAngle) - 180;
+ if (angle < 0) {
+ angle += 360;
+ }
+ return (float) angle;
+ }
+}
diff --git a/wearable/tests/src/android/support/wearable/view/SwipeDismissFrameLayoutTest.java b/wearable/tests/src/android/support/wearable/view/SwipeDismissFrameLayoutTest.java
index 3b0ae41..b595138 100644
--- a/wearable/tests/src/android/support/wearable/view/SwipeDismissFrameLayoutTest.java
+++ b/wearable/tests/src/android/support/wearable/view/SwipeDismissFrameLayoutTest.java
@@ -218,8 +218,7 @@
@SmallTest
public void testSwipeDoesNotDismissViewIfStartsInWrongPosition() {
// GIVEN a freshly setup SwipeDismissFrameLayout with dismiss turned on, but only for an
- // inner
- // circle.
+ // inner circle.
setUpSwipeableRegion();
// WHEN we perform a swipe to dismiss from the left edge of the screen.
onView(withId(R.id.swipe_dismiss_root)).perform(swipeRightFromLeftEdge());
@@ -231,8 +230,7 @@
@SmallTest
public void testSwipeDoesDismissViewIfStartsInRightPosition() {
// GIVEN a freshly setup SwipeDismissFrameLayout with dismiss turned on, but only for an
- // inner
- // circle.
+ // inner circle.
setUpSwipeableRegion();
// WHEN we perform a swipe to dismiss from the center of the screen.
onView(withId(R.id.swipe_dismiss_root)).perform(swipeRightFromCenter());
diff --git a/wearable/tests/src/android/support/wearable/view/WearableRecyclerViewTest.java b/wearable/tests/src/android/support/wearable/view/WearableRecyclerViewTest.java
new file mode 100644
index 0000000..82a731d
--- /dev/null
+++ b/wearable/tests/src/android/support/wearable/view/WearableRecyclerViewTest.java
@@ -0,0 +1,219 @@
+/*
+ * 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.wearable.view;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.wearable.view.util.AsyncViewActions.waitForMatchingView;
+import static android.support.wearable.view.util.MoreViewAssertions.withNoVerticalScrollOffset;
+import static android.support.wearable.view.util.MoreViewAssertions.withPositiveVerticalScrollOffset;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+
+import static org.hamcrest.Matchers.allOf;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.verify;
+
+import android.app.Activity;
+import android.support.annotation.IdRes;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.espresso.ViewAction;
+import android.support.test.espresso.action.GeneralLocation;
+import android.support.test.espresso.action.GeneralSwipeAction;
+import android.support.test.espresso.action.Press;
+import android.support.test.espresso.action.Swipe;
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.wearable.test.R;
+import android.support.wearable.view.util.WakeLockRule;
+import android.view.View;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class WearableRecyclerViewTest {
+
+ private static final long MAX_WAIT_TIME = 10000;
+ @Mock
+ WearableRecyclerView.OffsettingHelper mMockOffsettingHelper;
+
+ @Rule
+ public final WakeLockRule wakeLock = new WakeLockRule();
+
+ @Rule
+ public final ActivityTestRule<WearableRecyclerViewTestActivity> mActivityRule =
+ new ActivityTestRule<>(WearableRecyclerViewTestActivity.class, true, true);
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testCaseInitState() {
+ WearableRecyclerView wrv = new WearableRecyclerView(mActivityRule.getActivity());
+
+ assertFalse(wrv.getEdgeItemsCenteringEnabled());
+ assertFalse(wrv.isCircularScrollingGestureEnabled());
+ assertNull(wrv.getOffsettingHelper());
+ assertEquals(1.0f, wrv.getBezelWidthFraction());
+ assertEquals(180.0f, wrv.getScrollDegreesPerScreen());
+ }
+
+ @Test
+ public void testEdgeItemsCenteringOnAndOff() throws Throwable {
+ mActivityRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ WearableRecyclerView wrv =
+ (WearableRecyclerView) mActivityRule.getActivity().findViewById(R.id.wrv);
+ wrv.setEdgeItemsCenteringEnabled(true);
+ }
+ });
+
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ mActivityRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ WearableRecyclerView wrv =
+ (WearableRecyclerView) mActivityRule.getActivity().findViewById(R.id.wrv);
+ View child = wrv.getChildAt(0);
+ assertNotNull("child", child);
+ assertEquals((wrv.getHeight() - child.getHeight()) / 2, child.getTop());
+ }
+ });
+
+ mActivityRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ WearableRecyclerView wrv =
+ (WearableRecyclerView) mActivityRule.getActivity().findViewById(R.id.wrv);
+ wrv.setEdgeItemsCenteringEnabled(false);
+ }
+ });
+
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ mActivityRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ WearableRecyclerView wrv =
+ (WearableRecyclerView) mActivityRule.getActivity().findViewById(R.id.wrv);
+ View child = wrv.getChildAt(0);
+ assertNotNull("child", child);
+ assertEquals(0, child.getTop());
+
+ }
+ });
+ }
+
+ @Test
+ public void testCircularScrollingGesture() throws Throwable {
+ onView(withId(R.id.wrv)).perform(swipeDownFromTopRight());
+ assertNotScrolledY(R.id.wrv);
+
+ mActivityRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ WearableRecyclerView wrv =
+ (WearableRecyclerView) mActivityRule.getActivity().findViewById(R.id.wrv);
+ wrv.setCircularScrollingGestureEnabled(true);
+ }
+ });
+
+ onView(withId(R.id.wrv)).perform(swipeDownFromTopRight());
+ assertScrolledY(R.id.wrv);
+ }
+
+ @Test
+ public void testOffsettingHelper() throws Throwable {
+ mActivityRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ WearableRecyclerView wrv =
+ (WearableRecyclerView) mActivityRule.getActivity().findViewById(R.id.wrv);
+ wrv.setOffsettingHelper(mMockOffsettingHelper);
+ }
+ });
+
+ onView(withId(R.id.wrv)).perform(swipeDownFromTopRight());
+ verify(mMockOffsettingHelper, atLeast(1)).updateChild(any(View.class),
+ any(WearableRecyclerView.class));
+
+ }
+
+ @Test
+ public void testCurvedOffsettingHelper() throws Throwable {
+ mActivityRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ WearableRecyclerView wrv =
+ (WearableRecyclerView) mActivityRule.getActivity().findViewById(R.id.wrv);
+ wrv.setOffsettingHelper(new CurvedOffsettingHelper());
+ }
+ });
+
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+ onView(withId(R.id.wrv)).perform(swipeDownFromTopRight());
+
+ mActivityRule.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Activity activity = mActivityRule.getActivity();
+ WearableRecyclerView wrv = (WearableRecyclerView) activity.findViewById(R.id.wrv);
+ if (activity.getResources().getConfiguration().isScreenRound()) {
+ View child = wrv.getChildAt(0);
+ assertTrue(child.getLeft() > 0);
+ } else {
+ for (int i = 0; i < wrv.getChildCount(); i++) {
+ assertEquals(0, wrv.getChildAt(i).getLeft());
+ }
+ }
+ }
+ });
+ }
+
+ private static ViewAction swipeDownFromTopRight() {
+ return new GeneralSwipeAction(
+ Swipe.FAST, GeneralLocation.TOP_RIGHT, GeneralLocation.BOTTOM_RIGHT,
+ Press.FINGER);
+ }
+
+ private void assertScrolledY(@IdRes int layoutId) {
+ onView(withId(layoutId)).perform(waitForMatchingView(
+ allOf(withId(layoutId), withPositiveVerticalScrollOffset()), MAX_WAIT_TIME));
+ }
+
+ private void assertNotScrolledY(@IdRes int layoutId) {
+ onView(withId(layoutId)).perform(waitForMatchingView(
+ allOf(withId(layoutId), withNoVerticalScrollOffset()), MAX_WAIT_TIME));
+ }
+}
diff --git a/wearable/tests/src/android/support/wearable/view/WearableRecyclerViewTestActivity.java b/wearable/tests/src/android/support/wearable/view/WearableRecyclerViewTestActivity.java
new file mode 100644
index 0000000..1c4c8be
--- /dev/null
+++ b/wearable/tests/src/android/support/wearable/view/WearableRecyclerViewTestActivity.java
@@ -0,0 +1,63 @@
+/*
+ * 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.wearable.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.v7.widget.RecyclerView;
+import android.support.wearable.test.R;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+public class WearableRecyclerViewTestActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.wearable_recycler_view_basic);
+ WearableRecyclerView wrv =
+ (WearableRecyclerView) findViewById(android.support.wearable.test.R.id.wrv);
+ wrv.setAdapter(new TestAdapter());
+ }
+
+ private class ViewHolder extends RecyclerView.ViewHolder {
+ TextView mView;
+ ViewHolder(TextView itemView) {
+ super(itemView);
+ mView = itemView;
+ }
+ }
+
+ private class TestAdapter extends WearableRecyclerView.Adapter<ViewHolder> {
+
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ TextView view = new TextView(parent.getContext());
+ return new ViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder holder, int position) {
+ holder.mView.setText("holder at position " + position);
+ holder.mView.setTag(position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return 100;
+ }
+ }
+}
diff --git a/wearable/tests/src/android/support/wearable/view/util/MoreViewAssertions.java b/wearable/tests/src/android/support/wearable/view/util/MoreViewAssertions.java
index 929593a..79586ea 100644
--- a/wearable/tests/src/android/support/wearable/view/util/MoreViewAssertions.java
+++ b/wearable/tests/src/android/support/wearable/view/util/MoreViewAssertions.java
@@ -21,7 +21,7 @@
import android.support.test.espresso.NoMatchingViewException;
import android.support.test.espresso.ViewAssertion;
import android.support.test.espresso.util.HumanReadables;
-import android.util.Log;
+import android.support.wearable.view.WearableRecyclerView;
import android.view.View;
import org.hamcrest.Description;
@@ -30,13 +30,10 @@
public class MoreViewAssertions {
- public static final String TAG = "bilt";
-
public static ViewAssertion left(final Matcher<Integer> matcher) {
return new ViewAssertion() {
@Override
public void check(View view, NoMatchingViewException noViewException) {
- Log.d(TAG, "l: " + view.getLeft());
assertThat("View left: " + HumanReadables.describe(view), view.getLeft(), matcher);
}
};
@@ -46,7 +43,6 @@
return new ViewAssertion() {
@Override
public void check(View view, NoMatchingViewException noViewException) {
- Log.d(TAG, "t: " + view.getPaddingTop());
assertThat("View top: " + HumanReadables.describe(view), ((double) view.getTop()),
matcher);
}
@@ -57,7 +53,6 @@
return new ViewAssertion() {
@Override
public void check(View view, NoMatchingViewException noViewException) {
- Log.d(TAG, "t: " + view.getPaddingTop());
assertThat("View top: " + HumanReadables.describe(view), view.getTop(), matcher);
}
};
@@ -67,7 +62,6 @@
return new ViewAssertion() {
@Override
public void check(View view, NoMatchingViewException noViewException) {
- Log.d(TAG, "r: " + view.getPaddingRight());
assertThat("View right: " + HumanReadables.describe(view), view.getRight(),
matcher);
}
@@ -78,7 +72,6 @@
return new ViewAssertion() {
@Override
public void check(View view, NoMatchingViewException noViewException) {
- Log.d(TAG, "b: " + view.getBottom());
assertThat("View bottom: " + HumanReadables.describe(view), view.getBottom(),
matcher);
}
@@ -89,7 +82,6 @@
return new ViewAssertion() {
@Override
public void check(View view, NoMatchingViewException noViewException) {
- Log.d(TAG, "b: " + view.getBottom());
assertThat("View bottom: " + HumanReadables.describe(view), ((double) view
.getBottom()), matcher);
}
@@ -184,4 +176,32 @@
}
};
}
+
+ public static Matcher<WearableRecyclerView> withPositiveVerticalScrollOffset() {
+ return new TypeSafeMatcher<WearableRecyclerView>() {
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("with positive y scroll offset");
+ }
+
+ @Override
+ public boolean matchesSafely(WearableRecyclerView view) {
+ return view.computeVerticalScrollOffset() > 0;
+ }
+ };
+ }
+
+ public static Matcher<WearableRecyclerView> withNoVerticalScrollOffset() {
+ return new TypeSafeMatcher<WearableRecyclerView>() {
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("with no y scroll offset");
+ }
+
+ @Override
+ public boolean matchesSafely(WearableRecyclerView view) {
+ return view.computeVerticalScrollOffset() == 0;
+ }
+ };
+ }
}