Fixing overscroll effect when the navigation bar is opaque

The navigation bar is opaque on mobile devices in landscape mode.
Launcher should ignore the right insets and draw the edge effect appropriately.
Also draw the black bar under the navigation bar, just in case we assume it
to be opaque, but it was not actually opaque.

Bug: 18526657
Change-Id: I1d49dcb82b8a5ee25009bc738cd9b8c0c5c88263
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index ae204c4..20a77b5 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -17,6 +17,7 @@
 package com.android.launcher3;
 
 import android.annotation.TargetApi;
+import android.app.ActivityManager;
 import android.content.Context;
 import android.graphics.Point;
 import android.os.Build;
@@ -84,6 +85,9 @@
     DeviceProfile landscapeProfile;
     DeviceProfile portraitProfile;
 
+    // On Marshmallow the status bar is no longer opaque, when drawn on the right.
+    public boolean isRightInsetOpaque;
+
     InvariantDeviceProfile() {
     }
 
@@ -116,7 +120,7 @@
         defaultLayoutId = dlId;
     }
 
-    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
+    @TargetApi(Build.VERSION_CODES.M)
     InvariantDeviceProfile(Context context) {
         WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
         Display display = wm.getDefaultDisplay();
@@ -167,6 +171,9 @@
                 largeSide, smallSide, true /* isLandscape */);
         portraitProfile = new DeviceProfile(context, this, smallestSize, largestSize,
                 smallSide, largeSide, false /* isLandscape */);
+
+        isRightInsetOpaque = !Utilities.ATLEAST_MARSHMALLOW ||
+                context.getSystemService(ActivityManager.class).isLowRamDevice();
     }
 
     ArrayList<InvariantDeviceProfile> getPredefinedDeviceProfiles() {
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
index e8c11c4..1c6ca87 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -1,17 +1,42 @@
 package com.android.launcher3;
 
 import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 
 public class LauncherRootView extends InsettableFrameLayout {
+
+    private final Paint mOpaquePaint;
+    private boolean mDrawRightInsetBar;
+
     public LauncherRootView(Context context, AttributeSet attrs) {
         super(context, attrs);
+
+        mOpaquePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mOpaquePaint.setColor(Color.BLACK);
+        mOpaquePaint.setStyle(Paint.Style.FILL);
     }
 
     @Override
     protected boolean fitSystemWindows(Rect insets) {
         setInsets(insets);
+        mDrawRightInsetBar = mInsets.right > 0 && LauncherAppState
+                .getInstance().getInvariantDeviceProfile().isRightInsetOpaque;
+
         return true; // I'll take it from here
     }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        super.dispatchDraw(canvas);
+
+        // If the right inset is opaque, draw a black rectangle to ensure that is stays opaque.
+        if (mDrawRightInsetBar) {
+            int width = getWidth();
+            canvas.drawRect(width - mInsets.right, 0, width, getHeight(), mOpaquePaint);
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 05f0a05..2579ea3 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -202,6 +202,9 @@
     protected final Rect mInsets = new Rect();
     protected final boolean mIsRtl;
 
+    // When set to true, full screen content and overscroll effect is shited inside by right inset.
+    protected boolean mIgnoreRightInset;
+
     // Edge effect
     private final LauncherEdgeEffect mEdgeGlowLeft = new LauncherEdgeEffect();
     private final LauncherEdgeEffect mEdgeGlowRight = new LauncherEdgeEffect();
@@ -819,7 +822,8 @@
                     childWidthMode = MeasureSpec.EXACTLY;
                     childHeightMode = MeasureSpec.EXACTLY;
 
-                    childWidth = getViewportWidth() - mInsets.left - mInsets.right;
+                    childWidth = getViewportWidth() - mInsets.left
+                            - (mIgnoreRightInset ? mInsets.right : 0);
                     childHeight = getViewportHeight();
                 }
                 if (referenceChildWidth == 0) {
@@ -1177,8 +1181,10 @@
                 canvas.rotate(90);
 
                 getEdgeVerticalPostion(sTmpIntPoint);
-                canvas.translate(sTmpIntPoint[0] - display.top, -display.width());
-                mEdgeGlowRight.setSize(sTmpIntPoint[1] - sTmpIntPoint[0], display.width());
+
+                int width = mIgnoreRightInset ? (display.width() - mInsets.right) : display.width();
+                canvas.translate(sTmpIntPoint[0] - display.top, -width);
+                mEdgeGlowRight.setSize(sTmpIntPoint[1] - sTmpIntPoint[0], width);
                 if (mEdgeGlowRight.draw(canvas)) {
                     postInvalidateOnAnimation();
                 }
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 0fdc742..362e804 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -454,6 +454,7 @@
         setWallpaperDimension();
 
         setEdgeGlowColor(getResources().getColor(R.color.workspace_edge_effect_color));
+        mIgnoreRightInset = app.getInvariantDeviceProfile().isRightInsetOpaque;
     }
 
     private void setupLayoutTransition() {