Fix navigation bar order in seascape

This reverts the revert in commit c44368016a192dfe381f5f73c07be42e705e64db,
thus reapplying 27315acfbbf9921e760647e2e96e74ec7de6015a.

Also fixes the bug that was the reason this needed to be reverted and
fixes a case where the order was not correctly updated (landscape to
seascape or vice versa)

Fixes: 29612635
Change-Id: Id51cf7edaeeea16cba08bcd5a30313f58fa00d4d
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index dd46b08..67699737 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -28,7 +28,6 @@
 import android.widget.Space;
 
 import com.android.systemui.R;
-import com.android.systemui.SystemUIFactory;
 import com.android.systemui.statusbar.policy.KeyButtonView;
 import com.android.systemui.tuner.TunerService;
 
@@ -71,6 +70,8 @@
     private View mLastRot0;
     private View mLastRot90;
 
+    private boolean mAlternativeOrder;
+
     public NavigationBarInflaterView(Context context, AttributeSet attrs) {
         super(context, attrs);
         mDensity = context.getResources().getConfiguration().densityDpi;
@@ -114,6 +115,7 @@
                 false);
         mRot90.setId(R.id.rot90);
         addView(mRot90);
+        updateAlternativeOrder();
         if (getParent() instanceof NavigationBarView) {
             ((NavigationBarView) getParent()).updateRotatedViews();
         }
@@ -152,6 +154,26 @@
         }
     }
 
