Port P rotation lock action to Fling too

When rotation lock is enabled and the user rotates the device, if
the current app supports rotation, show an additional rotation icon
in the right area of the navbar (4 seconds).
Then a single tap on this area will trigger the rotation.
diff --git a/res/layout-sw600dp/fling_bar.xml b/res/layout-sw600dp/fling_bar.xml
index 28912e4..ac6fbda 100644
--- a/res/layout-sw600dp/fling_bar.xml
+++ b/res/layout-sw600dp/fling_bar.xml
@@ -52,10 +52,13 @@
                 android:layout_weight="0"
                 android:src="@drawable/ic_eos_fling" />
 
-            <Space
+            <ImageView
+                android:id="@+id/rotationLogo"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
-                android:layout_weight="1"/>
+                android:src="@drawable/ic_sysbar_rotate_button"
+                android:layout_weight="1"
+                android:visibility="invisible" />
 
         </LinearLayout>
     </FrameLayout>
@@ -77,10 +80,13 @@
             android:animateLayoutChanges="true"
             >
 
-            <Space
+            <ImageView
+                android:id="@+id/rotationLogo"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
-                android:layout_weight="1"/>
+                android:src="@drawable/ic_sysbar_rotate_button"
+                android:layout_weight="1"
+                android:visibility="invisible" />
 
             <!-- navigation controls -->
             <com.android.systemui.navigation.fling.FlingLogoView
diff --git a/res/layout/fling_bar.xml b/res/layout/fling_bar.xml
index 83a4674..851ffc8 100644
--- a/res/layout/fling_bar.xml
+++ b/res/layout/fling_bar.xml
@@ -38,7 +38,7 @@
             android:clipToPadding="false"
             android:orientation="horizontal" >
 
-            <View
+            <Space
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:layout_weight="1"
@@ -52,9 +52,11 @@
                 android:layout_weight="0"
                 android:src="@drawable/ic_eos_fling" />
 
-            <View
+            <ImageView
+                android:id="@+id/rotationLogo"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
+                android:src="@drawable/ic_sysbar_rotate_button"
                 android:layout_weight="1"
                 android:visibility="invisible" />
         </LinearLayout>
@@ -77,9 +79,11 @@
             android:clipToPadding="false"
             android:orientation="vertical" >
 
-            <View
+            <ImageView
+                android:id="@+id/rotationLogo"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
+                android:src="@drawable/ic_sysbar_rotate_button"
                 android:layout_weight="1"
                 android:visibility="invisible" />
 
@@ -91,7 +95,7 @@
                 android:layout_weight="0"
                 android:src="@drawable/ic_eos_fling_land" />
 
-            <View
+            <Space
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:layout_weight="1"
diff --git a/src/com/android/systemui/navigation/BaseNavigationBar.java b/src/com/android/systemui/navigation/BaseNavigationBar.java
index 74cc638..0c4e649 100644
--- a/src/com/android/systemui/navigation/BaseNavigationBar.java
+++ b/src/com/android/systemui/navigation/BaseNavigationBar.java
@@ -27,6 +27,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.navigation.Navigator;
 import com.android.systemui.navigation.Res;
 import com.android.systemui.navigation.NavbarOverlayResources;
@@ -35,6 +36,7 @@
 import com.android.systemui.navigation.utils.SmartObserver;
 import com.android.systemui.plugins.statusbar.phone.NavGesture;
 import com.android.systemui.statusbar.phone.BarTransitions;
+import com.android.systemui.statusbar.policy.RotationLockController;
 import com.android.systemui.R;
 
 import com.android.internal.utils.du.DUActionUtils;
@@ -108,6 +110,8 @@
     protected boolean mCarMode = false;
     protected boolean mDockedStackExists;
 
