Merge "A pass at fixing unchecked javac warnings."
diff --git a/api/25.3.0.txt b/api/25.3.0.txt
index ac4bf65..4bc005c 100644
--- a/api/25.3.0.txt
+++ b/api/25.3.0.txt
@@ -2414,10 +2414,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 +2422,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 +3532,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 +3796,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);
}
diff --git a/api/26.0.0.txt b/api/26.0.0.txt
index 3d77c5b..e8f18a3 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 {
@@ -1589,12 +1679,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 +1706,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 +1737,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 +1757,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 +1773,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 +1789,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 +1808,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 +1829,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 +3026,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 +3034,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 +4144,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 +4408,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);
}
@@ -9023,6 +9125,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 +9134,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 +10793,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 8d12577..a5206fe 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3026,10 +3026,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 +3034,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 +4144,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 +4408,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);
}
@@ -7525,14 +7493,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
diff --git a/build.gradle b/build.gradle
index b3fcda7..954bbe3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -17,14 +17,13 @@
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 +33,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/diff_and_docs.gradle b/buildSrc/diff_and_docs.gradle
index c6dda4f..2a78ae9 100644
--- a/buildSrc/diff_and_docs.gradle
+++ b/buildSrc/diff_and_docs.gradle
@@ -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/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 4844263..f1f6a04 100644
--- a/buildSrc/src/main/groovy/android/support/SupportLibraryPlugin.groovy
+++ b/buildSrc/src/main/groovy/android/support/SupportLibraryPlugin.groovy
@@ -89,8 +89,7 @@
}
// Library projects don't run lint by default, so set up dependency.
- // Disabled temporarily until we switch to Android Gradle Plugin 2.3
- // project.tasks.release.dependsOn project.tasks.lint
+ 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.
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/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/os/UserManagerCompatApi24.java b/compat/api24/android/support/v4/os/UserManagerCompatApi24.java
new file mode 100644
index 0000000..c8ef7c0
--- /dev/null
+++ b/compat/api24/android/support/v4/os/UserManagerCompatApi24.java
@@ -0,0 +1,28 @@
+/*
+ * 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.os;
+
+import android.content.Context;
+import android.os.UserManager;
+import android.support.annotation.RequiresApi;
+
+@RequiresApi(24)
+class UserManagerCompatApi24 {
+ public static boolean isUserUnlocked(Context context) {
+ return context.getSystemService(UserManager.class).isUserUnlocked();
+ }
+}
diff --git a/compat/java/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompat.java b/compat/java/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompat.java
index ce2d612..e2ea863 100644
--- a/compat/java/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompat.java
+++ b/compat/java/android/support/v4/accessibilityservice/AccessibilityServiceInfoCompat.java
@@ -18,7 +18,7 @@
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Build;
@@ -43,7 +43,7 @@
}
}
- @TargetApi(16)
+ @RequiresApi(16)
static class AccessibilityServiceInfoApi16Impl extends AccessibilityServiceInfoBaseImpl {
@Override
public String loadDescription(AccessibilityServiceInfo info, PackageManager pm) {
@@ -51,7 +51,7 @@
}
}
- @TargetApi(18)
+ @RequiresApi(18)
static class AccessibilityServiceInfoApi18Impl
extends AccessibilityServiceInfoApi16Impl {
@Override
diff --git a/compat/java/android/support/v4/app/AppOpsManagerCompat.java b/compat/java/android/support/v4/app/AppOpsManagerCompat.java
index 06da861..d67dbac 100644
--- a/compat/java/android/support/v4/app/AppOpsManagerCompat.java
+++ b/compat/java/android/support/v4/app/AppOpsManagerCompat.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
+import android.support.annotation.RequiresApi;
/**
* Helper for accessing features in android.app.AppOpsManager
@@ -64,6 +65,7 @@
}
}
+ @RequiresApi(23)
private static class AppOpsManager23 extends AppOpsManagerImpl {
AppOpsManager23() {
}
diff --git a/compat/java/android/support/v4/app/NotificationCompat.java b/compat/java/android/support/v4/app/NotificationCompat.java
index 5bc28c1..5d43871 100644
--- a/compat/java/android/support/v4/app/NotificationCompat.java
+++ b/compat/java/android/support/v4/app/NotificationCompat.java
@@ -20,6 +20,7 @@
import static java.lang.annotation.RetentionPolicy.SOURCE;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Notification;
import android.app.PendingIntent;
@@ -1029,6 +1030,7 @@
static {
if (BuildCompat.isAtLeastO()) {
+ //noinspection AndroidLintNewApi
IMPL = new NotificationCompatApi26Impl();
} else if (Build.VERSION.SDK_INT >= 24) {
IMPL = new NotificationCompatApi24Impl();
diff --git a/compat/java/android/support/v4/app/NotificationManagerCompat.java b/compat/java/android/support/v4/app/NotificationManagerCompat.java
index d0b25aa..0cdd765 100644
--- a/compat/java/android/support/v4/app/NotificationManagerCompat.java
+++ b/compat/java/android/support/v4/app/NotificationManagerCompat.java
@@ -16,7 +16,7 @@
package android.support.v4.app;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
@@ -188,7 +188,7 @@
}
}
- @TargetApi(19)
+ @RequiresApi(19)
static class ImplKitKat extends ImplBase {
@Override
public boolean areNotificationsEnabled(Context context,
@@ -197,7 +197,7 @@
}
}
- @TargetApi(24)
+ @RequiresApi(24)
static class ImplApi24 extends ImplKitKat {
@Override
public boolean areNotificationsEnabled(Context context,
diff --git a/compat/java/android/support/v4/app/RemoteInput.java b/compat/java/android/support/v4/app/RemoteInput.java
index 84dde3b..73eb388 100644
--- a/compat/java/android/support/v4/app/RemoteInput.java
+++ b/compat/java/android/support/v4/app/RemoteInput.java
@@ -22,6 +22,7 @@
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
+import android.support.annotation.RequiresApi;
import android.support.annotation.RestrictTo;
import android.util.Log;
@@ -338,6 +339,7 @@
}
}
+ @RequiresApi(16)
static class ImplJellybean implements Impl {
@Override
public Bundle getResultsFromIntent(Intent intent) {
@@ -363,6 +365,7 @@
}
}
+ @RequiresApi(20)
static class ImplApi20 implements Impl {
@Override
public Bundle getResultsFromIntent(Intent intent) {
diff --git a/compat/java/android/support/v4/app/ShareCompat.java b/compat/java/android/support/v4/app/ShareCompat.java
index de481ed..1f1c776 100644
--- a/compat/java/android/support/v4/app/ShareCompat.java
+++ b/compat/java/android/support/v4/app/ShareCompat.java
@@ -16,6 +16,7 @@
package android.support.v4.app;
+import android.support.annotation.RequiresApi;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
@@ -122,6 +123,7 @@
}
}
+ @RequiresApi(14)
static class ShareCompatImplICS extends ShareCompatImplBase {
@Override
public void configureMenuItem(MenuItem item, IntentBuilder shareIntent) {
@@ -137,6 +139,7 @@
}
}
+ @RequiresApi(16)
static class ShareCompatImplJB extends ShareCompatImplICS {
@Override
public String escapeHtml(CharSequence html) {
diff --git a/compat/java/android/support/v4/content/ContentResolverCompat.java b/compat/java/android/support/v4/content/ContentResolverCompat.java
index 7efe79e..1aafc82 100644
--- a/compat/java/android/support/v4/content/ContentResolverCompat.java
+++ b/compat/java/android/support/v4/content/ContentResolverCompat.java
@@ -20,6 +20,7 @@
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
+import android.support.annotation.RequiresApi;
import android.support.v4.os.CancellationSignal;
import android.support.v4.os.OperationCanceledException;
@@ -48,6 +49,7 @@
}
}
+ @RequiresApi(16)
static class ContentResolverCompatImplJB extends ContentResolverCompatImplBase {
@Override
public Cursor query(ContentResolver resolver, Uri uri, String[] projection,
@@ -73,8 +75,7 @@
private static final ContentResolverCompatImpl IMPL;
static {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 16) {
+ if (Build.VERSION.SDK_INT >= 16) {
IMPL = new ContentResolverCompatImplJB();
} else {
IMPL = new ContentResolverCompatImplBase();
diff --git a/compat/java/android/support/v4/content/IntentCompat.java b/compat/java/android/support/v4/content/IntentCompat.java
index d34c914..9cc4fa3 100644
--- a/compat/java/android/support/v4/content/IntentCompat.java
+++ b/compat/java/android/support/v4/content/IntentCompat.java
@@ -50,8 +50,7 @@
private static final IntentCompatBaseImpl IMPL;
static {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 15) {
+ if (Build.VERSION.SDK_INT >= 15) {
IMPL = new IntentCompatApi15Impl();
} else {
IMPL = new IntentCompatBaseImpl();
diff --git a/compat/java/android/support/v4/content/pm/ShortcutInfoCompat.java b/compat/java/android/support/v4/content/pm/ShortcutInfoCompat.java
index 2fe2e92..b6ac319 100644
--- a/compat/java/android/support/v4/content/pm/ShortcutInfoCompat.java
+++ b/compat/java/android/support/v4/content/pm/ShortcutInfoCompat.java
@@ -15,7 +15,7 @@
*/
package android.support.v4.content.pm;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -47,7 +47,7 @@
private ShortcutInfoCompat() { }
- @TargetApi(25)
+ @RequiresApi(25)
ShortcutInfo toShortcutInfo() {
ShortcutInfo.Builder builder = new ShortcutInfo.Builder(mContext, mId)
.setShortLabel(mLabel)
diff --git a/compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java b/compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java
index 2261e86..732a14f 100644
--- a/compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java
+++ b/compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java
@@ -16,6 +16,7 @@
package android.support.v4.content.pm;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -46,8 +47,10 @@
* @return {@code true} if the launcher supports {@link #requestPinShortcut},
* {@code false} otherwise
*/
+ @SuppressLint("NewApi")
public static boolean isRequestPinShortcutSupported(@NonNull Context context) {
if (BuildCompat.isAtLeastO()) {
+ //noinspection AndroidLintNewApi
return context.getSystemService(ShortcutManager.class).isRequestPinShortcutSupported();
}
@@ -82,9 +85,11 @@
* @see IntentSender
* @see android.app.PendingIntent#getIntentSender()
*/
+ @SuppressLint("NewApi")
public static boolean requestPinShortcut(@NonNull final Context context,
@NonNull ShortcutInfoCompat shortcut, @Nullable final IntentSender callback) {
if (BuildCompat.isAtLeastO()) {
+ //noinspection AndroidLintNewApi
return context.getSystemService(ShortcutManager.class).requestPinShortcut(
shortcut.toShortcutInfo(), callback);
}
@@ -125,10 +130,12 @@
* @see Intent#ACTION_CREATE_SHORTCUT
*/
@NonNull
+ @SuppressLint("NewApi")
public static Intent createShortcutResultIntent(@NonNull Context context,
@NonNull ShortcutInfoCompat shortcut) {
Intent result = null;
if (BuildCompat.isAtLeastO()) {
+ //noinspection AndroidLintNewApi
result = context.getSystemService(ShortcutManager.class)
.createShortcutResultIntent(shortcut.toShortcutInfo());
}
diff --git a/compat/java/android/support/v4/graphics/BitmapCompat.java b/compat/java/android/support/v4/graphics/BitmapCompat.java
index e59e717..f417938 100644
--- a/compat/java/android/support/v4/graphics/BitmapCompat.java
+++ b/compat/java/android/support/v4/graphics/BitmapCompat.java
@@ -15,10 +15,9 @@
*/
package android.support.v4.graphics;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.graphics.Bitmap;
import android.os.Build;
-import android.os.Build.VERSION_CODES;
/**
* Helper for accessing features in {@link android.graphics.Bitmap}
@@ -38,7 +37,7 @@
}
}
- @TargetApi(VERSION_CODES.JELLY_BEAN_MR2)
+ @RequiresApi(18)
static class BitmapCompatApi18Impl extends BitmapCompatBaseImpl {
@Override
public boolean hasMipMap(Bitmap bitmap){
@@ -51,7 +50,7 @@
}
}
- @TargetApi(VERSION_CODES.KITKAT)
+ @RequiresApi(19)
static class BitmapCompatApi19Impl extends BitmapCompatApi18Impl {
@Override
public int getAllocationByteCount(Bitmap bitmap) {
@@ -64,10 +63,9 @@
*/
static final BitmapCompatBaseImpl IMPL;
static {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 19) {
+ if (Build.VERSION.SDK_INT >= 19) {
IMPL = new BitmapCompatApi19Impl();
- } else if (version >= 18) {
+ } else if (Build.VERSION.SDK_INT >= 18) {
IMPL = new BitmapCompatApi18Impl();
} else {
IMPL = new BitmapCompatBaseImpl();
diff --git a/compat/java/android/support/v4/graphics/drawable/DrawableCompat.java b/compat/java/android/support/v4/graphics/drawable/DrawableCompat.java
index fa86926..53f43ef 100644
--- a/compat/java/android/support/v4/graphics/drawable/DrawableCompat.java
+++ b/compat/java/android/support/v4/graphics/drawable/DrawableCompat.java
@@ -23,6 +23,7 @@
import android.graphics.drawable.Drawable;
import android.graphics.drawable.DrawableContainer;
import android.graphics.drawable.InsetDrawable;
+import android.os.Build;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -333,14 +334,13 @@
*/
static final DrawableCompatBaseImpl IMPL;
static {
- final int version = android.os.Build.VERSION.SDK_INT;
- if (version >= 23) {
+ if (Build.VERSION.SDK_INT >= 23) {
IMPL = new DrawableCompatApi23Impl();
- } else if (version >= 21) {
+ } else if (Build.VERSION.SDK_INT >= 21) {
IMPL = new DrawableCompatApi21Impl();
- } else if (version >= 19) {
+ } else if (Build.VERSION.SDK_INT >= 19) {
IMPL = new DrawableCompatApi19Impl();
- } else if (version >= 17) {
+ } else if (Build.VERSION.SDK_INT >= 17) {
IMPL = new DrawableCompatApi17Impl();
} else {
IMPL = new DrawableCompatBaseImpl();
diff --git a/compat/java/android/support/v4/hardware/display/DisplayManagerCompat.java b/compat/java/android/support/v4/hardware/display/DisplayManagerCompat.java
index 177c40a..50387e3 100644
--- a/compat/java/android/support/v4/hardware/display/DisplayManagerCompat.java
+++ b/compat/java/android/support/v4/hardware/display/DisplayManagerCompat.java
@@ -17,6 +17,8 @@
package android.support.v4.hardware.display;
import android.content.Context;
+import android.os.Build;
+import android.support.annotation.RequiresApi;
import android.view.Display;
import android.view.WindowManager;
@@ -54,8 +56,7 @@
synchronized (sInstances) {
DisplayManagerCompat instance = sInstances.get(context);
if (instance == null) {
- final int version = android.os.Build.VERSION.SDK_INT;
- if (version >= 17) {
+ if (Build.VERSION.SDK_INT >= 17) {
instance = new JellybeanMr1Impl(context);
} else {
instance = new LegacyImpl(context);
@@ -129,6 +130,7 @@
}
}
+ @RequiresApi(17)
private static class JellybeanMr1Impl extends DisplayManagerCompat {
private final Object mDisplayManagerObj;
diff --git a/compat/java/android/support/v4/hardware/fingerprint/FingerprintManagerCompat.java b/compat/java/android/support/v4/hardware/fingerprint/FingerprintManagerCompat.java
index 26045f7..2065bd3 100644
--- a/compat/java/android/support/v4/hardware/fingerprint/FingerprintManagerCompat.java
+++ b/compat/java/android/support/v4/hardware/fingerprint/FingerprintManagerCompat.java
@@ -21,6 +21,7 @@
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.annotation.RequiresApi;
import android.support.v4.os.CancellationSignal;
import java.security.Signature;
@@ -49,8 +50,7 @@
static final FingerprintManagerCompatImpl IMPL;
static {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 23) {
+ if (Build.VERSION.SDK_INT >= 23) {
IMPL = new Api23FingerprintManagerCompatImpl();
} else {
IMPL = new LegacyFingerprintManagerCompatImpl();
@@ -229,6 +229,7 @@
}
}
+ @RequiresApi(23)
private static class Api23FingerprintManagerCompatImpl implements FingerprintManagerCompatImpl {
public Api23FingerprintManagerCompatImpl() {
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..eecf300 100644
--- a/compat/java/android/support/v4/internal/view/SupportMenuItem.java
+++ b/compat/java/android/support/v4/internal/view/SupportMenuItem.java
@@ -249,4 +249,89 @@
*/
@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.
+ */
+ public 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.
+ */
+ public 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.
+ */
+ public 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.
+ */
+ public 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.
+ */
+ public int getAlphabeticModifiers();
}
\ No newline at end of file
diff --git a/compat/java/android/support/v4/net/TrafficStatsCompat.java b/compat/java/android/support/v4/net/TrafficStatsCompat.java
index 5c76b59..a9cb423 100644
--- a/compat/java/android/support/v4/net/TrafficStatsCompat.java
+++ b/compat/java/android/support/v4/net/TrafficStatsCompat.java
@@ -16,7 +16,7 @@
package android.support.v4.net;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.net.TrafficStats;
import android.os.Build;
import android.os.ParcelFileDescriptor;
@@ -52,7 +52,7 @@
}
}
- @TargetApi(24)
+ @RequiresApi(24)
static class TrafficStatsCompatApi24Impl extends TrafficStatsCompatBaseImpl {
@Override
public void tagDatagramSocket(DatagramSocket socket) throws SocketException {
diff --git a/compat/java/android/support/v4/os/CancellationSignal.java b/compat/java/android/support/v4/os/CancellationSignal.java
index 41bdfe6..8a6a401 100644
--- a/compat/java/android/support/v4/os/CancellationSignal.java
+++ b/compat/java/android/support/v4/os/CancellationSignal.java
@@ -78,7 +78,7 @@
if (listener != null) {
listener.onCancel();
}
- if (obj != null) {
+ if (obj != null && Build.VERSION.SDK_INT >= 16) {
CancellationSignalCompatJellybean.cancel(obj);
}
} finally {
diff --git a/compat/java/android/support/v4/os/EnvironmentCompat.java b/compat/java/android/support/v4/os/EnvironmentCompat.java
index 454065d..9781a8a 100644
--- a/compat/java/android/support/v4/os/EnvironmentCompat.java
+++ b/compat/java/android/support/v4/os/EnvironmentCompat.java
@@ -53,8 +53,7 @@
* {@link Environment#MEDIA_UNMOUNTABLE}.
*/
public static String getStorageState(File path) {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 19) {
+ if (Build.VERSION.SDK_INT >= 19) {
return EnvironmentCompatKitKat.getStorageState(path);
}
diff --git a/compat/java/android/support/v4/os/UserManagerCompat.java b/compat/java/android/support/v4/os/UserManagerCompat.java
index 2321948..d73354f 100644
--- a/compat/java/android/support/v4/os/UserManagerCompat.java
+++ b/compat/java/android/support/v4/os/UserManagerCompat.java
@@ -18,13 +18,13 @@
import android.content.Context;
import android.os.Build;
-import android.os.UserManager;
/**
* Helper for accessing features in {@link android.os.UserManager} in a backwards compatible
* fashion.
*/
public class UserManagerCompat {
+
private UserManagerCompat() {
}
@@ -36,9 +36,10 @@
*/
public static boolean isUserUnlocked(Context context) {
if (Build.VERSION.SDK_INT >= 24) {
- return context.getSystemService(UserManager.class).isUserUnlocked();
+ return UserManagerCompatApi24.isUserUnlocked(context);
} else {
return true;
}
}
+
}
diff --git a/compat/java/android/support/v4/text/ICUCompat.java b/compat/java/android/support/v4/text/ICUCompat.java
index cd26961..d5ad0d6 100644
--- a/compat/java/android/support/v4/text/ICUCompat.java
+++ b/compat/java/android/support/v4/text/ICUCompat.java
@@ -16,7 +16,7 @@
package android.support.v4.text;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.os.Build;
import android.support.annotation.Nullable;
@@ -29,7 +29,7 @@
}
}
- @TargetApi(23)
+ @RequiresApi(21)
static class ICUCompatApi21Impl extends ICUCompatBaseImpl {
@Override
public String maximizeAndGetScript(Locale locale) {
@@ -40,8 +40,7 @@
private static final ICUCompatBaseImpl IMPL;
static {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 21) {
+ if (Build.VERSION.SDK_INT >= 21) {
IMPL = new ICUCompatApi21Impl();
} else {
IMPL = new ICUCompatBaseImpl();
diff --git a/compat/java/android/support/v4/text/TextUtilsCompat.java b/compat/java/android/support/v4/text/TextUtilsCompat.java
index 6acf644..9e190da 100644
--- a/compat/java/android/support/v4/text/TextUtilsCompat.java
+++ b/compat/java/android/support/v4/text/TextUtilsCompat.java
@@ -19,6 +19,7 @@
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.annotation.RequiresApi;
import android.support.v4.view.ViewCompat;
import java.util.Locale;
@@ -102,6 +103,7 @@
}
}
+ @RequiresApi(17)
private static class TextUtilsCompatJellybeanMr1Impl extends TextUtilsCompatImpl {
TextUtilsCompatJellybeanMr1Impl() {
}
@@ -120,8 +122,7 @@
private static final TextUtilsCompatImpl IMPL;
static {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 17) { // JellyBean MR1
+ if (Build.VERSION.SDK_INT >= 17) { // JellyBean MR1
IMPL = new TextUtilsCompatJellybeanMr1Impl();
} else {
IMPL = new TextUtilsCompatImpl();
diff --git a/compat/java/android/support/v4/view/GravityCompat.java b/compat/java/android/support/v4/view/GravityCompat.java
index cfcdd50..8131617 100644
--- a/compat/java/android/support/v4/view/GravityCompat.java
+++ b/compat/java/android/support/v4/view/GravityCompat.java
@@ -17,6 +17,7 @@
package android.support.v4.view;
+import android.support.annotation.RequiresApi;
import android.graphics.Rect;
import android.os.Build;
import android.view.Gravity;
@@ -59,6 +60,7 @@
}
}
+ @RequiresApi(17)
static class GravityCompatImplJellybeanMr1 implements GravityCompatImpl {
@Override
public int getAbsoluteGravity(int gravity, int layoutDirection) {
@@ -86,8 +88,7 @@
static final GravityCompatImpl IMPL;
static {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 17) {
+ if (Build.VERSION.SDK_INT >= 17) {
IMPL = new GravityCompatImplJellybeanMr1();
} else {
IMPL = new GravityCompatImplBase();
diff --git a/compat/java/android/support/v4/view/LayoutInflaterCompat.java b/compat/java/android/support/v4/view/LayoutInflaterCompat.java
index 8ffb9a8..1444b58 100644
--- a/compat/java/android/support/v4/view/LayoutInflaterCompat.java
+++ b/compat/java/android/support/v4/view/LayoutInflaterCompat.java
@@ -137,8 +137,7 @@
static final LayoutInflaterCompatBaseImpl IMPL;
static {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 21) {
+ if (Build.VERSION.SDK_INT >= 21) {
IMPL = new LayoutInflaterCompatApi21Impl();
} else {
IMPL = new LayoutInflaterCompatBaseImpl();
diff --git a/compat/java/android/support/v4/view/MarginLayoutParamsCompat.java b/compat/java/android/support/v4/view/MarginLayoutParamsCompat.java
index 4e5851e..84ad177 100644
--- a/compat/java/android/support/v4/view/MarginLayoutParamsCompat.java
+++ b/compat/java/android/support/v4/view/MarginLayoutParamsCompat.java
@@ -17,6 +17,7 @@
package android.support.v4.view;
+import android.support.annotation.RequiresApi;
import android.os.Build;
import android.view.ViewGroup;
@@ -79,6 +80,7 @@
}
}
+ @RequiresApi(17)
static class MarginLayoutParamsCompatImplJbMr1 implements MarginLayoutParamsCompatImpl {
@Override
@@ -124,8 +126,7 @@
static final MarginLayoutParamsCompatImpl IMPL;
static {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 17) { // jb-mr1
+ if (Build.VERSION.SDK_INT >= 17) { // jb-mr1
IMPL = new MarginLayoutParamsCompatImplJbMr1();
} else {
IMPL = new MarginLayoutParamsCompatImplBase();
diff --git a/compat/java/android/support/v4/view/MenuItemCompat.java b/compat/java/android/support/v4/view/MenuItemCompat.java
index 64d682c..0c5ba63 100644
--- a/compat/java/android/support/v4/view/MenuItemCompat.java
+++ b/compat/java/android/support/v4/view/MenuItemCompat.java
@@ -16,10 +16,12 @@
package android.support.v4.view;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
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,9 +150,32 @@
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;
+ }
}
- @TargetApi(26)
+ @RequiresApi(26)
static class MenuItemCompatApi26Impl extends MenuItemCompatBaseImpl {
@Override
public void setContentDescription(MenuItem item, CharSequence contentDescription) {
@@ -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();
+ }
}
/**
@@ -173,6 +230,7 @@
static final MenuVersionImpl IMPL;
static {
if (BuildCompat.isAtLeastO()) {
+ //noinspection AndroidLintNewApi
IMPL = new MenuItemCompatApi26Impl();
} else {
IMPL = new MenuItemCompatBaseImpl();
@@ -425,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/PointerIconCompat.java b/compat/java/android/support/v4/view/PointerIconCompat.java
index cea4dfb..77cda4f 100644
--- a/compat/java/android/support/v4/view/PointerIconCompat.java
+++ b/compat/java/android/support/v4/view/PointerIconCompat.java
@@ -18,9 +18,11 @@
import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+import android.support.annotation.RequiresApi;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.os.Build;
import android.support.annotation.RestrictTo;
import android.support.v4.os.BuildCompat;
@@ -136,6 +138,7 @@
}
}
+ @RequiresApi(24)
static class Api24PointerIconCompatImpl extends BasePointerIconCompatImpl {
@Override
public Object getSystemIcon(Context context, int style) {
@@ -155,7 +158,7 @@
static final PointerIconCompatImpl IMPL;
static {
- if (BuildCompat.isAtLeastN()) {
+ if (Build.VERSION.SDK_INT >= 24) {
IMPL = new Api24PointerIconCompatImpl();
} else {
IMPL = new BasePointerIconCompatImpl();
diff --git a/compat/java/android/support/v4/view/ScaleGestureDetectorCompat.java b/compat/java/android/support/v4/view/ScaleGestureDetectorCompat.java
index 30d0ca1..9141fb1 100644
--- a/compat/java/android/support/v4/view/ScaleGestureDetectorCompat.java
+++ b/compat/java/android/support/v4/view/ScaleGestureDetectorCompat.java
@@ -16,6 +16,9 @@
package android.support.v4.view;
+import android.os.Build;
+import android.support.annotation.RequiresApi;
+
/**
* Helper for accessing features in <code>ScaleGestureDetector</code> introduced
* after API level 19 (KitKat) in a backwards compatible fashion.
@@ -45,6 +48,7 @@
}
}
+ @RequiresApi(19)
private static class ScaleGestureDetectorCompatKitKatImpl implements ScaleGestureDetectorImpl {
ScaleGestureDetectorCompatKitKatImpl() {
}
@@ -61,8 +65,7 @@
}
static {
- final int version = android.os.Build.VERSION.SDK_INT;
- if (version >= 19) { // KitKat
+ if (Build.VERSION.SDK_INT >= 19) { // KitKat
IMPL = new ScaleGestureDetectorCompatKitKatImpl();
} else {
IMPL = new BaseScaleGestureDetectorImpl();
diff --git a/compat/java/android/support/v4/view/ViewCompat.java b/compat/java/android/support/v4/view/ViewCompat.java
index d792b40..91311be 100644
--- a/compat/java/android/support/v4/view/ViewCompat.java
+++ b/compat/java/android/support/v4/view/ViewCompat.java
@@ -19,7 +19,7 @@
import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
import android.animation.ValueAnimator;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.content.ClipData;
import android.content.Context;
import android.content.res.ColorStateList;
@@ -926,7 +926,7 @@
}
}
- @TargetApi(15)
+ @RequiresApi(15)
static class ViewCompatApi15Impl extends ViewCompatBaseImpl {
@Override
public boolean hasOnClickListeners(View view) {
@@ -934,7 +934,7 @@
}
}
- @TargetApi(16)
+ @RequiresApi(16)
static class ViewCompatApi16Impl extends ViewCompatApi15Impl {
@Override
public boolean hasTransientState(View view) {
@@ -1025,7 +1025,7 @@
}
}
- @TargetApi(17)
+ @RequiresApi(17)
static class ViewCompatApi17Impl extends ViewCompatApi16Impl {
@Override
@@ -1084,7 +1084,7 @@
}
}
- @TargetApi(18)
+ @RequiresApi(18)
static class ViewCompatApi18Impl extends ViewCompatApi17Impl {
@Override
public void setClipBounds(View view, Rect clipBounds) {
@@ -1102,7 +1102,7 @@
}
}
- @TargetApi(19)
+ @RequiresApi(19)
static class ViewCompatApi19Impl extends ViewCompatApi18Impl {
@Override
public int getAccessibilityLiveRegion(View view) {
@@ -1135,7 +1135,7 @@
}
}
- @TargetApi(21)
+ @RequiresApi(21)
static class ViewCompatApi21Impl extends ViewCompatApi19Impl {
private static ThreadLocal<Rect> sThreadLocalRect;
@@ -1390,7 +1390,7 @@
}
}
- @TargetApi(23)
+ @RequiresApi(23)
static class ViewCompatApi23Impl extends ViewCompatApi21Impl {
@Override
public void setScrollIndicators(View view, int indicators) {
@@ -1419,7 +1419,7 @@
}
}
- @TargetApi(24)
+ @RequiresApi(24)
static class ViewCompatApi24Impl extends ViewCompatApi23Impl {
@Override
public void dispatchStartTemporaryDetach(View view) {
@@ -1454,7 +1454,7 @@
}
}
- @TargetApi(26)
+ @RequiresApi(26)
static class ViewCompatApi26Impl extends ViewCompatApi24Impl {
@Override
public void setTooltipText(View view, CharSequence tooltipText) {
@@ -1464,24 +1464,24 @@
static final ViewCompatBaseImpl IMPL;
static {
- final int version = android.os.Build.VERSION.SDK_INT;
if (BuildCompat.isAtLeastO()) {
+ //noinspection AndroidLintNewApi
IMPL = new ViewCompatApi26Impl();
- } else if (version >= 24) {
+ } else if (Build.VERSION.SDK_INT >= 24) {
IMPL = new ViewCompatApi24Impl();
- } else if (version >= 23) {
+ } else if (Build.VERSION.SDK_INT >= 23) {
IMPL = new ViewCompatApi23Impl();
- } else if (version >= 21) {
+ } else if (Build.VERSION.SDK_INT >= 21) {
IMPL = new ViewCompatApi21Impl();
- } else if (version >= 19) {
+ } else if (Build.VERSION.SDK_INT >= 19) {
IMPL = new ViewCompatApi19Impl();
- } else if (version >= 18) {
+ } else if (Build.VERSION.SDK_INT >= 18) {
IMPL = new ViewCompatApi18Impl();
- } else if (version >= 17) {
+ } else if (Build.VERSION.SDK_INT >= 17) {
IMPL = new ViewCompatApi17Impl();
- } else if (version >= 16) {
+ } else if (Build.VERSION.SDK_INT >= 16) {
IMPL = new ViewCompatApi16Impl();
- } else if (version >= 15) {
+ } else if (Build.VERSION.SDK_INT >= 15) {
IMPL = new ViewCompatApi15Impl();
} else {
IMPL = new ViewCompatBaseImpl();
diff --git a/compat/java/android/support/v4/view/ViewGroupCompat.java b/compat/java/android/support/v4/view/ViewGroupCompat.java
index 39046a3..11706b0 100644
--- a/compat/java/android/support/v4/view/ViewGroupCompat.java
+++ b/compat/java/android/support/v4/view/ViewGroupCompat.java
@@ -101,10 +101,9 @@
static final ViewGroupCompatBaseImpl IMPL;
static {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 21) {
+ if (Build.VERSION.SDK_INT >= 21) {
IMPL = new ViewGroupCompatApi21Impl();
- } else if (version >= 18) {
+ } else if (Build.VERSION.SDK_INT >= 18) {
IMPL = new ViewGroupCompatApi18Impl();
} else {
IMPL = new ViewGroupCompatBaseImpl();
diff --git a/compat/java/android/support/v4/view/ViewParentCompat.java b/compat/java/android/support/v4/view/ViewParentCompat.java
index 53ff8dd..f54a693 100644
--- a/compat/java/android/support/v4/view/ViewParentCompat.java
+++ b/compat/java/android/support/v4/view/ViewParentCompat.java
@@ -190,10 +190,9 @@
static final ViewParentCompatBaseImpl IMPL;
static {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 21) {
+ if (Build.VERSION.SDK_INT >= 21) {
IMPL = new ViewParentCompatApi21Impl();
- } else if (version >= 19) {
+ } else if (Build.VERSION.SDK_INT >= 19) {
IMPL = new ViewParentCompatApi19Impl();
} else {
IMPL = new ViewParentCompatBaseImpl();
diff --git a/compat/java/android/support/v4/view/ViewPropertyAnimatorCompat.java b/compat/java/android/support/v4/view/ViewPropertyAnimatorCompat.java
index 117a4d6..48e6348 100644
--- a/compat/java/android/support/v4/view/ViewPropertyAnimatorCompat.java
+++ b/compat/java/android/support/v4/view/ViewPropertyAnimatorCompat.java
@@ -15,7 +15,7 @@
*/
package android.support.v4.view;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.os.Build;
import android.view.View;
import android.view.animation.Interpolator;
@@ -181,7 +181,7 @@
}
}
- @TargetApi(16)
+ @RequiresApi(16)
static class ViewPropertyAnimatorCompatApi16Impl extends ViewPropertyAnimatorCompatBaseImpl {
@Override
@@ -205,7 +205,7 @@
}
}
- @TargetApi(18)
+ @RequiresApi(18)
static class ViewPropertyAnimatorCompatApi18Impl extends ViewPropertyAnimatorCompatApi16Impl {
@Override
@@ -214,7 +214,7 @@
}
}
- @TargetApi(19)
+ @RequiresApi(19)
static class ViewPropertyAnimatorCompatApi19Impl extends ViewPropertyAnimatorCompatApi18Impl {
@Override
public void setUpdateListener(ViewPropertyAnimatorCompat vpa, View view,
@@ -223,7 +223,7 @@
}
}
- @TargetApi(21)
+ @RequiresApi(21)
static class ViewPropertyAnimatorCompatApi21Impl extends
ViewPropertyAnimatorCompatApi19Impl {
@Override
diff --git a/compat/java/android/support/v4/view/WindowInsetsCompat.java b/compat/java/android/support/v4/view/WindowInsetsCompat.java
index 79befe9..8d83a2c 100644
--- a/compat/java/android/support/v4/view/WindowInsetsCompat.java
+++ b/compat/java/android/support/v4/view/WindowInsetsCompat.java
@@ -18,6 +18,7 @@
import android.graphics.Rect;
import android.os.Build;
+import android.support.annotation.RequiresApi;
/**
* Describes a set of insets for window content.
@@ -144,6 +145,7 @@
}
}
+ @RequiresApi(20)
private static class WindowInsetsCompatApi20Impl extends WindowInsetsCompatBaseImpl {
WindowInsetsCompatApi20Impl() {
}
@@ -202,6 +204,7 @@
}
}
+ @RequiresApi(21)
private static class WindowInsetsCompatApi21Impl extends WindowInsetsCompatApi20Impl {
WindowInsetsCompatApi21Impl() {
}
@@ -251,10 +254,9 @@
private static final WindowInsetsCompatImpl IMPL;
static {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 21) {
+ if (Build.VERSION.SDK_INT >= 21) {
IMPL = new WindowInsetsCompatApi21Impl();
- } else if (version >= 20) {
+ } else if (Build.VERSION.SDK_INT >= 20) {
IMPL = new WindowInsetsCompatApi20Impl();
} else {
IMPL = new WindowInsetsCompatBaseImpl();
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityEventCompat.java b/compat/java/android/support/v4/view/accessibility/AccessibilityEventCompat.java
index 0941fe6..c06104b 100644
--- a/compat/java/android/support/v4/view/accessibility/AccessibilityEventCompat.java
+++ b/compat/java/android/support/v4/view/accessibility/AccessibilityEventCompat.java
@@ -17,6 +17,7 @@
package android.support.v4.view.accessibility;
import android.os.Build;
+import android.support.annotation.RequiresApi;
import android.view.accessibility.AccessibilityEvent;
/**
@@ -83,6 +84,7 @@
}
}
+ @RequiresApi(14)
static class AccessibilityEventIcsImpl extends AccessibilityEventStubImpl {
@Override
@@ -101,6 +103,7 @@
}
}
+ @RequiresApi(16)
static class AccessibilityEventJellyBeanImpl extends AccessibilityEventIcsImpl {
@Override
public void setMovementGranularity(AccessibilityEvent event, int granularity) {
@@ -123,6 +126,7 @@
}
}
+ @RequiresApi(19)
static class AccessibilityEventKitKatImpl extends AccessibilityEventJellyBeanImpl {
@Override
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityManagerCompat.java b/compat/java/android/support/v4/view/accessibility/AccessibilityManagerCompat.java
index 544091a..b7581cf 100644
--- a/compat/java/android/support/v4/view/accessibility/AccessibilityManagerCompat.java
+++ b/compat/java/android/support/v4/view/accessibility/AccessibilityManagerCompat.java
@@ -18,6 +18,7 @@
import android.accessibilityservice.AccessibilityServiceInfo;
import android.os.Build;
+import android.support.annotation.RequiresApi;
import android.support.v4.view.accessibility.AccessibilityManagerCompatIcs.AccessibilityStateChangeListenerBridge;
import android.support.v4.view.accessibility.AccessibilityManagerCompatIcs.AccessibilityStateChangeListenerWrapper;
import android.support.v4.view.accessibility.AccessibilityManagerCompatKitKat.TouchExplorationStateChangeListenerBridge;
@@ -108,6 +109,7 @@
}
}
+ @RequiresApi(14)
static class AccessibilityManagerIcsImpl extends AccessibilityManagerStubImpl {
@Override
public AccessibilityStateChangeListenerWrapper newAccessibilityStateChangeListener(
@@ -154,6 +156,7 @@
}
}
+ @RequiresApi(19)
static class AccessibilityManagerKitKatImpl extends AccessibilityManagerIcsImpl {
@Override
public TouchExplorationStateChangeListenerWrapper newTouchExplorationStateChangeListener(
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java b/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
index 952b78a..6bd1031 100644
--- a/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
+++ b/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
@@ -18,7 +18,7 @@
import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
@@ -1096,7 +1096,7 @@
}
}
- @TargetApi(16)
+ @RequiresApi(16)
static class AccessibilityNodeInfoApi16Impl extends AccessibilityNodeInfoBaseImpl {
@Override
public AccessibilityNodeInfo obtain(View root, int virtualDescendantId) {
@@ -1164,7 +1164,7 @@
}
}
- @TargetApi(17)
+ @RequiresApi(17)
static class AccessibilityNodeInfoApi17Impl extends AccessibilityNodeInfoApi16Impl {
@Override
@@ -1198,7 +1198,7 @@
}
}
- @TargetApi(18)
+ @RequiresApi(18)
static class AccessibilityNodeInfoApi18Impl extends AccessibilityNodeInfoApi17Impl {
@Override
@@ -1248,7 +1248,7 @@
}
}
- @TargetApi(19)
+ @RequiresApi(19)
static class AccessibilityNodeInfoApi19Impl extends AccessibilityNodeInfoApi18Impl {
private static final String ROLE_DESCRIPTION_KEY =
"AccessibilityNodeInfo.roleDescription";
@@ -1432,7 +1432,7 @@
}
}
- @TargetApi(21)
+ @RequiresApi(21)
static class AccessibilityNodeInfoApi21Impl extends AccessibilityNodeInfoApi19Impl {
@Override
public Object newAccessibilityAction(int actionId, CharSequence label) {
@@ -1526,7 +1526,7 @@
}
}
- @TargetApi(22)
+ @RequiresApi(22)
static class AccessibilityNodeInfoApi22Impl extends AccessibilityNodeInfoApi21Impl {
@Override
public Object getTraversalBefore(AccessibilityNodeInfo info) {
@@ -1561,7 +1561,7 @@
}
}
- @TargetApi(23)
+ @RequiresApi(23)
static class AccessibilityNodeInfoApi23Impl extends AccessibilityNodeInfoApi22Impl {
@Override
public Object getActionScrollToPosition() {
@@ -1609,7 +1609,7 @@
}
}
- @TargetApi(24)
+ @RequiresApi(24)
static class AccessibilityNodeInfoApi24Impl extends AccessibilityNodeInfoApi23Impl {
@Override
public Object getActionSetProgress() {
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityNodeProviderCompat.java b/compat/java/android/support/v4/view/accessibility/AccessibilityNodeProviderCompat.java
index 48f2f5c..c336585 100644
--- a/compat/java/android/support/v4/view/accessibility/AccessibilityNodeProviderCompat.java
+++ b/compat/java/android/support/v4/view/accessibility/AccessibilityNodeProviderCompat.java
@@ -16,7 +16,7 @@
package android.support.v4.view.accessibility;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
@@ -41,7 +41,7 @@
}
}
- @TargetApi(16)
+ @RequiresApi(16)
private static class AccessibilityNodeProviderJellyBeanImpl
extends AccessibilityNodeProviderStubImpl {
AccessibilityNodeProviderJellyBeanImpl() {
@@ -91,7 +91,7 @@
}
}
- @TargetApi(19)
+ @RequiresApi(19)
private static class AccessibilityNodeProviderKitKatImpl
extends AccessibilityNodeProviderStubImpl {
AccessibilityNodeProviderKitKatImpl() {
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityRecordCompat.java b/compat/java/android/support/v4/view/accessibility/AccessibilityRecordCompat.java
index 9d00c58..695be96 100644
--- a/compat/java/android/support/v4/view/accessibility/AccessibilityRecordCompat.java
+++ b/compat/java/android/support/v4/view/accessibility/AccessibilityRecordCompat.java
@@ -18,6 +18,7 @@
import android.os.Build;
import android.os.Parcelable;
+import android.support.annotation.RequiresApi;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
@@ -311,6 +312,7 @@
}
}
+ @RequiresApi(14)
static class AccessibilityRecordIcsImpl extends AccessibilityRecordStubImpl {
@Override
public Object obtain() {
@@ -519,6 +521,7 @@
}
}
+ @RequiresApi(15)
static class AccessibilityRecordIcsMr1Impl extends AccessibilityRecordIcsImpl {
@Override
public int getMaxScrollX(Object record) {
@@ -541,6 +544,7 @@
}
}
+ @RequiresApi(16)
static class AccessibilityRecordJellyBeanImpl extends AccessibilityRecordIcsMr1Impl {
@Override
public void setSource(Object record, View root, int virtualDescendantId) {
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityWindowInfoCompat.java b/compat/java/android/support/v4/view/accessibility/AccessibilityWindowInfoCompat.java
index bec1dd5..b8d90c5 100644
--- a/compat/java/android/support/v4/view/accessibility/AccessibilityWindowInfoCompat.java
+++ b/compat/java/android/support/v4/view/accessibility/AccessibilityWindowInfoCompat.java
@@ -18,6 +18,7 @@
import android.graphics.Rect;
import android.os.Build;
+import android.support.annotation.RequiresApi;
/**
* Helper for accessing {@link android.view.accessibility.AccessibilityWindowInfo}
@@ -128,6 +129,7 @@
}
}
+ @RequiresApi(21)
private static class AccessibilityWindowInfoApi21Impl extends AccessibilityWindowInfoStubImpl {
AccessibilityWindowInfoApi21Impl() {
}
@@ -203,6 +205,7 @@
}
}
+ @RequiresApi(24)
private static class AccessibilityWindowInfoApi24Impl extends AccessibilityWindowInfoApi21Impl {
AccessibilityWindowInfoApi24Impl() {
}
diff --git a/compat/java/android/support/v4/widget/CompoundButtonCompat.java b/compat/java/android/support/v4/widget/CompoundButtonCompat.java
index f52a55c..25d876e 100644
--- a/compat/java/android/support/v4/widget/CompoundButtonCompat.java
+++ b/compat/java/android/support/v4/widget/CompoundButtonCompat.java
@@ -16,7 +16,7 @@
package android.support.v4.widget;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.content.res.ColorStateList;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
@@ -38,10 +38,9 @@
private static final CompoundButtonCompatBaseImpl IMPL;
static {
- final int sdk = Build.VERSION.SDK_INT;
- if (sdk >= 23) {
+ if (Build.VERSION.SDK_INT >= 23) {
IMPL = new CompoundButtonCompatApi23Impl();
- } else if (sdk >= 21) {
+ } else if (Build.VERSION.SDK_INT >= 21) {
IMPL = new CompoundButtonCompatApi21Impl();
} else {
IMPL = new CompoundButtonCompatBaseImpl();
@@ -103,7 +102,7 @@
}
}
- @TargetApi(21)
+ @RequiresApi(21)
static class CompoundButtonCompatApi21Impl extends CompoundButtonCompatBaseImpl {
@Override
public void setButtonTintList(CompoundButton button, ColorStateList tint) {
@@ -126,7 +125,7 @@
}
}
- @TargetApi(23)
+ @RequiresApi(23)
static class CompoundButtonCompatApi23Impl extends CompoundButtonCompatApi21Impl {
@Override
public Drawable getButtonDrawable(CompoundButton button) {
diff --git a/compat/java/android/support/v4/widget/ListPopupWindowCompat.java b/compat/java/android/support/v4/widget/ListPopupWindowCompat.java
index 8d34312..9901f04 100644
--- a/compat/java/android/support/v4/widget/ListPopupWindowCompat.java
+++ b/compat/java/android/support/v4/widget/ListPopupWindowCompat.java
@@ -16,6 +16,8 @@
package android.support.v4.widget;
+import android.support.annotation.RequiresApi;
+import android.os.Build;
import android.view.View;
import android.view.View.OnTouchListener;
@@ -44,6 +46,7 @@
/**
* Interface implementation for devices with at least KitKat APIs.
*/
+ @RequiresApi(19)
static class KitKatListPopupWindowImpl extends BaseListPopupWindowImpl {
@Override
public OnTouchListener createDragToOpenListener(Object listPopupWindow, View src) {
@@ -56,8 +59,7 @@
*/
static final ListPopupWindowImpl IMPL;
static {
- final int version = android.os.Build.VERSION.SDK_INT;
- if (version >= 19) {
+ if (Build.VERSION.SDK_INT >= 19) {
IMPL = new KitKatListPopupWindowImpl();
} else {
IMPL = new BaseListPopupWindowImpl();
diff --git a/compat/java/android/support/v4/widget/PopupMenuCompat.java b/compat/java/android/support/v4/widget/PopupMenuCompat.java
index 3651429..2de7cc8 100644
--- a/compat/java/android/support/v4/widget/PopupMenuCompat.java
+++ b/compat/java/android/support/v4/widget/PopupMenuCompat.java
@@ -16,6 +16,8 @@
package android.support.v4.widget;
+import android.support.annotation.RequiresApi;
+import android.os.Build;
import android.view.View.OnTouchListener;
/**
@@ -43,6 +45,7 @@
/**
* Interface implementation for devices with at least KitKat APIs.
*/
+ @RequiresApi(19)
static class KitKatPopupMenuImpl extends BasePopupMenuImpl {
@Override
public OnTouchListener getDragToOpenListener(Object popupMenu) {
@@ -55,8 +58,7 @@
*/
static final PopupMenuImpl IMPL;
static {
- final int version = android.os.Build.VERSION.SDK_INT;
- if (version >= 19) {
+ if (Build.VERSION.SDK_INT >= 19) {
IMPL = new KitKatPopupMenuImpl();
} else {
IMPL = new BasePopupMenuImpl();
diff --git a/compat/java/android/support/v4/widget/PopupWindowCompat.java b/compat/java/android/support/v4/widget/PopupWindowCompat.java
index 2047662..5018e04 100644
--- a/compat/java/android/support/v4/widget/PopupWindowCompat.java
+++ b/compat/java/android/support/v4/widget/PopupWindowCompat.java
@@ -16,41 +16,29 @@
package android.support.v4.widget;
+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,
@@ -63,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 {
@@ -95,7 +80,6 @@
}
}
- @Override
public int getWindowLayoutType(PopupWindow popupWindow) {
if (!sGetWindowLayoutTypeMethodAttempted) {
try {
@@ -122,62 +106,90 @@
/**
* Interface implementation for devices with at least KitKat APIs.
*/
- static class KitKatPopupWindowImpl extends BasePopupWindowImpl {
+ @RequiresApi(19)
+ 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);
}
}
- static class Api21PopupWindowImpl extends KitKatPopupWindowImpl {
+ @RequiresApi(21)
+ 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;
}
}
- static class Api23PopupWindowImpl extends Api21PopupWindowImpl {
+ @RequiresApi(23)
+ 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 {
- final int version = android.os.Build.VERSION.SDK_INT;
- if (version >= 23) {
- IMPL = new Api23PopupWindowImpl();
- } else if (version >= 21) {
- IMPL = new Api21PopupWindowImpl();
- } else if (version >= 19) {
- IMPL = new KitKatPopupWindowImpl();
+ if (Build.VERSION.SDK_INT >= 23) {
+ IMPL = new PopupWindowCompatApi23Impl();
+ } else if (Build.VERSION.SDK_INT >= 21) {
+ IMPL = new PopupWindowCompatApi21Impl();
+ } else if (Build.VERSION.SDK_INT >= 19) {
+ IMPL = new PopupWindowCompatApi19Impl();
} else {
- IMPL = new BasePopupWindowImpl();
+ IMPL = new PopupWindowCompatBaseImpl();
}
}
@@ -228,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/java/android/support/v4/widget/TextViewCompat.java b/compat/java/android/support/v4/widget/TextViewCompat.java
index f6b759a..dbf8dbd 100644
--- a/compat/java/android/support/v4/widget/TextViewCompat.java
+++ b/compat/java/android/support/v4/widget/TextViewCompat.java
@@ -16,7 +16,7 @@
package android.support.v4.widget;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.DrawableRes;
@@ -135,7 +135,7 @@
}
}
- @TargetApi(16)
+ @RequiresApi(16)
static class TextViewCompatApi16Impl extends TextViewCompatBaseImpl {
@Override
public int getMaxLines(TextView textView) {
@@ -148,7 +148,7 @@
}
}
- @TargetApi(17)
+ @RequiresApi(17)
static class TextViewCompatApi17Impl extends TextViewCompatApi16Impl {
@Override
public void setCompoundDrawablesRelative(@NonNull TextView textView,
@@ -191,7 +191,7 @@
}
}
- @TargetApi(18)
+ @RequiresApi(18)
static class TextViewCompatApi18Impl extends TextViewCompatApi17Impl {
@Override
public void setCompoundDrawablesRelative(@NonNull TextView textView,
@@ -220,7 +220,7 @@
}
}
- @TargetApi(23)
+ @RequiresApi(23)
static class TextViewCompatApi23Impl extends TextViewCompatApi18Impl {
@Override
public void setTextAppearance(@NonNull TextView textView, @StyleRes int resId) {
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/app/NotificationCompatTest.java b/compat/tests/java/android/support/v4/app/NotificationCompatTest.java
index 5b2a79b..3b953ff 100644
--- a/compat/tests/java/android/support/v4/app/NotificationCompatTest.java
+++ b/compat/tests/java/android/support/v4/app/NotificationCompatTest.java
@@ -22,6 +22,7 @@
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import android.annotation.TargetApi;
import android.app.Notification;
import android.content.Context;
import android.support.test.filters.SdkSuppress;
@@ -108,6 +109,7 @@
}
@SdkSuppress(minSdkVersion = 17)
+ @TargetApi(17)
@Test
public void testNotificationWearableExtenderAction_setAllowGeneratedRepliesTrue()
throws Throwable {
@@ -121,6 +123,7 @@
}
@SdkSuppress(minSdkVersion = 17)
+ @TargetApi(17)
@Test
public void testNotificationWearableExtenderAction_setAllowGeneratedRepliesFalse()
throws Throwable {
diff --git a/compat/tests/java/android/support/v4/app/RemoteInputTest.java b/compat/tests/java/android/support/v4/app/RemoteInputTest.java
index 4c3d81b..55d6cca 100644
--- a/compat/tests/java/android/support/v4/app/RemoteInputTest.java
+++ b/compat/tests/java/android/support/v4/app/RemoteInputTest.java
@@ -21,6 +21,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import android.annotation.TargetApi;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
@@ -95,6 +96,7 @@
}
@SdkSuppress(minSdkVersion = 17)
+ @TargetApi(17)
@Test
public void testRemoteInputBuilder_addAndGetDataResultsFromIntent() throws Throwable {
Uri uri = Uri.parse("Some Uri");
@@ -108,6 +110,7 @@
}
@SdkSuppress(minSdkVersion = 17)
+ @TargetApi(17)
@Test
public void testRemoteInputBuilder_addAndGetTextResultsFromIntent() throws Throwable {
CharSequence charSequence = "value doesn't matter";
@@ -123,6 +126,7 @@
}
@SdkSuppress(minSdkVersion = 17)
+ @TargetApi(17)
@Test
public void testRemoteInputBuilder_addAndGetDataAndTextResultsFromIntentDataFirst()
throws Throwable {
@@ -149,6 +153,7 @@
}
@SdkSuppress(minSdkVersion = 17)
+ @TargetApi(17)
@Test
public void testRemoteInputBuilder_addAndGetDataAndTextResultsFromIntentTextFirst()
throws Throwable {
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/core-ui/java/android/support/v4/widget/DrawerLayout.java b/core-ui/java/android/support/v4/widget/DrawerLayout.java
index 8440cda..c3cb8f7 100644
--- a/core-ui/java/android/support/v4/widget/DrawerLayout.java
+++ b/core-ui/java/android/support/v4/widget/DrawerLayout.java
@@ -17,6 +17,7 @@
package android.support.v4.widget;
+import android.support.annotation.RequiresApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
@@ -321,6 +322,7 @@
}
}
+ @RequiresApi(21)
static class DrawerLayoutCompatImplApi21 implements DrawerLayoutCompatImpl {
@Override
public void configureApplyInsets(View drawerLayout) {
@@ -349,8 +351,7 @@
}
static {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 21) {
+ if (Build.VERSION.SDK_INT >= 21) {
IMPL = new DrawerLayoutCompatImplApi21();
} else {
IMPL = new DrawerLayoutCompatImplBase();
diff --git a/core-ui/java/android/support/v4/widget/SlidingPaneLayout.java b/core-ui/java/android/support/v4/widget/SlidingPaneLayout.java
index 82b974c..0e482d7 100644
--- a/core-ui/java/android/support/v4/widget/SlidingPaneLayout.java
+++ b/core-ui/java/android/support/v4/widget/SlidingPaneLayout.java
@@ -16,6 +16,7 @@
package android.support.v4.widget;
+import android.support.annotation.RequiresApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
@@ -197,10 +198,9 @@
static final SlidingPanelLayoutImpl IMPL;
static {
- final int deviceVersion = Build.VERSION.SDK_INT;
- if (deviceVersion >= 17) {
+ if (Build.VERSION.SDK_INT >= 17) {
IMPL = new SlidingPanelLayoutImplJBMR1();
- } else if (deviceVersion >= 16) {
+ } else if (Build.VERSION.SDK_INT >= 16) {
IMPL = new SlidingPanelLayoutImplJB();
} else {
IMPL = new SlidingPanelLayoutImplBase();
@@ -1507,6 +1507,7 @@
}
}
+ @RequiresApi(16)
static class SlidingPanelLayoutImplJB extends SlidingPanelLayoutImplBase {
/*
* Private API hacks! Nasty! Bad!
@@ -1551,6 +1552,7 @@
}
}
+ @RequiresApi(17)
static class SlidingPanelLayoutImplJBMR1 extends SlidingPanelLayoutImplBase {
@Override
public void invalidateChildRegion(SlidingPaneLayout parent, View child) {
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-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/app/NavUtils.java b/core-utils/java/android/support/v4/app/NavUtils.java
index ae1bb10..b5638c5 100644
--- a/core-utils/java/android/support/v4/app/NavUtils.java
+++ b/core-utils/java/android/support/v4/app/NavUtils.java
@@ -16,7 +16,8 @@
package android.support.v4.app;
-import android.annotation.TargetApi;
+import android.os.Build;
+import android.support.annotation.RequiresApi;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
@@ -93,7 +94,7 @@
}
}
- @TargetApi(16)
+ @RequiresApi(16)
static class NavUtilsImplJB extends NavUtilsImplBase {
@Override
@@ -134,8 +135,7 @@
private static final NavUtilsImpl IMPL;
static {
- final int version = android.os.Build.VERSION.SDK_INT;
- if (version >= 16) {
+ if (Build.VERSION.SDK_INT >= 16) {
IMPL = new NavUtilsImplJB();
} else {
IMPL = new NavUtilsImplBase();
diff --git a/core-utils/java/android/support/v4/app/TaskStackBuilder.java b/core-utils/java/android/support/v4/app/TaskStackBuilder.java
index 3d5e1f4..dc9a2dc 100644
--- a/core-utils/java/android/support/v4/app/TaskStackBuilder.java
+++ b/core-utils/java/android/support/v4/app/TaskStackBuilder.java
@@ -16,7 +16,7 @@
package android.support.v4.app;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.ComponentName;
@@ -82,7 +82,7 @@
}
}
- @TargetApi(16)
+ @RequiresApi(16)
static class TaskStackBuilderApi16Impl extends TaskStackBuilderBaseImpl {
@Override
public PendingIntent getPendingIntent(Context context, Intent[] intents, int requestCode,
diff --git a/core-utils/java/android/support/v4/print/PrintHelper.java b/core-utils/java/android/support/v4/print/PrintHelper.java
index 87899e2..fb8bc12 100644
--- a/core-utils/java/android/support/v4/print/PrintHelper.java
+++ b/core-utils/java/android/support/v4/print/PrintHelper.java
@@ -16,6 +16,7 @@
package android.support.v4.print;
+import android.support.annotation.RequiresApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
@@ -79,11 +80,8 @@
* @return True if printing is supported.
*/
public static boolean systemSupportsPrint() {
- if (Build.VERSION.SDK_INT >= 19) {
- // Supported on Android 4.4 or later.
- return true;
- }
- return false;
+ // Supported on Android 4.4 or later.
+ return Build.VERSION.SDK_INT >= 19;
}
/**
@@ -154,6 +152,7 @@
/**
* Generic implementation for KitKat to Api24
*/
+ @RequiresApi(19)
private static class PrintHelperImpl<RealHelper extends PrintHelperKitkat>
implements PrintHelperVersionImpl {
private final RealHelper mPrintHelper;
@@ -226,6 +225,7 @@
/**
* Implementation used on KitKat
*/
+ @RequiresApi(19)
private static final class PrintHelperKitkatImpl extends PrintHelperImpl<PrintHelperKitkat> {
PrintHelperKitkatImpl(Context context) {
super(new PrintHelperKitkat(context));
@@ -235,6 +235,7 @@
/**
* Implementation used on Api20 to Api22
*/
+ @RequiresApi(20)
private static final class PrintHelperApi20Impl extends PrintHelperImpl<PrintHelperApi20> {
PrintHelperApi20Impl(Context context) {
super(new PrintHelperApi20(context));
@@ -244,6 +245,7 @@
/**
* Implementation used on Api23
*/
+ @RequiresApi(23)
private static final class PrintHelperApi23Impl extends PrintHelperImpl<PrintHelperApi23> {
PrintHelperApi23Impl(Context context) {
super(new PrintHelperApi23(context));
@@ -254,6 +256,7 @@
/**
* Implementation used on Api24 and above
*/
+ @RequiresApi(24)
private static final class PrintHelperApi24Impl extends PrintHelperImpl<PrintHelperApi24> {
PrintHelperApi24Impl(Context context) {
super(new PrintHelperApi24(context));
@@ -267,17 +270,16 @@
* @return the <code>PrintHelper</code> to support printing images.
*/
public PrintHelper(Context context) {
- if (systemSupportsPrint()) {
- if (Build.VERSION.SDK_INT >= 24) {
- mImpl = new PrintHelperApi24Impl(context);
- } else if (Build.VERSION.SDK_INT >= 23) {
- mImpl = new PrintHelperApi23Impl(context);
- } else if (Build.VERSION.SDK_INT >= 20) {
- mImpl = new PrintHelperApi20Impl(context);
- } else {
- mImpl = new PrintHelperKitkatImpl(context);
- }
+ if (Build.VERSION.SDK_INT >= 24) {
+ mImpl = new PrintHelperApi24Impl(context);
+ } else if (Build.VERSION.SDK_INT >= 23) {
+ mImpl = new PrintHelperApi23Impl(context);
+ } else if (Build.VERSION.SDK_INT >= 20) {
+ mImpl = new PrintHelperApi20Impl(context);
+ } else if (Build.VERSION.SDK_INT >= 19){
+ mImpl = new PrintHelperKitkatImpl(context);
} else {
+ // System does not support printing.
mImpl = new PrintHelperStubImpl();
}
}
diff --git a/core-utils/java/android/support/v4/provider/DocumentFile.java b/core-utils/java/android/support/v4/provider/DocumentFile.java
index c573db0..2d1550d 100644
--- a/core-utils/java/android/support/v4/provider/DocumentFile.java
+++ b/core-utils/java/android/support/v4/provider/DocumentFile.java
@@ -107,8 +107,7 @@
* {@link Intent#ACTION_CREATE_DOCUMENT} request.
*/
public static DocumentFile fromSingleUri(Context context, Uri singleUri) {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 19) {
+ if (Build.VERSION.SDK_INT >= 19) {
return new SingleDocumentFile(null, context, singleUri);
} else {
return null;
@@ -125,8 +124,7 @@
* {@link Intent#ACTION_OPEN_DOCUMENT_TREE} request.
*/
public static DocumentFile fromTreeUri(Context context, Uri treeUri) {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 21) {
+ if (Build.VERSION.SDK_INT >= 21) {
return new TreeDocumentFile(null, context,
DocumentsContractApi21.prepareTreeUri(treeUri));
} else {
@@ -139,8 +137,7 @@
* {@link android.provider.DocumentsProvider}.
*/
public static boolean isDocumentUri(Context context, Uri uri) {
- final int version = Build.VERSION.SDK_INT;
- if (version >= 19) {
+ if (Build.VERSION.SDK_INT >= 19) {
return DocumentsContractApi19.isDocumentUri(context, uri);
} else {
return false;
diff --git a/core-utils/java/android/support/v4/provider/SingleDocumentFile.java b/core-utils/java/android/support/v4/provider/SingleDocumentFile.java
index 3a4ccf2..77c4e49 100644
--- a/core-utils/java/android/support/v4/provider/SingleDocumentFile.java
+++ b/core-utils/java/android/support/v4/provider/SingleDocumentFile.java
@@ -18,8 +18,9 @@
import android.content.Context;
import android.net.Uri;
-import android.support.v4.provider.DocumentsContractApi19;
+import android.support.annotation.RequiresApi;
+@RequiresApi(19)
class SingleDocumentFile extends DocumentFile {
private Context mContext;
private Uri mUri;
diff --git a/core-utils/java/android/support/v4/provider/TreeDocumentFile.java b/core-utils/java/android/support/v4/provider/TreeDocumentFile.java
index 02975bd..cb8979d 100644
--- a/core-utils/java/android/support/v4/provider/TreeDocumentFile.java
+++ b/core-utils/java/android/support/v4/provider/TreeDocumentFile.java
@@ -18,7 +18,9 @@
import android.content.Context;
import android.net.Uri;
+import android.support.annotation.RequiresApi;
+@RequiresApi(21)
class TreeDocumentFile extends DocumentFile {
private Context mContext;
private Uri mUri;
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/design/lollipop/android/support/design/widget/FloatingActionButtonLollipop.java b/design/lollipop/android/support/design/widget/FloatingActionButtonLollipop.java
index d7c258f..df0df85 100644
--- a/design/lollipop/android/support/design/widget/FloatingActionButtonLollipop.java
+++ b/design/lollipop/android/support/design/widget/FloatingActionButtonLollipop.java
@@ -80,8 +80,7 @@
@Override
void onElevationsChanged(final float elevation, final float pressedTranslationZ) {
- final int sdk = Build.VERSION.SDK_INT;
- if (sdk == 21) {
+ if (Build.VERSION.SDK_INT == 21) {
// Animations produce NPE in version 21. Bluntly set the values instead (matching the
// logic in the animations below).
if (mView.isEnabled()) {
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/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/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/AppBarWithCollapsingToolbarTest.java b/design/tests/src/android/support/design/widget/AppBarWithCollapsingToolbarTest.java
index aeca0be..1dcb592 100644
--- a/design/tests/src/android/support/design/widget/AppBarWithCollapsingToolbarTest.java
+++ b/design/tests/src/android/support/design/widget/AppBarWithCollapsingToolbarTest.java
@@ -26,7 +26,6 @@
import android.support.design.test.R;
import android.support.test.filters.FlakyTest;
import android.support.test.filters.LargeTest;
-import android.support.test.filters.SdkSuppress;
import android.support.test.filters.Suppress;
import android.widget.ImageView;
@@ -536,7 +535,6 @@
@Suppress
@FlakyTest(bugId = 30701044)
@Test
- @SdkSuppress(minSdkVersion = 11)
public void testPinnedToolbarWithMargins() throws Throwable {
configureContent(R.layout.design_appbar_toolbar_collapse_pin_margins,
R.string.design_appbar_collapsing_toolbar_pin_margins);
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/CoordinatorLayoutTest.java b/design/tests/src/android/support/design/widget/CoordinatorLayoutTest.java
index 73ad193..a273be2 100644
--- a/design/tests/src/android/support/design/widget/CoordinatorLayoutTest.java
+++ b/design/tests/src/android/support/design/widget/CoordinatorLayoutTest.java
@@ -37,6 +37,7 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import android.annotation.TargetApi;
import android.app.Instrumentation;
import android.graphics.Rect;
import android.support.design.test.R;
@@ -76,6 +77,7 @@
@Test
@SdkSuppress(minSdkVersion = 21)
+ @TargetApi(21)
public void testSetFitSystemWindows() throws Throwable {
final Instrumentation instrumentation = getInstrumentation();
final CoordinatorLayout col = mActivityTestRule.getActivity().mCoordinatorLayout;
diff --git a/design/tests/src/android/support/design/widget/NavigationViewTest.java b/design/tests/src/android/support/design/widget/NavigationViewTest.java
index 8d6746d..e7e922a 100755
--- a/design/tests/src/android/support/design/widget/NavigationViewTest.java
+++ b/design/tests/src/android/support/design/widget/NavigationViewTest.java
@@ -61,6 +61,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+import android.annotation.TargetApi;
import android.content.res.Resources;
import android.os.Build;
import android.os.Parcelable;
@@ -406,6 +407,7 @@
}
@SdkSuppress(minSdkVersion = 11)
+ @TargetApi(11)
@Test
public void testHeaderState() {
// Open our drawer
@@ -445,6 +447,7 @@
}
@SdkSuppress(minSdkVersion = 11)
+ @TargetApi(11)
@Test
public void testActionViewState() {
// Open our drawer
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/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/DynamicAnimation.java b/dynamic-animation/src/android/support/animation/DynamicAnimation.java
index bd0f853..ee90df2 100644
--- a/dynamic-animation/src/android/support/animation/DynamicAnimation.java
+++ b/dynamic-animation/src/android/support/animation/DynamicAnimation.java
@@ -18,6 +18,7 @@
import android.os.Build;
import android.os.Looper;
+import android.support.v4.view.ViewCompat;
import android.util.AndroidRuntimeException;
import android.view.View;
@@ -89,18 +90,12 @@
public static final ViewProperty TRANSLATION_Z = new ViewProperty("translationZ") {
@Override
void setValue(View view, float value) {
- if (isZSupported()) {
- view.setTranslationZ(value);
- }
+ ViewCompat.setTranslationZ(view, value);
}
@Override
float getValue(View view) {
- if (isZSupported()) {
- return view.getTranslationZ();
- } else {
- return 0;
- }
+ return ViewCompat.getTranslationZ(view);
}
};
@@ -215,18 +210,12 @@
public static final ViewProperty Z = new ViewProperty("z") {
@Override
void setValue(View view, float value) {
- if (isZSupported()) {
- view.setZ(value);
- }
+ ViewCompat.setZ(view, value);
}
@Override
float getValue(View view) {
- if (isZSupported()) {
- return view.getZ();
- } else {
- return 0;
- }
+ return ViewCompat.getZ(view);
}
};
@@ -617,13 +606,6 @@
}
/**
- * Returns whether z and translationZ are supported on the current build version.
- */
- private static boolean isZSupported() {
- return Build.VERSION.SDK_INT >= 21;
- }
-
- /**
* Updates the property value through the corresponding setter.
*/
void setPropertyValue(float value) {
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/FragmentTransition.java b/fragment/java/android/support/v4/app/FragmentTransition.java
index 27cca90..fb3ad12 100644
--- a/fragment/java/android/support/v4/app/FragmentTransition.java
+++ b/fragment/java/android/support/v4/app/FragmentTransition.java
@@ -17,6 +17,7 @@
import android.graphics.Rect;
import android.os.Build;
+import android.support.annotation.RequiresApi;
import android.support.v4.util.ArrayMap;
import android.support.v4.view.ViewCompat;
import android.util.SparseArray;
@@ -82,38 +83,41 @@
static void startTransitions(FragmentManagerImpl fragmentManager,
ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop,
int startIndex, int endIndex, boolean isOptimized) {
- if (fragmentManager.mCurState < Fragment.CREATED
- || Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+ if (fragmentManager.mCurState < Fragment.CREATED) {
return;
}
- SparseArray<FragmentContainerTransition> transitioningFragments =
- new SparseArray<>();
- for (int i = startIndex; i < endIndex; i++) {
- final BackStackRecord record = records.get(i);
- final boolean isPop = isRecordPop.get(i);
- if (isPop) {
- calculatePopFragments(record, transitioningFragments, isOptimized);
- } else {
- calculateFragments(record, transitioningFragments, isOptimized);
- }
- }
- if (transitioningFragments.size() != 0) {
- final View nonExistentView = new View(fragmentManager.mHost.getContext());
- final int numContainers = transitioningFragments.size();
- for (int i = 0; i < numContainers; i++) {
- int containerId = transitioningFragments.keyAt(i);
- ArrayMap<String, String> nameOverrides = calculateNameOverrides(containerId,
- records, isRecordPop, startIndex, endIndex);
-
- FragmentContainerTransition containerTransition = transitioningFragments.valueAt(i);
-
- if (isOptimized) {
- configureTransitionsOptimized(fragmentManager, containerId,
- containerTransition, nonExistentView, nameOverrides);
+ if (Build.VERSION.SDK_INT >= 21) {
+ SparseArray<FragmentContainerTransition> transitioningFragments =
+ new SparseArray<>();
+ for (int i = startIndex; i < endIndex; i++) {
+ final BackStackRecord record = records.get(i);
+ final boolean isPop = isRecordPop.get(i);
+ if (isPop) {
+ calculatePopFragments(record, transitioningFragments, isOptimized);
} else {
- configureTransitionsUnoptimized(fragmentManager, containerId,
- containerTransition, nonExistentView, nameOverrides);
+ calculateFragments(record, transitioningFragments, isOptimized);
+ }
+ }
+
+ if (transitioningFragments.size() != 0) {
+ final View nonExistentView = new View(fragmentManager.mHost.getContext());
+ final int numContainers = transitioningFragments.size();
+ for (int i = 0; i < numContainers; i++) {
+ int containerId = transitioningFragments.keyAt(i);
+ ArrayMap<String, String> nameOverrides = calculateNameOverrides(containerId,
+ records, isRecordPop, startIndex, endIndex);
+
+ FragmentContainerTransition containerTransition =
+ transitioningFragments.valueAt(i);
+
+ if (isOptimized) {
+ configureTransitionsOptimized(fragmentManager, containerId,
+ containerTransition, nonExistentView, nameOverrides);
+ } else {
+ configureTransitionsUnoptimized(fragmentManager, containerId,
+ containerTransition, nonExistentView, nameOverrides);
+ }
}
}
}
@@ -185,6 +189,7 @@
* the final fragment's Views as given in
* {@link FragmentTransaction#addSharedElement(View, String)}.
*/
+ @RequiresApi(21)
private static void configureTransitionsOptimized(FragmentManagerImpl fragmentManager,
int containerId, FragmentContainerTransition fragments,
View nonExistentView, ArrayMap<String, String> nameOverrides) {
@@ -246,6 +251,7 @@
* the entire fragment's view GONE, make each exiting view INVISIBLE. At the end of the
* transition, make the fragment's view GONE.
*/
+ @RequiresApi(21)
private static void replaceHide(Object exitTransition, Fragment exitingFragment,
final ArrayList<View> exitingViews) {
if (exitingFragment != null && exitTransition != null && exitingFragment.mAdded
@@ -278,6 +284,7 @@
* the final fragment's Views as given in
* {@link FragmentTransaction#addSharedElement(View, String)}.
*/
+ @RequiresApi(21)
private static void configureTransitionsUnoptimized(FragmentManagerImpl fragmentManager,
int containerId, FragmentContainerTransition fragments,
View nonExistentView, ArrayMap<String, String> nameOverrides) {
@@ -355,6 +362,7 @@
* @param exitTransition The exit transition of the outgoing fragment
* @param exitingViews The exiting views of the outgoing fragment
*/
+ @RequiresApi(21)
private static void scheduleTargetChange(final ViewGroup sceneRoot,
final Fragment inFragment, final View nonExistentView,
final ArrayList<View> sharedElementsIn,
@@ -397,6 +405,7 @@
* @return A TransitionSet wrapping the shared element transition or null if no such transition
* exists.
*/
+ @RequiresApi(21)
private static Object getSharedElementTransition(Fragment inFragment,
Fragment outFragment, boolean isPop) {
if (inFragment == null || outFragment == null) {
@@ -411,6 +420,7 @@
/**
* Returns a clone of the enter transition or null if no such transition exists.
*/
+ @RequiresApi(21)
private static Object getEnterTransition(Fragment inFragment, boolean isPop) {
if (inFragment == null) {
return null;
@@ -423,6 +433,7 @@
/**
* Returns a clone of the exit transition or null if no such transition exists.
*/
+ @RequiresApi(21)
private static Object getExitTransition(Fragment outFragment, boolean isPop) {
if (outFragment == null) {
return null;
@@ -459,6 +470,7 @@
* epicenter
* @return The shared element transition or null if no shared elements exist
*/
+ @RequiresApi(21)
private static Object configureSharedElementsOptimized(final ViewGroup sceneRoot,
final View nonExistentView, final ArrayMap<String, String> nameOverrides,
final FragmentContainerTransition fragments,
@@ -587,6 +599,7 @@
* epicenter
* @return The shared element transition or null if no shared elements exist
*/
+ @RequiresApi(21)
private static Object configureSharedElementsUnoptimized(final ViewGroup sceneRoot,
final View nonExistentView, final ArrayMap<String, String> nameOverrides,
final FragmentContainerTransition fragments,
@@ -683,6 +696,7 @@
* @return The mapping of shared element names to the Views in the hierarchy or null
* if there is no shared element transition.
*/
+ @RequiresApi(21)
private static ArrayMap<String, View> captureOutSharedElements(
ArrayMap<String, String> nameOverrides, Object sharedElementTransition,
FragmentContainerTransition fragments) {
@@ -738,6 +752,7 @@
* @return The mapping of shared element names to the Views in the hierarchy or null
* if there is no shared element transition.
*/
+ @RequiresApi(21)
private static ArrayMap<String, View> captureInSharedElements(
ArrayMap<String, String> nameOverrides, Object sharedElementTransition,
FragmentContainerTransition fragments) {
@@ -833,6 +848,7 @@
* @param outIsPop Is the outgoing fragment being removed as a pop transaction?
* @param outTransaction The transaction that caused the fragment to be removed.
*/
+ @RequiresApi(21)
private static void setOutEpicenter(Object sharedElementTransition,
Object exitTransition, ArrayMap<String, View> outSharedElements, boolean outIsPop,
BackStackRecord outTransaction) {
@@ -897,6 +913,7 @@
}
}
+ @RequiresApi(21)
private static ArrayList<View> configureEnteringExitingViews(Object transition,
Fragment fragment, ArrayList<View> sharedElements, View nonExistentView) {
ArrayList<View> viewList = null;
@@ -934,6 +951,7 @@
* Merges exit, shared element, and enter transitions so that they act together or
* sequentially as defined in the fragments.
*/
+ @RequiresApi(21)
private static Object mergeTransitions(Object enterTransition,
Object exitTransition, Object sharedElementTransition, Fragment inFragment,
boolean isPop) {
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/FragmentReplaceTest.java b/fragment/tests/java/android/support/v4/app/FragmentReplaceTest.java
index 6aadeb7..fe7045c 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentReplaceTest.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentReplaceTest.java
@@ -26,7 +26,6 @@
import android.support.fragment.test.R;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
-import android.support.test.filters.SdkSuppress;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.support.v4.app.test.FragmentTestActivity;
@@ -98,7 +97,6 @@
});
}
- @SdkSuppress(minSdkVersion = 11)
@Test
public void testBackPressWithFrameworkFragment() throws Throwable {
final Activity activity = mActivityRule.getActivity();
diff --git a/fragment/tests/java/android/support/v4/app/FragmentTestUtil.java b/fragment/tests/java/android/support/v4/app/FragmentTestUtil.java
index a37b82e..ff48420 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentTestUtil.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentTestUtil.java
@@ -30,6 +30,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 +67,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 +218,21 @@
} while (!hasEnded[0] && SystemClock.uptimeMillis() < endTime);
return hasEnded[0];
}
+
+ /**
+ * Allocates until a garbage collection occurs.
+ */
+ public static void forceGC() {
+ // Do it twice so that we know we're not in the middle of the first collection when
+ // returning.
+ 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..6538fe7
--- /dev/null
+++ b/fragment/tests/java/android/support/v4/app/LoaderTest.java
@@ -0,0 +1,177 @@
+/*
+ * 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 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.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.Loader;
+
+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 {
+ @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
+ }
+
+ // Now 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());
+ }
+
+ private boolean switchOrientation() throws InterruptedException {
+ LoaderActivity activity = LoaderActivity.sActivity;
+
+ int currentOrientation = activity.getResources().getConfiguration().orientation;
+
+ int nextOrientation;
+ if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
+ nextOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+ } else if (currentOrientation == Configuration.ORIENTATION_PORTRAIT) {
+ nextOrientation = ActivityInfo.SCREEN_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);
+
+ activity.setRequestedOrientation(nextOrientation);
+ assertTrue(LoaderActivity.sResumed.await(1, TimeUnit.SECONDS));
+ 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..40f41f0
--- /dev/null
+++ b/fragment/tests/java/android/support/v4/app/test/LoaderActivity.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.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.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 TextView textView;
+
+ public static void clearState() {
+ sActivity = null;
+ sResumed = null;
+ }
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ sActivity = this;
+
+ setContentView(R.layout.fragment_a);
+ textView = (TextView) findViewById(R.id.textA);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ getSupportLoaderManager().initLoader(0, null, new TextLoaderCallback());
+ if (sResumed != null) {
+ sResumed.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 014f353..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 [ "$os" = "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/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java b/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java
index 5f61127..3c349f9 100644
--- a/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java
+++ b/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java
@@ -17,6 +17,7 @@
import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
import android.annotation.SuppressLint;
+import android.support.annotation.RequiresApi;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
@@ -263,7 +264,7 @@
@Override
public ConstantState getConstantState() {
- if (mDelegateDrawable != null) {
+ if (mDelegateDrawable != null && Build.VERSION.SDK_INT >= 24) {
// Such that the configuration can be refreshed.
return new VectorDrawableDelegateState(mDelegateDrawable.getConstantState());
}
@@ -884,6 +885,7 @@
* Instead of creating a VectorDrawable, create a VectorDrawableCompat instance which contains
* a delegated VectorDrawable instance.
*/
+ @RequiresApi(24)
private static class VectorDrawableDelegateState extends ConstantState {
private final ConstantState mDelegateState;
diff --git a/media-compat/api26/android/support/v4/media/MediaBrowserCompatApi26.java b/media-compat/api26/android/support/v4/media/MediaBrowserCompatApi26.java
new file mode 100644
index 0000000..9c3b99d
--- /dev/null
+++ b/media-compat/api26/android/support/v4/media/MediaBrowserCompatApi26.java
@@ -0,0 +1,60 @@
+/*
+ * 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.media;
+
+import android.media.browse.MediaBrowser;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.RequiresApi;
+
+import java.util.List;
+
+@RequiresApi(26)
+class MediaBrowserCompatApi26 {
+ public static Object createSearchCallback(SearchCallback callback) {
+ return new SearchCallbackProxy<>(callback);
+ }
+
+ public static void search(Object browserObj, String query, Bundle extras, Object callback) {
+ ((MediaBrowser) browserObj).search(query, extras,
+ (MediaBrowser.SearchCallback) callback);
+ }
+
+ interface SearchCallback {
+ void onSearchResult(@NonNull String query, Bundle extras, @NonNull List<?> items);
+ void onError(@NonNull String query, Bundle extras);
+ }
+
+ static class SearchCallbackProxy<T extends SearchCallback> extends MediaBrowser.SearchCallback {
+ protected final T mSearchCallback;
+
+ SearchCallbackProxy(T callback) {
+ mSearchCallback = callback;
+ }
+
+ @Override
+ public void onSearchResult(String query, Bundle extras,
+ List<MediaBrowser.MediaItem> items) {
+ mSearchCallback.onSearchResult(query, extras, items);
+ }
+
+ @Override
+ public void onError(String query, Bundle extras) {
+ mSearchCallback.onError(query, extras);
+ }
+ }
+}
diff --git a/media-compat/api26/android/support/v4/media/MediaBrowserServiceCompatApi26.java b/media-compat/api26/android/support/v4/media/MediaBrowserServiceCompatApi26.java
new file mode 100644
index 0000000..d427531
--- /dev/null
+++ b/media-compat/api26/android/support/v4/media/MediaBrowserServiceCompatApi26.java
@@ -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.
+ */
+
+package android.support.v4.media;
+
+import android.content.Context;
+import android.media.browse.MediaBrowser;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.RequiresApi;
+
+import java.util.List;
+
+@RequiresApi(26)
+class MediaBrowserServiceCompatApi26 {
+
+ public static Object createService(Context context, ServiceCompatProxy serviceProxy) {
+ return new MediaBrowserServiceAdaptor(context, serviceProxy);
+ }
+
+ public interface ServiceCompatProxy extends MediaBrowserServiceCompatApi24.ServiceCompatProxy {
+ void onSearch(@NonNull String query, Bundle extras,
+ MediaBrowserServiceCompatApi24.ResultWrapper result);
+ }
+
+ static class MediaBrowserServiceAdaptor extends
+ MediaBrowserServiceCompatApi24.MediaBrowserServiceAdaptor {
+ MediaBrowserServiceAdaptor(Context context, ServiceCompatProxy serviceWrapper) {
+ super(context, serviceWrapper);
+ }
+
+ @Override
+ public void onSearch(@NonNull String query, Bundle extras,
+ @NonNull Result<List<MediaBrowser.MediaItem>> result) {
+ ((ServiceCompatProxy) mServiceProxy).onSearch(query, extras,
+ new MediaBrowserServiceCompatApi24.ResultWrapper(result));
+ }
+ }
+}
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 bf2ca60..33829e7 100644
--- a/media-compat/api26/android/support/v4/media/session/MediaControllerCompatApi26.java
+++ b/media-compat/api26/android/support/v4/media/session/MediaControllerCompatApi26.java
@@ -16,10 +16,10 @@
package android.support.v4.media.session;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.media.session.MediaController;
-@TargetApi(26)
+@RequiresApi(26)
class MediaControllerCompatApi26 {
public static Object createCallback(Callback callback) {
return new CallbackProxy<>(callback);
diff --git a/media-compat/java/android/support/v4/media/MediaBrowserCompat.java b/media-compat/java/android/support/v4/media/MediaBrowserCompat.java
index 4a854e4..48a945e 100644
--- a/media-compat/java/android/support/v4/media/MediaBrowserCompat.java
+++ b/media-compat/java/android/support/v4/media/MediaBrowserCompat.java
@@ -38,10 +38,12 @@
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;
+import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -59,8 +61,10 @@
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+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;
@@ -122,11 +126,13 @@
* @see MediaBrowserServiceCompat.BrowserRoot#EXTRA_OFFLINE
* @see MediaBrowserServiceCompat.BrowserRoot#EXTRA_SUGGESTED
*/
+ @SuppressLint("NewApi")
public MediaBrowserCompat(Context context, ComponentName serviceComponent,
ConnectionCallback callback, Bundle rootHints) {
// To workaround an issue of {@link #unsubscribe(String, SubscriptionCallback)} on API 24
// and 25 devices, use the support library version of implementation on those devices.
- if (Build.VERSION.SDK_INT >= 26 || BuildCompat.isAtLeastO()) {
+ if (BuildCompat.isAtLeastO()) {
+ //noinspection AndroidLintNewApi
mImpl = new MediaBrowserImplApi24(context, serviceComponent, callback, rootHints);
} else if (Build.VERSION.SDK_INT >= 23) {
mImpl = new MediaBrowserImplApi23(context, serviceComponent, callback, rootHints);
@@ -600,8 +606,10 @@
private final IBinder mToken;
WeakReference<Subscription> mSubscriptionRef;
+ @SuppressLint("NewApi")
public SubscriptionCallback() {
- if (Build.VERSION.SDK_INT >= 26 || BuildCompat.isAtLeastO()) {
+ if (BuildCompat.isAtLeastO()) {
+ //noinspection AndroidLintNewApi
mSubscriptionCallbackObj =
MediaBrowserCompatApi24.createSubscriptionCallback(new StubApi24());
mToken = null;
@@ -800,6 +808,18 @@
* Callback for receiving the result of {@link #search}.
*/
public abstract static class SearchCallback {
+ final Object mSearchCallbackObj;
+
+ @SuppressLint("NewApi")
+ public SearchCallback() {
+ if (BuildCompat.isAtLeastO()) {
+ //noinspection AndroidLintNewApi
+ mSearchCallbackObj = MediaBrowserCompatApi26.createSearchCallback(new StubApi26());
+ } else {
+ mSearchCallbackObj = null;
+ }
+ }
+
/**
* Called when the {@link #search} finished successfully.
*
@@ -820,6 +840,23 @@
*/
public void onError(@NonNull String query, Bundle extras) {
}
+
+ private class StubApi26 implements MediaBrowserCompatApi26.SearchCallback {
+ StubApi26() {
+ }
+
+ @Override
+ public void onSearchResult(@NonNull String query, Bundle extras,
+ @NonNull List<?> items) {
+ SearchCallback.this.onSearchResult(
+ query, extras, MediaItem.fromMediaItemList(items));
+ }
+
+ @Override
+ public void onError(@NonNull String query, Bundle extras) {
+ SearchCallback.this.onError(query, extras);
+ }
+ }
}
interface MediaBrowserImpl {
@@ -1422,6 +1459,7 @@
}
}
+ @RequiresApi(21)
static class MediaBrowserImplApi21 implements MediaBrowserImpl, MediaBrowserServiceCallbackImpl,
ConnectionCallback.ConnectionCallbackInternal {
protected final Object mBrowserObj;
@@ -1431,6 +1469,7 @@
protected ServiceBinderWrapper mServiceBinderWrapper;
protected Messenger mCallbacksMessenger;
+ private MediaSessionCompat.Token mMediaSessionToken;
public MediaBrowserImplApi21(Context context, ComponentName serviceComponent,
ConnectionCallback callback, Bundle rootHints) {
@@ -1492,8 +1531,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
@@ -1678,12 +1720,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);
}
@@ -1738,6 +1787,7 @@
}
}
+ @RequiresApi(23)
static class MediaBrowserImplApi23 extends MediaBrowserImplApi21 {
public MediaBrowserImplApi23(Context context, ComponentName serviceComponent,
ConnectionCallback callback, Bundle rootHints) {
@@ -1755,6 +1805,7 @@
}
// TODO: Rename to MediaBrowserImplApi26 once O is released
+ @RequiresApi(26)
static class MediaBrowserImplApi24 extends MediaBrowserImplApi23 {
public MediaBrowserImplApi24(Context context, ComponentName serviceComponent,
ConnectionCallback callback, Bundle rootHints) {
@@ -1782,6 +1833,12 @@
callback.mSubscriptionCallbackObj);
}
}
+
+ @Override
+ public void search(@NonNull final String query, final Bundle extras,
+ @NonNull final SearchCallback callback) {
+ MediaBrowserCompatApi26.search(mBrowserObj, query, extras, callback.mSearchCallbackObj);
+ }
}
private static class Subscription {
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 2d6c886..7fbf88e 100644
--- a/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
+++ b/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
@@ -39,11 +39,13 @@
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;
import static android.support.v4.media.MediaBrowserProtocol.SERVICE_VERSION_CURRENT;
+import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -59,6 +61,7 @@
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.annotation.RequiresApi;
import android.support.annotation.RestrictTo;
import android.support.v4.app.BundleCompat;
import android.support.v4.media.session.MediaSessionCompat;
@@ -222,6 +225,7 @@
}
}
+ @RequiresApi(21)
class MediaBrowserServiceImplApi21 implements MediaBrowserServiceImpl,
MediaBrowserServiceCompatApi21.ServiceCompatProxy {
Object mServiceObj;
@@ -293,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);
@@ -336,6 +342,7 @@
}
}
+ @RequiresApi(23)
class MediaBrowserServiceImplApi23 extends MediaBrowserServiceImplApi21 implements
MediaBrowserServiceCompatApi23.ServiceCompatProxy {
@Override
@@ -371,11 +378,12 @@
}
// TODO: Rename to MediaBrowserServiceImplApi26 once O is released
+ @RequiresApi(26)
class MediaBrowserServiceImplApi24 extends MediaBrowserServiceImplApi23 implements
- MediaBrowserServiceCompatApi24.ServiceCompatProxy {
+ MediaBrowserServiceCompatApi26.ServiceCompatProxy {
@Override
public void onCreate() {
- mServiceObj = MediaBrowserServiceCompatApi24.createService(
+ mServiceObj = MediaBrowserServiceCompatApi26.createService(
MediaBrowserServiceCompat.this, this);
MediaBrowserServiceCompatApi21.onCreate(mServiceObj);
}
@@ -426,6 +434,29 @@
}
return MediaBrowserServiceCompatApi24.getBrowserRootHints(mServiceObj);
}
+
+ @Override
+ public void onSearch(@NonNull String query, Bundle extras,
+ final MediaBrowserServiceCompatApi24.ResultWrapper resultWrapper) {
+ final Result<List<MediaBrowserCompat.MediaItem>> result =
+ new Result<List<MediaBrowserCompat.MediaItem>>(query) {
+ @Override
+ void onResultSent(List<MediaBrowserCompat.MediaItem> list,
+ @ResultFlags int flags) {
+ List<Parcel> parcelList = null;
+ if (list != null) {
+ parcelList = new ArrayList<>();
+ for (MediaBrowserCompat.MediaItem item : list) {
+ Parcel parcel = Parcel.obtain();
+ item.writeToParcel(parcel, 0);
+ parcelList.add(parcel);
+ }
+ }
+ resultWrapper.sendResult(parcelList, flags);
+ }
+ };
+ MediaBrowserServiceCompat.this.onSearch(query, extras, result);
+ }
}
private final class ServiceHandler extends Handler {
@@ -828,9 +859,11 @@
}
@Override
+ @SuppressLint("NewApi")
public void onCreate() {
super.onCreate();
- if (Build.VERSION.SDK_INT >= 26 || BuildCompat.isAtLeastO()) {
+ if (BuildCompat.isAtLeastO()) {
+ //noinspection AndroidLintNewApi
mImpl = new MediaBrowserServiceImplApi24();
} else if (Build.VERSION.SDK_INT >= 23) {
mImpl = new MediaBrowserServiceImplApi23();
diff --git a/media-compat/java/android/support/v4/media/MediaDescriptionCompat.java b/media-compat/java/android/support/v4/media/MediaDescriptionCompat.java
index 1a617e9..37643d8 100644
--- a/media-compat/java/android/support/v4/media/MediaDescriptionCompat.java
+++ b/media-compat/java/android/support/v4/media/MediaDescriptionCompat.java
@@ -334,44 +334,44 @@
* none.
*/
public static MediaDescriptionCompat fromMediaDescription(Object descriptionObj) {
- if (descriptionObj == null || Build.VERSION.SDK_INT < 21) {
+ if (descriptionObj != null && Build.VERSION.SDK_INT >= 21) {
+ Builder bob = new Builder();
+ bob.setMediaId(MediaDescriptionCompatApi21.getMediaId(descriptionObj));
+ bob.setTitle(MediaDescriptionCompatApi21.getTitle(descriptionObj));
+ bob.setSubtitle(MediaDescriptionCompatApi21.getSubtitle(descriptionObj));
+ bob.setDescription(MediaDescriptionCompatApi21.getDescription(descriptionObj));
+ bob.setIconBitmap(MediaDescriptionCompatApi21.getIconBitmap(descriptionObj));
+ bob.setIconUri(MediaDescriptionCompatApi21.getIconUri(descriptionObj));
+ Bundle extras = MediaDescriptionCompatApi21.getExtras(descriptionObj);
+ Uri mediaUri = extras == null ? null :
+ (Uri) extras.getParcelable(DESCRIPTION_KEY_MEDIA_URI);
+ if (mediaUri != null) {
+ if (extras.containsKey(DESCRIPTION_KEY_NULL_BUNDLE_FLAG) && extras.size() == 2) {
+ // The extras were only created for the media URI, so we set it back to null to
+ // ensure mediaDescriptionCompat.getExtras() equals
+ // fromMediaDescription(getMediaDescription(mediaDescriptionCompat)).getExtras()
+ extras = null;
+ } else {
+ // Remove media URI keys to ensure mediaDescriptionCompat.getExtras().keySet()
+ // equals fromMediaDescription(getMediaDescription(mediaDescriptionCompat))
+ // .getExtras().keySet()
+ extras.remove(DESCRIPTION_KEY_MEDIA_URI);
+ extras.remove(DESCRIPTION_KEY_NULL_BUNDLE_FLAG);
+ }
+ }
+ bob.setExtras(extras);
+ if (mediaUri != null) {
+ bob.setMediaUri(mediaUri);
+ } else if (Build.VERSION.SDK_INT >= 23) {
+ bob.setMediaUri(MediaDescriptionCompatApi23.getMediaUri(descriptionObj));
+ }
+ MediaDescriptionCompat descriptionCompat = bob.build();
+ descriptionCompat.mDescriptionObj = descriptionObj;
+
+ return descriptionCompat;
+ } else {
return null;
}
-
- Builder bob = new Builder();
- bob.setMediaId(MediaDescriptionCompatApi21.getMediaId(descriptionObj));
- bob.setTitle(MediaDescriptionCompatApi21.getTitle(descriptionObj));
- bob.setSubtitle(MediaDescriptionCompatApi21.getSubtitle(descriptionObj));
- bob.setDescription(MediaDescriptionCompatApi21.getDescription(descriptionObj));
- bob.setIconBitmap(MediaDescriptionCompatApi21.getIconBitmap(descriptionObj));
- bob.setIconUri(MediaDescriptionCompatApi21.getIconUri(descriptionObj));
- Bundle extras = MediaDescriptionCompatApi21.getExtras(descriptionObj);
- Uri mediaUri = extras == null ? null :
- (Uri) extras.getParcelable(DESCRIPTION_KEY_MEDIA_URI);
- if (mediaUri != null) {
- if (extras.containsKey(DESCRIPTION_KEY_NULL_BUNDLE_FLAG) && extras.size() == 2) {
- // The extras were only created for the media URI, so we set it back to null to
- // ensure mediaDescriptionCompat.getExtras() equals
- // fromMediaDescription(getMediaDescription(mediaDescriptionCompat)).getExtras()
- extras = null;
- } else {
- // Remove media URI keys to ensure mediaDescriptionCompat.getExtras().keySet()
- // equals fromMediaDescription(getMediaDescription(mediaDescriptionCompat))
- // .getExtras().keySet()
- extras.remove(DESCRIPTION_KEY_MEDIA_URI);
- extras.remove(DESCRIPTION_KEY_NULL_BUNDLE_FLAG);
- }
- }
- bob.setExtras(extras);
- if (mediaUri != null) {
- bob.setMediaUri(mediaUri);
- } else if (Build.VERSION.SDK_INT >= 23) {
- bob.setMediaUri(MediaDescriptionCompatApi23.getMediaUri(descriptionObj));
- }
- MediaDescriptionCompat descriptionCompat = bob.build();
- descriptionCompat.mDescriptionObj = descriptionObj;
-
- return descriptionCompat;
}
public static final Parcelable.Creator<MediaDescriptionCompat> CREATOR =
diff --git a/media-compat/java/android/support/v4/media/MediaMetadataCompat.java b/media-compat/java/android/support/v4/media/MediaMetadataCompat.java
index f8c1f57..58c1147 100644
--- a/media-compat/java/android/support/v4/media/MediaMetadataCompat.java
+++ b/media-compat/java/android/support/v4/media/MediaMetadataCompat.java
@@ -580,17 +580,17 @@
* none.
*/
public static MediaMetadataCompat fromMediaMetadata(Object metadataObj) {
- if (metadataObj == null || Build.VERSION.SDK_INT < 21) {
+ if (metadataObj != null && Build.VERSION.SDK_INT >= 21) {
+ Parcel p = Parcel.obtain();
+ MediaMetadataCompatApi21.writeToParcel(metadataObj, p, 0);
+ p.setDataPosition(0);
+ MediaMetadataCompat metadata = MediaMetadataCompat.CREATOR.createFromParcel(p);
+ p.recycle();
+ metadata.mMetadataObj = metadataObj;
+ return metadata;
+ } else {
return null;
}
-
- Parcel p = Parcel.obtain();
- MediaMetadataCompatApi21.writeToParcel(metadataObj, p, 0);
- p.setDataPosition(0);
- MediaMetadataCompat metadata = MediaMetadataCompat.CREATOR.createFromParcel(p);
- p.recycle();
- metadata.mMetadataObj = metadataObj;
- return metadata;
}
/**
@@ -604,15 +604,13 @@
* if none.
*/
public Object getMediaMetadata() {
- if (mMetadataObj != null || Build.VERSION.SDK_INT < 21) {
- return mMetadataObj;
+ if (mMetadataObj == null && Build.VERSION.SDK_INT >= 21) {
+ Parcel p = Parcel.obtain();
+ writeToParcel(p, 0);
+ p.setDataPosition(0);
+ mMetadataObj = MediaMetadataCompatApi21.createFromParcel(p);
+ p.recycle();
}
-
- Parcel p = Parcel.obtain();
- writeToParcel(p, 0);
- p.setDataPosition(0);
- mMetadataObj = MediaMetadataCompatApi21.createFromParcel(p);
- p.recycle();
return mMetadataObj;
}
@@ -662,7 +660,7 @@
* <p>
* This also deep-copies the bitmaps for {@link #METADATA_KEY_ART} and
* {@link #METADATA_KEY_ALBUM_ART} on
- * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWITCH} and later
+ * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH} and later
* to prevent bitmaps from being recycled by RCC.
*
* @param source The original metadata to copy.
diff --git a/media-compat/java/android/support/v4/media/RatingCompat.java b/media-compat/java/android/support/v4/media/RatingCompat.java
index f61a686..e8cb10d 100644
--- a/media-compat/java/android/support/v4/media/RatingCompat.java
+++ b/media-compat/java/android/support/v4/media/RatingCompat.java
@@ -324,37 +324,38 @@
* @return An equivalent {@link RatingCompat} object, or null if none.
*/
public static RatingCompat fromRating(Object ratingObj) {
- if (ratingObj == null || Build.VERSION.SDK_INT < 19) {
+ if (ratingObj != null && Build.VERSION.SDK_INT >= 19) {
+ final int ratingStyle = RatingCompatKitkat.getRatingStyle(ratingObj);
+ final RatingCompat rating;
+ if (RatingCompatKitkat.isRated(ratingObj)) {
+ switch (ratingStyle) {
+ case RATING_HEART:
+ rating = newHeartRating(RatingCompatKitkat.hasHeart(ratingObj));
+ break;
+ case RATING_THUMB_UP_DOWN:
+ rating = newThumbRating(RatingCompatKitkat.isThumbUp(ratingObj));
+ break;
+ case RATING_3_STARS:
+ case RATING_4_STARS:
+ case RATING_5_STARS:
+ rating = newStarRating(ratingStyle,
+ RatingCompatKitkat.getStarRating(ratingObj));
+ break;
+ case RATING_PERCENTAGE:
+ rating = newPercentageRating(
+ RatingCompatKitkat.getPercentRating(ratingObj));
+ break;
+ default:
+ return null;
+ }
+ } else {
+ rating = newUnratedRating(ratingStyle);
+ }
+ rating.mRatingObj = ratingObj;
+ return rating;
+ } else {
return null;
}
-
- final int ratingStyle = RatingCompatKitkat.getRatingStyle(ratingObj);
- final RatingCompat rating;
- if (RatingCompatKitkat.isRated(ratingObj)) {
- switch (ratingStyle) {
- case RATING_HEART:
- rating = newHeartRating(RatingCompatKitkat.hasHeart(ratingObj));
- break;
- case RATING_THUMB_UP_DOWN:
- rating = newThumbRating(RatingCompatKitkat.isThumbUp(ratingObj));
- break;
- case RATING_3_STARS:
- case RATING_4_STARS:
- case RATING_5_STARS:
- rating = newStarRating(ratingStyle,
- RatingCompatKitkat.getStarRating(ratingObj));
- break;
- case RATING_PERCENTAGE:
- rating = newPercentageRating(RatingCompatKitkat.getPercentRating(ratingObj));
- break;
- default:
- return null;
- }
- } else {
- rating = newUnratedRating(ratingStyle);
- }
- rating.mRatingObj = ratingObj;
- return rating;
}
/**
@@ -366,30 +367,29 @@
* @return An equivalent {@link android.media.Rating} object, or null if none.
*/
public Object getRating() {
- if (mRatingObj != null || Build.VERSION.SDK_INT < 19) {
- return mRatingObj;
- }
-
- if (isRated()) {
- switch (mRatingStyle) {
- case RATING_HEART:
- mRatingObj = RatingCompatKitkat.newHeartRating(hasHeart());
- break;
- case RATING_THUMB_UP_DOWN:
- mRatingObj = RatingCompatKitkat.newThumbRating(isThumbUp());
- break;
- case RATING_3_STARS:
- case RATING_4_STARS:
- case RATING_5_STARS:
- mRatingObj = RatingCompatKitkat.newStarRating(mRatingStyle, getStarRating());
- break;
- case RATING_PERCENTAGE:
- mRatingObj = RatingCompatKitkat.newPercentageRating(getPercentRating());
- default:
- return null;
+ if (mRatingObj == null && Build.VERSION.SDK_INT >= 19) {
+ if (isRated()) {
+ switch (mRatingStyle) {
+ case RATING_HEART:
+ mRatingObj = RatingCompatKitkat.newHeartRating(hasHeart());
+ break;
+ case RATING_THUMB_UP_DOWN:
+ mRatingObj = RatingCompatKitkat.newThumbRating(isThumbUp());
+ break;
+ case RATING_3_STARS:
+ case RATING_4_STARS:
+ case RATING_5_STARS:
+ mRatingObj = RatingCompatKitkat.newStarRating(mRatingStyle,
+ getStarRating());
+ break;
+ case RATING_PERCENTAGE:
+ mRatingObj = RatingCompatKitkat.newPercentageRating(getPercentRating());
+ default:
+ return null;
+ }
+ } else {
+ mRatingObj = RatingCompatKitkat.newUnratedRating(mRatingStyle);
}
- } else {
- mRatingObj = RatingCompatKitkat.newUnratedRating(mRatingStyle);
}
return mRatingObj;
}
diff --git a/media-compat/java/android/support/v4/media/TransportMediator.java b/media-compat/java/android/support/v4/media/TransportMediator.java
index 40c245c..cb10bb1 100644
--- a/media-compat/java/android/support/v4/media/TransportMediator.java
+++ b/media-compat/java/android/support/v4/media/TransportMediator.java
@@ -259,7 +259,10 @@
*/
@Deprecated
public Object getRemoteControlClient() {
- return mController != null ? mController.getRemoteControlClient() : null;
+ if (Build.VERSION.SDK_INT >= 18) {
+ return mController != null ? mController.getRemoteControlClient() : null;
+ }
+ return null;
}
/**
@@ -327,7 +330,7 @@
}
private void pushControllerState() {
- if (mController != null) {
+ if (mController != null && Build.VERSION.SDK_INT >= 18) {
mController.refreshState(mCallbacks.onIsPlaying(),
mCallbacks.onGetCurrentPosition(),
mCallbacks.onGetTransportControlFlags());
@@ -353,7 +356,7 @@
@Deprecated
@Override
public void startPlaying() {
- if (mController != null) {
+ if (mController != null && Build.VERSION.SDK_INT >= 18) {
mController.startPlaying();
}
mCallbacks.onStart();
@@ -370,7 +373,7 @@
@Deprecated
@Override
public void pausePlaying() {
- if (mController != null) {
+ if (mController != null && Build.VERSION.SDK_INT >= 18) {
mController.pausePlaying();
}
mCallbacks.onPause();
@@ -387,7 +390,7 @@
@Deprecated
@Override
public void stopPlaying() {
- if (mController != null) {
+ if (mController != null && Build.VERSION.SDK_INT >= 18) {
mController.stopPlaying();
}
mCallbacks.onStop();
@@ -483,6 +486,8 @@
*/
@Deprecated
public void destroy() {
- mController.destroy();
+ if (mController != null && Build.VERSION.SDK_INT >= 18) {
+ mController.destroy();
+ }
}
}
diff --git a/media-compat/java/android/support/v4/media/VolumeProviderCompat.java b/media-compat/java/android/support/v4/media/VolumeProviderCompat.java
index a3aa047..3085969 100644
--- a/media-compat/java/android/support/v4/media/VolumeProviderCompat.java
+++ b/media-compat/java/android/support/v4/media/VolumeProviderCompat.java
@@ -121,7 +121,7 @@
public final void setCurrentVolume(int currentVolume) {
mCurrentVolume = currentVolume;
Object volumeProviderObj = getVolumeProvider();
- if (volumeProviderObj != null) {
+ if (volumeProviderObj != null && Build.VERSION.SDK_INT >= 21) {
VolumeProviderCompatApi21.setCurrentVolume(volumeProviderObj, currentVolume);
}
if (mCallback != null) {
@@ -164,23 +164,22 @@
* @return An equivalent {@link android.media.VolumeProvider} object, or null if none.
*/
public Object getVolumeProvider() {
- if (mVolumeProviderObj != null || Build.VERSION.SDK_INT < 21) {
- return mVolumeProviderObj;
+ if (mVolumeProviderObj == null && Build.VERSION.SDK_INT >= 21) {
+ mVolumeProviderObj = VolumeProviderCompatApi21.createVolumeProvider(
+ mControlType, mMaxVolume, mCurrentVolume,
+ new VolumeProviderCompatApi21.Delegate() {
+
+ @Override
+ public void onSetVolumeTo(int volume) {
+ VolumeProviderCompat.this.onSetVolumeTo(volume);
+ }
+
+ @Override
+ public void onAdjustVolume(int direction) {
+ VolumeProviderCompat.this.onAdjustVolume(direction);
+ }
+ });
}
-
- mVolumeProviderObj = VolumeProviderCompatApi21.createVolumeProvider(
- mControlType, mMaxVolume, mCurrentVolume, new VolumeProviderCompatApi21.Delegate() {
-
- @Override
- public void onSetVolumeTo(int volume) {
- VolumeProviderCompat.this.onSetVolumeTo(volume);
- }
-
- @Override
- public void onAdjustVolume(int direction) {
- VolumeProviderCompat.this.onAdjustVolume(direction);
- }
- });
return mVolumeProviderObj;
}
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 4f9fe6d..d040bb6 100644
--- a/media-compat/java/android/support/v4/media/session/MediaControllerCompat.java
+++ b/media-compat/java/android/support/v4/media/session/MediaControllerCompat.java
@@ -28,7 +28,7 @@
import android.os.Message;
import android.os.RemoteException;
import android.os.ResultReceiver;
-import android.support.annotation.VisibleForTesting;
+import android.support.annotation.RequiresApi;
import android.support.v4.app.BundleCompat;
import android.support.v4.app.SupportActivity;
import android.support.v4.media.MediaDescriptionCompat;
@@ -498,15 +498,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.
@@ -1153,12 +1144,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());
}
@@ -1621,6 +1610,7 @@
}
}
+ @RequiresApi(21)
static class MediaControllerImplApi21 implements MediaControllerImpl {
protected final Object mControllerObj;
@@ -1633,7 +1623,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)
@@ -1641,7 +1634,10 @@
mControllerObj = MediaControllerCompatApi21.fromToken(context,
sessionToken.getToken());
if (mControllerObj == null) throw new RemoteException();
- requestExtraBinder();
+ mExtraBinder = sessionToken.getExtraBinder();
+ if (mExtraBinder == null) {
+ requestExtraBinder();
+ }
}
@Override
@@ -1843,7 +1839,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()));
@@ -2114,6 +2109,7 @@
}
}
+ @RequiresApi(23)
static class MediaControllerImplApi23 extends MediaControllerImplApi21 {
public MediaControllerImplApi23(Context context, MediaSessionCompat session) {
@@ -2132,6 +2128,7 @@
}
}
+ @RequiresApi(23)
static class TransportControlsApi23 extends TransportControlsApi21 {
public TransportControlsApi23(Object controlsObj) {
@@ -2145,6 +2142,7 @@
}
}
+ @RequiresApi(24)
static class MediaControllerImplApi24 extends MediaControllerImplApi23 {
public MediaControllerImplApi24(Context context, MediaSessionCompat session) {
@@ -2163,6 +2161,7 @@
}
}
+ @RequiresApi(24)
static class TransportControlsApi24 extends TransportControlsApi23 {
public TransportControlsApi24(Object controlsObj) {
@@ -2192,6 +2191,7 @@
}
}
+ @RequiresApi(26)
static class MediaControllerImplApi26 extends MediaControllerImplApi24 {
MediaControllerImplApi26(Context context, MediaSessionCompat session) {
@@ -2220,6 +2220,7 @@
}
}
+ @RequiresApi(26)
static class TransportControlsApi26 extends TransportControlsApi24 {
TransportControlsApi26(Object controlsObj) {
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 a186c95..c6fc6da 100644
--- a/media-compat/java/android/support/v4/media/session/MediaSessionCompat.java
+++ b/media-compat/java/android/support/v4/media/session/MediaSessionCompat.java
@@ -681,10 +681,10 @@
* @return An equivalent {@link MediaSessionCompat} object, or null if none.
*/
public static MediaSessionCompat fromMediaSession(Context context, Object mediaSession) {
- if (context == null || mediaSession == null || Build.VERSION.SDK_INT < 21) {
- return null;
+ if (context != null && mediaSession != null && Build.VERSION.SDK_INT >= 21) {
+ return new MediaSessionCompat(context, new MediaSessionImplApi21(mediaSession));
}
- return new MediaSessionCompat(context, new MediaSessionImplApi21(mediaSession));
+ return null;
}
/**
@@ -944,6 +944,7 @@
public void onRemoveQueueItemAt(int index) {
}
+ @RequiresApi(21)
private class StubApi21 implements MediaSessionCompatApi21.Callback {
StubApi21() {
@@ -955,7 +956,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)) {
@@ -1079,6 +1081,7 @@
}
}
+ @RequiresApi(23)
private class StubApi23 extends StubApi21 implements MediaSessionCompatApi23.Callback {
StubApi23() {
@@ -1090,6 +1093,7 @@
}
}
+ @RequiresApi(24)
private class StubApi24 extends StubApi23 implements MediaSessionCompatApi24.Callback {
StubApi24() {
@@ -1116,6 +1120,7 @@
}
}
+ @RequiresApi(26)
private class StubApi26 extends StubApi24 implements MediaSessionCompatApi26.Callback {
@Override
public void onSetRepeatMode(int repeatMode) {
@@ -1136,9 +1141,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;
}
/**
@@ -1153,10 +1164,28 @@
* @return A compat Token for use with {@link MediaControllerCompat}.
*/
public static Token fromToken(Object token) {
- if (token == null || android.os.Build.VERSION.SDK_INT < 21) {
- return null;
+ 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), extraBinder);
}
- return new Token(MediaSessionCompatApi21.verifyToken(token));
+ return null;
}
@Override
@@ -1168,6 +1197,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);
}
@@ -1213,23 +1243,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];
+ }
};
}
@@ -2798,7 +2838,6 @@
private final Token mToken;
private boolean mDestroyed = false;
- private ExtraSession mExtraSessionBinder;
private final RemoteCallbackList<IMediaControllerCallback> mExtraControllerCallbacks =
new RemoteCallbackList<>();
@@ -2809,12 +2848,14 @@
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
@@ -3001,13 +3042,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) {
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 815fe95..ab85133 100644
--- a/media-compat/java/android/support/v4/media/session/PlaybackStateCompat.java
+++ b/media-compat/java/android/support/v4/media/session/PlaybackStateCompat.java
@@ -713,35 +713,38 @@
* @return An equivalent {@link PlaybackStateCompat} object, or null if none.
*/
public static PlaybackStateCompat fromPlaybackState(Object stateObj) {
- if (stateObj == null || Build.VERSION.SDK_INT < 21) {
+ if (stateObj != null && Build.VERSION.SDK_INT >= 21) {
+ List<Object> customActionObjs = PlaybackStateCompatApi21.getCustomActions(stateObj);
+ List<PlaybackStateCompat.CustomAction> customActions = null;
+ if (customActionObjs != null) {
+ customActions = new ArrayList<>(customActionObjs.size());
+ for (Object customActionObj : customActionObjs) {
+ customActions.add(CustomAction.fromCustomAction(customActionObj));
+ }
+ }
+ Bundle extras;
+ if (Build.VERSION.SDK_INT >= 22) {
+ extras = PlaybackStateCompatApi22.getExtras(stateObj);
+ } else {
+ extras = null;
+ }
+ PlaybackStateCompat state = new PlaybackStateCompat(
+ PlaybackStateCompatApi21.getState(stateObj),
+ PlaybackStateCompatApi21.getPosition(stateObj),
+ PlaybackStateCompatApi21.getBufferedPosition(stateObj),
+ PlaybackStateCompatApi21.getPlaybackSpeed(stateObj),
+ PlaybackStateCompatApi21.getActions(stateObj),
+ ERROR_CODE_UNKNOWN_ERROR,
+ PlaybackStateCompatApi21.getErrorMessage(stateObj),
+ PlaybackStateCompatApi21.getLastPositionUpdateTime(stateObj),
+ customActions,
+ PlaybackStateCompatApi21.getActiveQueueItemId(stateObj),
+ extras);
+ state.mStateObj = stateObj;
+ return state;
+ } else {
return null;
}
-
- List<Object> customActionObjs = PlaybackStateCompatApi21.getCustomActions(stateObj);
- List<PlaybackStateCompat.CustomAction> customActions = null;
- if (customActionObjs != null) {
- customActions = new ArrayList<>(customActionObjs.size());
- for (Object customActionObj : customActionObjs) {
- customActions.add(CustomAction.fromCustomAction(customActionObj));
- }
- }
- Bundle extras = Build.VERSION.SDK_INT >= 22
- ? PlaybackStateCompatApi22.getExtras(stateObj)
- : null;
- PlaybackStateCompat state = new PlaybackStateCompat(
- PlaybackStateCompatApi21.getState(stateObj),
- PlaybackStateCompatApi21.getPosition(stateObj),
- PlaybackStateCompatApi21.getBufferedPosition(stateObj),
- PlaybackStateCompatApi21.getPlaybackSpeed(stateObj),
- PlaybackStateCompatApi21.getActions(stateObj),
- ERROR_CODE_UNKNOWN_ERROR,
- PlaybackStateCompatApi21.getErrorMessage(stateObj),
- PlaybackStateCompatApi21.getLastPositionUpdateTime(stateObj),
- customActions,
- PlaybackStateCompatApi21.getActiveQueueItemId(stateObj),
- extras);
- state.mStateObj = stateObj;
- return state;
}
/**
@@ -753,25 +756,26 @@
* @return An equivalent {@link android.media.session.PlaybackState} object, or null if none.
*/
public Object getPlaybackState() {
- if (mStateObj != null || Build.VERSION.SDK_INT < 21) {
- return mStateObj;
- }
-
- List<Object> customActions = null;
- if (mCustomActions != null) {
- customActions = new ArrayList<>(mCustomActions.size());
- for (PlaybackStateCompat.CustomAction customAction : mCustomActions) {
- customActions.add(customAction.getCustomAction());
+ if (mStateObj == null && Build.VERSION.SDK_INT >= 21) {
+ List<Object> customActions = null;
+ if (mCustomActions != null) {
+ customActions = new ArrayList<>(mCustomActions.size());
+ for (PlaybackStateCompat.CustomAction customAction : mCustomActions) {
+ customActions.add(customAction.getCustomAction());
+ }
}
- }
- if (Build.VERSION.SDK_INT >= 22) {
- mStateObj = PlaybackStateCompatApi22.newInstance(mState, mPosition, mBufferedPosition,
- mSpeed, mActions, mErrorMessage, mUpdateTime,
- customActions, mActiveItemId, mExtras);
- } else {
- mStateObj = PlaybackStateCompatApi21.newInstance(mState, mPosition, mBufferedPosition,
- mSpeed, mActions, mErrorMessage, mUpdateTime,
- customActions, mActiveItemId);
+ if (Build.VERSION.SDK_INT >= 22) {
+ mStateObj = PlaybackStateCompatApi22.newInstance(mState, mPosition,
+ mBufferedPosition,
+ mSpeed, mActions, mErrorMessage, mUpdateTime,
+ customActions, mActiveItemId, mExtras);
+ } else if (Build.VERSION.SDK_INT >= 21) {
+ // The extra conditional is necessary to pass the NewApi Lint inspection.
+ mStateObj = PlaybackStateCompatApi21.newInstance(mState, mPosition,
+ mBufferedPosition,
+ mSpeed, mActions, mErrorMessage, mUpdateTime,
+ customActions, mActiveItemId);
+ }
}
return mStateObj;
}
diff --git a/media-compat/tests/src/android/support/v4/media/StubMediaBrowserServiceCompat.java b/media-compat/tests/src/android/support/v4/media/StubMediaBrowserServiceCompat.java
index b943594..d93af38 100644
--- a/media-compat/tests/src/android/support/v4/media/StubMediaBrowserServiceCompat.java
+++ b/media-compat/tests/src/android/support/v4/media/StubMediaBrowserServiceCompat.java
@@ -45,7 +45,7 @@
MEDIA_ID_CHILDREN_DELAYED
};
- static final String SEARCH_QUERY = "test_media_children";
+ static final String SEARCH_QUERY = "children_2";
static final String SEARCH_QUERY_FOR_NO_RESULT = "query no result";
static final String SEARCH_QUERY_FOR_ERROR = "query for error";
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..d461ed2 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
@@ -24,7 +24,6 @@
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 +31,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;
@@ -90,15 +88,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());
}
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..978da6c 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();
@@ -316,9 +311,6 @@
@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,9 +331,6 @@
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();
@@ -361,10 +350,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 +605,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;
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/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/SupportAnimationDemos/Android.mk b/samples/SupportAnimationDemos/Android.mk
new file mode 100644
index 0000000..bbc786a
--- /dev/null
+++ b/samples/SupportAnimationDemos/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+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 := SupportAnimationDemos
+LOCAL_MODULE_TAGS := samples
+LOCAL_SDK_VERSION := current
+LOCAL_MIN_SDK_VERSION := 16
+LOCAL_DEX_PREOPT := false
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_STATIC_ANDROID_LIBRARIES := \
+ android-support-dynamic-animation
+LOCAL_AAPT_FLAGS := --no-version-vectors
+include $(BUILD_PACKAGE)
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%
rename from dynamic-animation/AndroidManifest-make.xml
rename 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/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/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/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/SupportLeanbackJank/build.gradle b/samples/SupportLeanbackJank/build.gradle
index 976dc9b..42adb9a 100644
--- a/samples/SupportLeanbackJank/build.gradle
+++ b/samples/SupportLeanbackJank/build.gradle
@@ -21,7 +21,7 @@
}
lintOptions {
- abortOnError false
+ abortOnError true
}
compileOptions {
diff --git a/samples/SupportLeanbackJank/res/values-v21/styles.xml b/samples/SupportLeanbackJank/res/values-v21/styles.xml
new file mode 100644
index 0000000..ef7efe9
--- /dev/null
+++ b/samples/SupportLeanbackJank/res/values-v21/styles.xml
@@ -0,0 +1,24 @@
+<?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
+ -->
+
+<resources>
+ <style name="JankApp" parent="Theme.Leanback">
+ <item name="android:colorPrimary">@color/jank_yellow</item>
+ <item name="android:windowAllowReturnTransitionOverlap">true</item>
+ <item name="android:windowAllowEnterTransitionOverlap">true</item>
+ </style>
+</resources>
\ No newline at end of file
diff --git a/samples/SupportLeanbackJank/res/values/styles.xml b/samples/SupportLeanbackJank/res/values/styles.xml
index ef7efe9..ba3a5de 100644
--- a/samples/SupportLeanbackJank/res/values/styles.xml
+++ b/samples/SupportLeanbackJank/res/values/styles.xml
@@ -17,8 +17,5 @@
<resources>
<style name="JankApp" parent="Theme.Leanback">
- <item name="android:colorPrimary">@color/jank_yellow</item>
- <item name="android:windowAllowReturnTransitionOverlap">true</item>
- <item name="android:windowAllowEnterTransitionOverlap">true</item>
</style>
</resources>
\ No newline at end of file
diff --git a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/data/VideoProvider.java b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/data/VideoProvider.java
index a9e0dd5..909da45 100644
--- a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/data/VideoProvider.java
+++ b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/data/VideoProvider.java
@@ -131,7 +131,8 @@
canvas.drawText(string, width / 2, (height + rect.height()) / 2, paint);
- try (FileOutputStream outputStream = new FileOutputStream(file)) {
+ try {
+ FileOutputStream outputStream = new FileOutputStream(file);
bitmap.compress(CompressFormat.JPEG, 90, outputStream);
} catch (IOException e) {
Log.e(TAG, "Cannot write image to file: " + file, e);
diff --git a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/CardPresenter.java b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/CardPresenter.java
index 564ff92..d301c4e 100644
--- a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/CardPresenter.java
+++ b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/CardPresenter.java
@@ -18,6 +18,7 @@
import android.support.v17.leanback.widget.ImageCardView;
import android.support.v17.leanback.widget.Presenter;
+import android.support.v4.content.res.ResourcesCompat;
import android.view.ViewGroup;
import com.bumptech.glide.Glide;
@@ -37,8 +38,10 @@
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
- mDefaultBackgroundColor = parent.getResources().getColor(R.color.jank_blue, null);
- mSelectedBackgroundColor = parent.getResources().getColor(R.color.jank_red, null);
+ mDefaultBackgroundColor =
+ ResourcesCompat.getColor(parent.getResources(), R.color.jank_blue, null);
+ mSelectedBackgroundColor =
+ ResourcesCompat.getColor(parent.getResources(), R.color.jank_red, null);
ImageCardView cardView = new ImageCardView(parent.getContext()) {
@Override
diff --git a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/GridItemPresenter.java b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/GridItemPresenter.java
index ff99a9b..3374f5e 100644
--- a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/GridItemPresenter.java
+++ b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/GridItemPresenter.java
@@ -19,6 +19,7 @@
import android.content.res.Resources;
import android.graphics.Color;
import android.support.v17.leanback.widget.Presenter;
+import android.support.v4.content.res.ResourcesCompat;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.TextView;
@@ -38,7 +39,8 @@
view.setLayoutParams(new ViewGroup.LayoutParams(width, height));
view.setFocusable(true);
view.setFocusableInTouchMode(true);
- view.setBackgroundColor(parent.getResources().getColor(R.color.jank_yellow, null));
+ view.setBackgroundColor(
+ ResourcesCompat.getColor(parent.getResources(), R.color.jank_yellow, null));
view.setTextColor(Color.WHITE);
view.setGravity(Gravity.CENTER);
return new ViewHolder(view);
diff --git a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/HeaderItemPresenter.java b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/HeaderItemPresenter.java
index 9740088..6d6b36f 100644
--- a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/HeaderItemPresenter.java
+++ b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/presenter/HeaderItemPresenter.java
@@ -22,6 +22,7 @@
import android.support.v17.leanback.widget.ListRow;
import android.support.v17.leanback.widget.Presenter;
import android.support.v17.leanback.widget.RowHeaderPresenter;
+import android.support.v4.content.res.ResourcesCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -53,7 +54,8 @@
rootView.setFocusable(true);
ImageView iconView = (ImageView) rootView.findViewById(R.id.header_icon);
- Drawable icon = rootView.getResources().getDrawable(R.drawable.android_header, null);
+ Drawable icon = ResourcesCompat.getDrawable(
+ rootView.getResources(), R.drawable.android_header, null);
iconView.setImageDrawable(icon);
TextView label = (TextView) rootView.findViewById(R.id.header_label);
diff --git a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/MainFragment.java b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/MainFragment.java
index 5cbff96..42abf3e 100644
--- a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/MainFragment.java
+++ b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/MainFragment.java
@@ -27,6 +27,7 @@
import android.support.v17.leanback.widget.ListRowPresenter;
import android.support.v17.leanback.widget.Presenter;
import android.support.v17.leanback.widget.PresenterSelector;
+import android.support.v4.content.res.ResourcesCompat;
import com.google.android.leanbackjank.IntentDefaults;
import com.google.android.leanbackjank.IntentKeys;
@@ -90,9 +91,9 @@
} else if (whichVideo == IntentKeys.VIDEO_480P_60FPS) {
resource = R.raw.bbb_480p;
}
- Uri uri = Uri.parse("android.resource://" + getContext().getPackageName() + "/"
+ Uri uri = Uri.parse("android.resource://" + getActivity().getPackageName() + "/"
+ resource);
- Intent videoIntent = new Intent(Intent.ACTION_VIEW, uri, getContext(),
+ Intent videoIntent = new Intent(Intent.ACTION_VIEW, uri, getActivity(),
VideoActivity.class);
startActivity(videoIntent);
}
@@ -102,19 +103,21 @@
mBackgroundManager = BackgroundManager.getInstance(getActivity());
mBackgroundManager.attach(getActivity().getWindow());
mBackgroundManager.setDrawable(
- getResources().getDrawable(R.drawable.default_background, null));
+ ResourcesCompat.getDrawable(getResources(), R.drawable.default_background, null));
}
private void setupUIElements() {
- setBadgeDrawable(getActivity().getResources().getDrawable(R.drawable.app_banner, null));
+ setBadgeDrawable(ResourcesCompat.getDrawable(
+ getActivity().getResources(), R.drawable.app_banner, null));
// Badge, when set, takes precedent over title
setTitle(getString(R.string.browse_title));
setHeadersState(HEADERS_ENABLED);
setHeadersTransitionOnBackEnabled(true);
// set headers background color
- setBrandColor(getResources().getColor(R.color.jank_yellow));
+ setBrandColor(ResourcesCompat.getColor(getResources(), R.color.jank_yellow, null));
// set search icon color
- setSearchAffordanceColor(getResources().getColor(R.color.search_opaque));
+ setSearchAffordanceColor(
+ ResourcesCompat.getColor(getResources(), R.color.search_opaque, null));
setHeaderPresenterSelector(new PresenterSelector() {
@Override
@@ -130,7 +133,7 @@
listRowPresenter.setShadowEnabled(!disableShadows);
mRowsAdapter = new ArrayObjectAdapter(listRowPresenter);
HashMap<String, List<VideoInfo>> data = VideoProvider.buildMedia(categoryCount,
- entriesPerCat, cardWidth, cardHeight, getContext(), useSingleBitmap);
+ entriesPerCat, cardWidth, cardHeight, getActivity(), useSingleBitmap);
CardPresenter cardPresenter = new CardPresenter(cardWidth, cardHeight);
int i = 0;
diff --git a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/VideoActivity.java b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/VideoActivity.java
index f026cc2..90c8552 100644
--- a/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/VideoActivity.java
+++ b/samples/SupportLeanbackJank/src/com/google/android/leanbackjank/ui/VideoActivity.java
@@ -21,6 +21,7 @@
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
@@ -48,7 +49,9 @@
setContentView(mVideoView);
if (checkIntent(getIntent())) {
- enterPictureInPictureMode();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ enterPictureInPictureMode();
+ }
}
}
diff --git a/samples/SupportPreferenceDemos/src/com/example/android/supportpreference/FragmentSupportPreferencesLeanback.java b/samples/SupportPreferenceDemos/src/com/example/android/supportpreference/FragmentSupportPreferencesLeanback.java
index f7babfb..eb9a4c0 100644
--- a/samples/SupportPreferenceDemos/src/com/example/android/supportpreference/FragmentSupportPreferencesLeanback.java
+++ b/samples/SupportPreferenceDemos/src/com/example/android/supportpreference/FragmentSupportPreferencesLeanback.java
@@ -16,6 +16,7 @@
package com.example.android.supportpreference;
+import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
@@ -26,6 +27,7 @@
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
+@TargetApi(17)
public class FragmentSupportPreferencesLeanback extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
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/settings.gradle b/settings.gradle
index 1597c2e..b46b4b7 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -135,6 +135,9 @@
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')
+
/////////////////////////////
//
// External
@@ -148,3 +151,7 @@
include ':jdiff'
project(':jdiff').projectDir = new File(externalRoot, 'jdiff')
+
+///// FLATFOOT START
+
+///// FLATFOOT END
\ No newline at end of file
diff --git a/tv-provider/src/android/support/media/tv/Channel.java b/tv-provider/src/android/support/media/tv/Channel.java
index 5e158e2..792143a 100644
--- a/tv-provider/src/android/support/media/tv/Channel.java
+++ b/tv-provider/src/android/support/media/tv/Channel.java
@@ -33,7 +33,33 @@
import java.net.URISyntaxException;
/**
- * 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 {
/**
diff --git a/tv-provider/src/android/support/media/tv/Program.java b/tv-provider/src/android/support/media/tv/Program.java
index 71c51fb..f8b4a85 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> {
/**
diff --git a/v13/java/android/support/v13/view/inputmethod/EditorInfoCompat.java b/v13/java/android/support/v13/view/inputmethod/EditorInfoCompat.java
index 4a6d3a0..92743c2 100644
--- a/v13/java/android/support/v13/view/inputmethod/EditorInfoCompat.java
+++ b/v13/java/android/support/v13/view/inputmethod/EditorInfoCompat.java
@@ -16,7 +16,7 @@
package android.support.v13.view.inputmethod;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
@@ -102,7 +102,7 @@
}
}
- @TargetApi(25)
+ @RequiresApi(25)
private static final class EditorInfoCompatApi25Impl implements EditorInfoCompatImpl {
@Override
public void setContentMimeTypes(@NonNull EditorInfo editorInfo,
diff --git a/v13/java/android/support/v13/view/inputmethod/InputConnectionCompat.java b/v13/java/android/support/v13/view/inputmethod/InputConnectionCompat.java
index ba16fd0..5999575 100644
--- a/v13/java/android/support/v13/view/inputmethod/InputConnectionCompat.java
+++ b/v13/java/android/support/v13/view/inputmethod/InputConnectionCompat.java
@@ -16,7 +16,7 @@
package android.support.v13.view.inputmethod;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.content.ClipDescription;
import android.net.Uri;
import android.os.Build;
@@ -130,7 +130,7 @@
}
}
- @TargetApi(25)
+ @RequiresApi(25)
private static final class InputContentInfoCompatApi25Impl
implements InputConnectionCompatImpl {
@Override
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/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/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/FragmentUtil.java b/v17/leanback/src/android/support/v17/leanback/app/FragmentUtil.java
index 23c6039..b555698 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/FragmentUtil.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/FragmentUtil.java
@@ -15,14 +15,14 @@
*/
package android.support.v17.leanback.app;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.app.Fragment;
import android.content.Context;
import android.os.Build;
class FragmentUtil {
- @TargetApi(23)
+ @RequiresApi(23)
private static Context getContextNew(Fragment fragment) {
return fragment.getContext();
}
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..c7b57f4 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackFragment.java
@@ -594,6 +594,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.
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..4dfea3b 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
@@ -610,6 +610,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.
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..de94173 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
@@ -613,6 +613,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.
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..298570c 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackSupportFragment.java
@@ -597,6 +597,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.
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/graphics/FitWidthBitmapDrawable.java b/v17/leanback/src/android/support/v17/leanback/graphics/FitWidthBitmapDrawable.java
index d1e28de..6300ff2 100644
--- a/v17/leanback/src/android/support/v17/leanback/graphics/FitWidthBitmapDrawable.java
+++ b/v17/leanback/src/android/support/v17/leanback/graphics/FitWidthBitmapDrawable.java
@@ -15,7 +15,7 @@
*/
package android.support.v17.leanback.graphics;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
@@ -228,7 +228,7 @@
}
}
- @TargetApi(24)
+ @RequiresApi(24)
static IntProperty<FitWidthBitmapDrawable> getVerticalOffsetIntProperty() {
return new IntProperty<FitWidthBitmapDrawable>("verticalOffset") {
@Override
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/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/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/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/values/attrs.xml b/v7/appcompat/res/values/attrs.xml
index c140a67..f31524e 100644
--- a/v7/appcompat/res/values/attrs.xml
+++ b/v7/appcompat/res/values/attrs.xml
@@ -634,10 +634,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/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/AppCompatDelegate.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegate.java
index 3d37b1f..d2852de 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegate.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegate.java
@@ -195,14 +195,13 @@
private static AppCompatDelegate create(Context context, Window window,
AppCompatCallback callback) {
- final int sdk = Build.VERSION.SDK_INT;
if (BuildCompat.isAtLeastN()) {
return new AppCompatDelegateImplN(context, window, callback);
- } else if (sdk >= 23) {
+ } else if (Build.VERSION.SDK_INT >= 23) {
return new AppCompatDelegateImplV23(context, window, callback);
- } else if (sdk >= 14) {
+ } else if (Build.VERSION.SDK_INT >= 14) {
return new AppCompatDelegateImplV14(context, window, callback);
- } else if (sdk >= 11) {
+ } else if (Build.VERSION.SDK_INT >= 11) {
return new AppCompatDelegateImplV11(context, window, callback);
} else {
return new AppCompatDelegateImplV9(context, window, callback);
diff --git a/v7/appcompat/src/android/support/v7/app/NotificationCompat.java b/v7/appcompat/src/android/support/v7/app/NotificationCompat.java
index 17f858b..2f5082a 100644
--- a/v7/appcompat/src/android/support/v7/app/NotificationCompat.java
+++ b/v7/appcompat/src/android/support/v7/app/NotificationCompat.java
@@ -191,6 +191,7 @@
return new TextAppearanceSpan(null, 0, 0, ColorStateList.valueOf(color), null);
}
+ @RequiresApi(16)
private static void addMessagingFallBackStyle(MessagingStyle style,
NotificationBuilderWithBuilderAccessor builder,
android.support.v4.app.NotificationCompat.Builder b) {
@@ -441,6 +442,7 @@
}
}
+ @RequiresApi(14)
private static class IceCreamSandwichExtender extends BuilderExtender {
IceCreamSandwichExtender() {
@@ -462,6 +464,7 @@
}
}
+ @RequiresApi(16)
private static class JellybeanExtender extends BuilderExtender {
JellybeanExtender() {
@@ -482,6 +485,7 @@
}
}
+ @RequiresApi(21)
private static class LollipopExtender extends BuilderExtender {
LollipopExtender() {
@@ -503,6 +507,7 @@
}
}
+ @RequiresApi(24)
private static class Api24Extender extends BuilderExtender {
@Override
diff --git a/v7/appcompat/src/android/support/v7/app/ResourcesFlusher.java b/v7/appcompat/src/android/support/v7/app/ResourcesFlusher.java
index ebfc7cb..8454078 100644
--- a/v7/appcompat/src/android/support/v7/app/ResourcesFlusher.java
+++ b/v7/appcompat/src/android/support/v7/app/ResourcesFlusher.java
@@ -16,7 +16,7 @@
package android.support.v7.app;
-import android.annotation.TargetApi;
+import android.support.annotation.RequiresApi;
import android.content.res.Resources;
import android.os.Build;
import android.support.annotation.NonNull;
@@ -52,7 +52,7 @@
return false;
}
- @TargetApi(21)
+ @RequiresApi(21)
private static boolean flushLollipops(@NonNull final Resources resources) {
if (!sDrawableCacheFieldFetched) {
try {
@@ -78,7 +78,7 @@
return false;
}
- @TargetApi(23)
+ @RequiresApi(23)
private static boolean flushMarshmallows(@NonNull final Resources resources) {
if (!sDrawableCacheFieldFetched) {
try {
@@ -107,7 +107,7 @@
return drawableCache != null && flushThemedResourcesCache(drawableCache);
}
- @TargetApi(24)
+ @RequiresApi(24)
private static boolean flushNougats(@NonNull final Resources resources) {
if (!sResourcesImplFieldFetched) {
try {
@@ -158,7 +158,7 @@
return drawableCache != null && flushThemedResourcesCache(drawableCache);
}
- @TargetApi(16)
+ @RequiresApi(16)
private static boolean flushThemedResourcesCache(@NonNull final Object cache) {
if (!sThemedResourceCacheClazzFetched) {
try {
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..2779857 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;
}
@@ -163,6 +176,13 @@
}
@Override
+ public MenuItem setAlphabeticShortcut(char alphaChar, int alphaModifiers) {
+ mShortcutAlphabeticChar = alphaChar;
+ mShortcutAlphabeticModifiers = KeyEvent.normalizeMetaState(alphaModifiers);
+ return this;
+ }
+
+ @Override
public MenuItem setCheckable(boolean checkable) {
mFlags = (mFlags & ~CHECKABLE) | (checkable ? CHECKABLE : 0);
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;
@@ -225,6 +252,16 @@
}
@Override
+ public MenuItem setShortcut(char numericChar, char alphaChar, int numericModifiers,
+ int alphaModifiers) {
+ mShortcutNumericChar = numericChar;
+ mShortcutNumericModifiers = KeyEvent.normalizeMetaState(numericModifiers);
+ mShortcutAlphabeticChar = alphaChar;
+ mShortcutAlphabeticModifiers = KeyEvent.normalizeMetaState(alphaModifiers);
+ return this;
+ }
+
+ @Override
public MenuItem setTitle(CharSequence title) {
mTitle = title;
return this;
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/SwitchCompat.java b/v7/appcompat/src/android/support/v7/widget/SwitchCompat.java
index 3d2fa6d..72c20b5 100644
--- a/v7/appcompat/src/android/support/v7/widget/SwitchCompat.java
+++ b/v7/appcompat/src/android/support/v7/widget/SwitchCompat.java
@@ -17,7 +17,6 @@
package android.support.v7.widget;
import android.animation.ObjectAnimator;
-import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -81,7 +80,6 @@
* @attr ref android.support.v7.appcompat.R.styleable#SwitchCompat_track
*/
@RequiresApi(14)
-@TargetApi(14)
public class SwitchCompat extends CompoundButton {
private static final int THUMB_ANIMATION_DURATION = 250;
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/BaseBasicsTestCase.java b/v7/appcompat/tests/src/android/support/v7/app/BaseBasicsTestCase.java
index 3aa7259..ecdc64f 100644
--- a/v7/appcompat/tests/src/android/support/v7/app/BaseBasicsTestCase.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/BaseBasicsTestCase.java
@@ -35,6 +35,7 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import android.support.annotation.RequiresApi;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.SdkSuppress;
import android.support.test.filters.SmallTest;
@@ -77,6 +78,7 @@
@Test
@SdkSuppress(minSdkVersion = 16)
+ @RequiresApi(16)
public void testFitSystemWindowsReachesContent() {
final FitWindowsContentLayout content =
(FitWindowsContentLayout) getActivity().findViewById(R.id.test_content);
@@ -91,6 +93,7 @@
@Test
@SdkSuppress(minSdkVersion = 21)
+ @RequiresApi(21)
public void testOnApplyWindowInsetsReachesContent() {
final View content = getActivity().findViewById(R.id.test_content);
assertNotNull(content);
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/app/LayoutInflaterFactoryTestCase.java b/v7/appcompat/tests/src/android/support/v7/app/LayoutInflaterFactoryTestCase.java
index 0502ad4..64c63a0 100644
--- a/v7/appcompat/tests/src/android/support/v7/app/LayoutInflaterFactoryTestCase.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/LayoutInflaterFactoryTestCase.java
@@ -20,6 +20,7 @@
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import android.support.annotation.RequiresApi;
import android.content.Context;
import android.content.res.Resources;
import android.support.test.annotation.UiThreadTest;
@@ -77,6 +78,7 @@
// Propagation of themed context to children only works on API 11+.
@SdkSuppress(minSdkVersion = 11)
+ @RequiresApi(11)
@UiThreadTest
@Test
@SmallTest
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/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/RemoteControlClientCompat.java b/v7/mediarouter/src/android/support/v7/media/RemoteControlClientCompat.java
index c5dede8..085d6ff 100644
--- a/v7/mediarouter/src/android/support/v7/media/RemoteControlClientCompat.java
+++ b/v7/mediarouter/src/android/support/v7/media/RemoteControlClientCompat.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.media.AudioManager;
import android.os.Build;
+import android.support.annotation.RequiresApi;
import java.lang.ref.WeakReference;
@@ -118,6 +119,7 @@
* other API available to do so in this platform version. The UserRouteInfo itself
* is not attached to the MediaRouter so it is transparent to the user.
*/
+ @RequiresApi(16)
static class JellybeanImpl extends RemoteControlClientCompat {
private final Object mRouterObj;
private final Object mUserRouteCategoryObj;
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/mediarouter/src/android/support/v7/media/SystemMediaRouteProvider.java b/v7/mediarouter/src/android/support/v7/media/SystemMediaRouteProvider.java
index 0833be3..42d0b2a 100644
--- a/v7/mediarouter/src/android/support/v7/media/SystemMediaRouteProvider.java
+++ b/v7/mediarouter/src/android/support/v7/media/SystemMediaRouteProvider.java
@@ -24,6 +24,7 @@
import android.content.res.Resources;
import android.media.AudioManager;
import android.os.Build;
+import android.support.annotation.RequiresApi;
import android.support.v7.mediarouter.R;
import android.view.Display;
@@ -212,6 +213,7 @@
/**
* Jellybean implementation.
*/
+ @RequiresApi(16)
static class JellybeanImpl extends SystemMediaRouteProvider
implements MediaRouterJellybean.Callback, MediaRouterJellybean.VolumeCallback {
private static final ArrayList<IntentFilter> LIVE_AUDIO_CONTROL_FILTERS;
@@ -731,6 +733,7 @@
/**
* Jellybean MR1 implementation.
*/
+ @RequiresApi(17)
private static class JellybeanMr1Impl extends JellybeanImpl
implements MediaRouterJellybeanMr1.Callback {
private MediaRouterJellybeanMr1.ActiveScanWorkaround mActiveScanWorkaround;
@@ -807,6 +810,7 @@
/**
* Jellybean MR2 implementation.
*/
+ @RequiresApi(18)
private static class JellybeanMr2Impl extends JellybeanMr1Impl {
public JellybeanMr2Impl(Context context, SyncCallback syncCallback) {
super(context, syncCallback);
@@ -864,6 +868,7 @@
/**
* Api24 implementation.
*/
+ @RequiresApi(24)
private static class Api24Impl extends JellybeanMr2Impl {
public Api24Impl(Context context, SyncCallback syncCallback) {
super(context, syncCallback);
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;