+    public void setAlternativeOrder(boolean alternativeOrder) {
+        if (alternativeOrder != mAlternativeOrder) {
+            mAlternativeOrder = alternativeOrder;
+            updateAlternativeOrder();
+        }
+    }
+
+    private void updateAlternativeOrder() {
+        updateAlternativeOrder(mRot0.findViewById(R.id.ends_group));
+        updateAlternativeOrder(mRot0.findViewById(R.id.center_group));
+        updateAlternativeOrder(mRot90.findViewById(R.id.ends_group));
+        updateAlternativeOrder(mRot90.findViewById(R.id.center_group));
+    }
+
+    private void updateAlternativeOrder(View v) {
+        if (v instanceof ReverseLinearLayout) {
+            ((ReverseLinearLayout) v).setAlternativeOrder(mAlternativeOrder);
+        }
+    }
+
     private void initiallyFill(ButtonDispatcher buttonDispatcher) {
         addAll(buttonDispatcher, (ViewGroup) mRot0.findViewById(R.id.ends_group));
         addAll(buttonDispatcher, (ViewGroup) mRot0.findViewById(R.id.center_group));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 53fe6ce3..23aeae8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -99,6 +99,8 @@
     private final SparseArray<ButtonDispatcher> mButtonDisatchers = new SparseArray<>();
     private Configuration mConfiguration;
 
+    private NavigationBarInflaterView mNavigationInflaterView;
+
     private class NavTransitionListener implements TransitionListener {
         private boolean mBackTransitioning;
         private boolean mHomeAppearing;
@@ -472,9 +474,10 @@
 
     @Override
     public void onFinishInflate() {
+        mNavigationInflaterView = (NavigationBarInflaterView) findViewById(
+                R.id.navigation_inflater);
         updateRotatedViews();
-        ((NavigationBarInflaterView) findViewById(R.id.navigation_inflater)).setButtonDispatchers(
-                mButtonDisatchers);
+        mNavigationInflaterView.setButtonDispatchers(mButtonDisatchers);
 
         getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
 
@@ -530,6 +533,7 @@
         }
         mCurrentView = mRotatedViews[rot];
         mCurrentView.setVisibility(View.VISIBLE);
+        mNavigationInflaterView.setAlternativeOrder(rot == Surface.ROTATION_90);
         for (int i = 0; i < mButtonDisatchers.size(); i++) {
             mButtonDisatchers.valueAt(i).setCurrentView(mCurrentView);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 34aaae4..9bc5426 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -52,6 +52,7 @@
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
+import android.hardware.display.DisplayManager;
 import android.inputmethodservice.InputMethodService;
 import android.media.AudioAttributes;
 import android.media.MediaMetadata;
@@ -200,7 +201,7 @@
 
 public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
         DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
-        HeadsUpManager.OnHeadsUpChangedListener {
+        HeadsUpManager.OnHeadsUpChangedListener, DisplayManager.DisplayListener {
     static final String TAG = "PhoneStatusBar";
     public static final boolean DEBUG = BaseStatusBar.DEBUG;
     public static final boolean SPEW = false;
@@ -684,6 +685,8 @@
         mUnlockMethodCache.addListener(this);
         startKeyguard();
 
+        mContext.getSystemService(DisplayManager.class).registerDisplayListener(this, null);
+
         mDozeServiceHost = new DozeServiceHost();
         KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mDozeServiceHost);
         putComponent(DozeHost.class, mDozeServiceHost);
@@ -3503,6 +3506,21 @@
     }
 
     @Override
+    public void onDisplayAdded(int displayId) {
+    }
+
+    @Override
+    public void onDisplayRemoved(int displayId) {
+    }
+
+    @Override
+    public void onDisplayChanged(int displayId) {
+        if (displayId == Display.DEFAULT_DISPLAY) {
+            repositionNavigationBar();
+        }
+    }
+
+    @Override
     public void userSwitched(int newUserId) {
         super.userSwitched(newUserId);
         if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
index 3682aa1..f45967a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
@@ -30,7 +30,11 @@
  */
 public class ReverseLinearLayout extends LinearLayout {
 
-    private boolean mIsLayoutRtl;
+    /** If true, the layout is reversed vs. a regular linear layout */
+    private boolean mIsLayoutReverse;
+
+    /** If true, the layout is opposite to it's natural reversity from the layout direction */
+    private boolean mIsAlternativeOrder;
 
     public ReverseLinearLayout(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
@@ -39,45 +43,50 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mIsLayoutRtl = getResources().getConfiguration()
-                .getLayoutDirection() == LAYOUT_DIRECTION_RTL;
+        updateOrder();
     }
 
     @Override
     public void addView(View child) {
         reversParams(child.getLayoutParams());
-        if (mIsLayoutRtl) {
-            super.addView(child);
-        } else {
+        if (mIsLayoutReverse) {
             super.addView(child, 0);
+        } else {
+            super.addView(child);
         }
     }
 
     @Override
     public void addView(View child, ViewGroup.LayoutParams params) {
         reversParams(params);
-        if (mIsLayoutRtl) {
-            super.addView(child, params);
-        } else {
+        if (mIsLayoutReverse) {
             super.addView(child, 0, params);
+        } else {
+            super.addView(child, params);
         }
     }
 
     @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        updateRTLOrder();
+    public void onRtlPropertiesChanged(int layoutDirection) {
+        super.onRtlPropertiesChanged(layoutDirection);
+        updateOrder();
+    }
+
+    public void setAlternativeOrder(boolean alternative) {
+        mIsAlternativeOrder = alternative;
+        updateOrder();
     }
 
     /**
      * In landscape, the LinearLayout is not auto mirrored since it is vertical. Therefore we
      * have to do it manually
      */
-    private void updateRTLOrder() {
-        boolean isLayoutRtl = getResources().getConfiguration()
-                .getLayoutDirection() == LAYOUT_DIRECTION_RTL;
-        if (mIsLayoutRtl != isLayoutRtl) {
-            // RTL changed, swap the order of all views.
+    private void updateOrder() {
+        boolean isLayoutRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
+        boolean isLayoutReverse = isLayoutRtl ^ mIsAlternativeOrder;
+
+        if (mIsLayoutReverse != isLayoutReverse) {
+            // reversity changed, swap the order of all views.
             int childCount = getChildCount();
             ArrayList<View> childList = new ArrayList<>(childCount);
             for (int i = 0; i < childCount; i++) {
@@ -87,7 +96,7 @@
             for (int i = childCount - 1; i >= 0; i--) {
                 super.addView(childList.get(i));
             }
-            mIsLayoutRtl = isLayoutRtl;
+            mIsLayoutReverse = isLayoutReverse;
         }
     }