+    private RotationLockController mRotationLockController;
+
     private class H extends Handler {
         public void handleMessage(Message m) {
             switch (m.what) {
@@ -182,6 +186,12 @@
         filter.addAction(Intent.ACTION_SCREEN_OFF);
         filter.addAction(Intent.ACTION_BOOT_COMPLETED);
         context.registerReceiver(mReceiver, filter);
+
+        mRotationLockController = Dependency.get(RotationLockController.class);
+    }
+
+    protected RotationLockController getRotationController() {
+        return mRotationLockController;
     }
 
     // require implementation
diff --git a/src/com/android/systemui/navigation/NavbarOverlayResources.java b/src/com/android/systemui/navigation/NavbarOverlayResources.java
index f540253..9f7158c 100644
--- a/src/com/android/systemui/navigation/NavbarOverlayResources.java
+++ b/src/com/android/systemui/navigation/NavbarOverlayResources.java
@@ -31,7 +31,6 @@
 import android.graphics.drawable.Drawable;
 
     public class NavbarOverlayResources extends ActionIconResources {
-
 //      public int mOpaque;
 //      public int mSemiTransparent;
 //      public int mTransparent;
@@ -39,6 +38,8 @@
         public Drawable mGradient;
         public Drawable mFlingLogo;
         public Drawable mFlingLogoDark;
+        public Drawable mFlingRotationLogo;
+        public Drawable mFlingRotationLogoDark;
         public Drawable mLightsOutLarge;
 
     public NavbarOverlayResources(Context ctx, Resources res) {
@@ -50,8 +51,10 @@
         mGradient = res.getDrawable(R.drawable.nav_background);
         mFlingLogo = res.getDrawable(R.drawable.ic_eos_fling);
         mFlingLogoDark = res.getDrawable(R.drawable.ic_eos_fling_dark);
+        mFlingRotationLogo = res.getDrawable(R.drawable.ic_sysbar_rotate_button);
+        mFlingRotationLogoDark = res.getDrawable(R.drawable.ic_sysbar_rotate_button_dark);
         mLightsOutLarge = res.getDrawable(R.drawable.ic_sysbar_lights_out_dot_large);
-        }
+    }
 
     public void updateResources(Resources res) {
         super.updateResources(res);
@@ -64,6 +67,8 @@
         mGradient.setBounds(bounds);
         mFlingLogo = res.getDrawable(R.drawable.ic_eos_fling);
         mFlingLogoDark = res.getDrawable(R.drawable.ic_eos_fling_dark);
+        mFlingRotationLogo = res.getDrawable(R.drawable.ic_sysbar_rotate_button);
+        mFlingRotationLogoDark = res.getDrawable(R.drawable.ic_sysbar_rotate_button_dark);
         mLightsOutLarge = res.getDrawable(R.drawable.ic_sysbar_lights_out_dot_large);
     }
 }
diff --git a/src/com/android/systemui/navigation/fling/FlingActionHandler.java b/src/com/android/systemui/navigation/fling/FlingActionHandler.java
index 3adaba6..508d06d 100644
--- a/src/com/android/systemui/navigation/fling/FlingActionHandler.java
+++ b/src/com/android/systemui/navigation/fling/FlingActionHandler.java
@@ -204,6 +204,11 @@
 
     @Override
     public void onSingleRightPress() {
+        if (((FlingView)mHost).isRotateButtonVisible()) {
+            ((FlingView)mHost).rotate();
+            return;
+        }
+
         if (mUseKbCursors) {
             ActionHandler.performTask(mContext, ActionHandler.SYSTEMUI_TASK_HOME);
             return;
@@ -308,7 +313,7 @@
         mOnTapPreloadedRecents = false;
         for (String flingAction : (isRight? mRightTapActions : mLeftTapActions)) {
             ActionConfig action = (ActionConfig) mActionMap.get(flingAction);
-            if (!mUseKbCursors && action != null && !action.hasNoAction() && action.isActionRecents()) {
+            if (!mUseKbCursors && !((FlingView)mHost).isRotateButtonVisible() && action != null && !action.hasNoAction() && action.isActionRecents()) {
                 ActionHandler.preloadRecentApps();
                 mOnTapPreloadedRecents = true;
                 return;
diff --git a/src/com/android/systemui/navigation/fling/FlingBarTransitions.java b/src/com/android/systemui/navigation/fling/FlingBarTransitions.java
index 28f7206..9b1dc03 100644
--- a/src/com/android/systemui/navigation/fling/FlingBarTransitions.java
+++ b/src/com/android/systemui/navigation/fling/FlingBarTransitions.java
@@ -64,6 +64,15 @@
         if (hidden != null && hidden instanceof DarkIntensity) {
             ((DarkIntensity) hidden).setDarkIntensity(darkIntensity);
         }
+
+        Drawable rotationCurrent = mView.getRotationLogoDrawable(false);
+        if (rotationCurrent != null && rotationCurrent instanceof DarkIntensity) {
+            ((DarkIntensity) rotationCurrent).setDarkIntensity(darkIntensity);
+        }
+        Drawable rotationHidden = mView.getRotationLogoDrawable(true);
+        if (rotationHidden != null && rotationHidden instanceof DarkIntensity) {
+            ((DarkIntensity) rotationHidden).setDarkIntensity(darkIntensity);
+        }
     }
 
     @Override
diff --git a/src/com/android/systemui/navigation/fling/FlingLogoController.java b/src/com/android/systemui/navigation/fling/FlingLogoController.java
index 312eb4f..b8720d0 100644
--- a/src/com/android/systemui/navigation/fling/FlingLogoController.java
+++ b/src/com/android/systemui/navigation/fling/FlingLogoController.java
@@ -242,6 +242,15 @@
         hiddenLogo.setImageDrawable(getCurrentDrawable());
         updateButtonScalingAndPadding(currentLogo, mLogoConfig, mHost.isLandscape());
         updateButtonScalingAndPadding(hiddenLogo, mLogoConfig, !mHost.isLandscape());
+
+        ImageView currentRotationLogo = (ImageView)current.findViewById(R.id.rotationLogo);
+        ImageView hiddenRotationLogo = (ImageView)hidden.findViewById(R.id.rotationLogo);
+        currentRotationLogo.setImageDrawable(null);
+        currentRotationLogo.setImageDrawable(getCurrentRotationDrawable());
+        hiddenRotationLogo.setImageDrawable(null);
+        hiddenRotationLogo.setImageDrawable(getCurrentRotationDrawable());
+        updateButtonScalingAndPadding(currentRotationLogo, mLogoConfig, mHost.isLandscape());
+        updateButtonScalingAndPadding(hiddenRotationLogo, mLogoConfig, !mHost.isLandscape());
     }
 
     Drawable getCurrentDrawable() {
@@ -256,12 +265,20 @@
             d = KeyButtonDrawable.create(light, dark);
             return d;
         }
+
         light = mHost.mResourceMap.mFlingLogo;
         dark = mHost.mResourceMap.mFlingLogoDark;
         d = KeyButtonDrawable.create(light, dark);
         return d;
     }
 
+    Drawable getCurrentRotationDrawable() {
+        Drawable light = mHost.mResourceMap.mFlingRotationLogo;
+        Drawable dark = mHost.mResourceMap.mFlingRotationLogoDark;
+        KeyButtonDrawable d = KeyButtonDrawable.create(light, dark);
+        return d;
+    }
+
     // Helper to flatten AdaptiveIconDrawable layers to a single drawable
     private static BitmapDrawable getBitmapDrawable(Context ctx, Drawable d) {
         if (d instanceof BitmapDrawable) {
diff --git a/src/com/android/systemui/navigation/fling/FlingView.java b/src/com/android/systemui/navigation/fling/FlingView.java
index 70e4773..c02ec8e 100644
--- a/src/com/android/systemui/navigation/fling/FlingView.java
+++ b/src/com/android/systemui/navigation/fling/FlingView.java
@@ -94,6 +94,9 @@
 
     private int mNavigationIconHints = 0;
 
+    private boolean mRotateButtonVisible;
+    private int mLastRotation = 0;
+
     private SmartObservable mObservable = new SmartObservable() {
         @Override
         public Set<Uri> onGetUris() {
@@ -344,6 +347,16 @@
         return getLogoView(hiddenView ? getHiddenView() : getCurrentView()).getDrawable();
     }
 
+    private ImageView getRotationLogoView(View v) {
+        final ViewGroup viewGroup = (ViewGroup) v;
+        ImageView rotationLogoView = (ImageView)viewGroup.findViewById(R.id.rotationLogo);
+        return rotationLogoView;
+    }
+
+    public Drawable getRotationLogoDrawable(boolean hiddenView) {
+        return getRotationLogoView(hiddenView ? getHiddenView() : getCurrentView()).getDrawable();
+    }
+
     @Override
     protected void onInflateFromUser() {
         mGestureHandler.onScreenStateChanged(mScreenOn);
@@ -373,6 +386,59 @@
     }
 
     @Override
+    public void setRotateSuggestionButtonState(boolean visible, boolean skipAnim) {
+        mRotateButtonVisible = visible;
+        //skipAnim
+        onRotationButtonStateChange(visible);
+        // this will set also the correct darkintensity for the rotation logo
+        setNavigationIconHints(mNavigationIconHints, true);
+    }
+
+    @Override
+    public void setLastRotation(int rotation) {
+        mLastRotation = rotation;
+    }
+
+    public void rotate() {
+        getRotationController().setRotationLockedAtAngle(true, mLastRotation);
+    }
+
+    public boolean isRotateButtonVisible() {
+        return mRotateButtonVisible;
+    }
+
+    public void onRotationButtonStateChange(boolean visible) {
+        ImageView hidden = getRotationLogoView(getHiddenView());
+        ImageView current = getRotationLogoView(getCurrentView());
+        if (visible) {
+            hidden.setVisibility(View.VISIBLE);
+            current.setVisibility(View.VISIBLE);
+            current.setAlpha(0.0f);
+            current.animate()
+                    .setListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationEnd(Animator _a) {
+                        }
+                    })
+                    .alpha(1.0f)
+                    .setDuration(100)
+                    .start();
+        } else {
+            current.animate()
+                    .alpha(0.0f)
+                    .setDuration(100)
+                    .setListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationEnd(Animator _a) {
+                            hidden.setVisibility(View.INVISIBLE);
+                            current.setVisibility(View.INVISIBLE);
+                        }
+                    })
+                    .start();
+        }
+    }
+
+    @Override
     public void onDraw(Canvas canvas) {
         super.onDraw(canvas);
         if (mRippleEnabled) {
diff --git a/src/com/android/systemui/navigation/smartbar/SmartBarView.java b/src/com/android/systemui/navigation/smartbar/SmartBarView.java
index 44c9ea6..d8f906c 100644
--- a/src/com/android/systemui/navigation/smartbar/SmartBarView.java
+++ b/src/com/android/systemui/navigation/smartbar/SmartBarView.java
@@ -58,7 +58,6 @@
 import com.android.internal.utils.du.Config;
 import com.android.internal.utils.du.Config.ActionConfig;
 import com.android.internal.utils.du.Config.ButtonConfig;
-import com.android.systemui.Dependency;
 import com.android.systemui.navigation.BaseEditor;
 import com.android.systemui.navigation.BaseNavigationBar;
 import com.android.systemui.navigation.Editor;
@@ -76,7 +75,6 @@
 import com.android.systemui.statusbar.phone.BarTransitions;
 import com.android.systemui.statusbar.phone.LightBarTransitionsController;
 import com.android.systemui.statusbar.policy.KeyButtonDrawable;
-import com.android.systemui.statusbar.policy.RotationLockController;
 import com.android.systemui.R;
 
 import java.util.ArrayList;
@@ -163,7 +161,6 @@
 
     private boolean mRotateButtonVisible;
     private int mLastRotation = 0;
-    private RotationLockController mRotationLockController;
 
     @Override
     public void onReceive(Intent intent) {
@@ -205,7 +202,7 @@
     }
 
     public void rotate() {
-        mRotationLockController.setRotationLockedAtAngle(true, mLastRotation);
+        getRotationController().setRotationLockedAtAngle(true, mLastRotation);
     }
 
     public SmartBarView(Context context) {
@@ -226,8 +223,6 @@
                 return true;
             }
         });
-
-        mRotationLockController = Dependency.get(RotationLockController.class);
     }
 
     private final OnTouchListener mSmartBarTouchListener = new OnTouchListener() {