diff options
3 files changed, 251 insertions, 97 deletions
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml index 896efde..c6178a0 100644 --- a/packages/SystemUI/res/layout/super_status_bar.xml +++ b/packages/SystemUI/res/layout/super_status_bar.xml @@ -18,13 +18,13 @@ --> <!-- This is the combined status bar / notification panel window. --> -<FrameLayout +<com.android.systemui.statusbar.phone.NavBarInsetLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:sysui="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:focusable="true" - android:fitsSystemWindows="false" + android:fitsSystemWindows="true" android:descendantFocusability="afterDescendants"> <com.android.systemui.statusbar.BackDropView @@ -45,29 +45,34 @@ android:visibility="invisible" /> </com.android.systemui.statusbar.BackDropView> - <FrameLayout android:id="@+id/scrimview" + <com.android.systemui.statusbar.phone.NavBarInsetLayout + android:id="@+id/scrimview" android:layout_width="match_parent" android:layout_height="match_parent" - android:visibility="visible"> + android:visibility="visible" + sysui:ignoreRightInset="true" + android:fitsSystemWindows="true"> <com.android.systemui.statusbar.ScrimView android:id="@+id/scrim_behind" android:layout_width="match_parent" android:layout_height="match_parent" + sysui:ignoreRightInset="true" android:importantForAccessibility="no"/> <com.android.systemui.statusbar.AlphaOptimizedView - android:id="@+id/heads_up_scrim" - android:layout_width="match_parent" - android:layout_height="@dimen/heads_up_scrim_height" - android:background="@drawable/heads_up_scrim" - android:importantForAccessibility="no"/> + android:id="@+id/heads_up_scrim" + android:layout_width="match_parent" + android:layout_height="@dimen/heads_up_scrim_height" + android:background="@drawable/heads_up_scrim" + android:importantForAccessibility="no"/> <com.android.systemui.statusbar.VisualizerView android:id="@+id/visualizerview" android:gravity="bottom" android:layout_gravity="bottom" android:layout_width="match_parent" android:layout_height="match_parent" + sysui:ignoreRightInset="true" android:visibility="visible"/> - </FrameLayout> + </com.android.systemui.statusbar.phone.NavBarInsetLayout> <include layout="@layout/status_bar" android:layout_width="match_parent" @@ -109,4 +114,4 @@ sysui:ignoreRightInset="true" /> -</FrameLayout> +</com.android.systemui.statusbar.phone.NavBarInsetLayout> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarInsetLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarInsetLayout.java new file mode 100644 index 0000000..e767ca5 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarInsetLayout.java @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2016 The CyanogenMod 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.android.systemui.statusbar.phone; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Rect; +import android.os.Handler; +import android.os.IBinder; +import android.os.UserHandle; +import android.util.AttributeSet; +import android.view.View; +import android.view.WindowManager; +import android.view.WindowManagerGlobal; +import android.widget.FrameLayout; +import com.android.systemui.R; +import com.android.systemui.cm.UserContentObserver; +import com.android.systemui.statusbar.BaseStatusBar; +import cyanogenmod.providers.CMSettings; + +public class NavBarInsetLayout extends FrameLayout { + public static final String TAG = "NavBarInsetLayout"; + public static final boolean DEBUG = BaseStatusBar.DEBUG; + + boolean mLeftInsetMode = false; + + private int mLeftInset = 0; + private int mRightInset = 0; + + private final Paint mTransparentSrcPaint = new Paint(); + + private SettingsObserver mSettingsObserver; + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + mSettingsObserver.observe(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + mSettingsObserver.unobserve(); + } + + public NavBarInsetLayout(Context context, AttributeSet attrs) { + super(context, attrs); + mTransparentSrcPaint.setColor(0); + mTransparentSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); + + mSettingsObserver = new SettingsObserver(new Handler()); + } + + @Override + protected boolean fitSystemWindows(Rect insets) { + if (getFitsSystemWindows()) { + boolean paddingChanged; + + if (mLeftInsetMode) { + paddingChanged = insets.right != getPaddingRight() + || insets.top != getPaddingTop() + || insets.bottom != getPaddingBottom(); + + if (insets.left != mLeftInset) { + mLeftInset = insets.left; + applyMargins(); + } + } else { + paddingChanged = insets.left != getPaddingLeft() + || insets.top != getPaddingTop() + || insets.bottom != getPaddingBottom(); + + if (insets.right != mRightInset) { + mRightInset = insets.right; + applyMargins(); + } + } + + // Drop top inset, apply left inset and pass through bottom inset. + if (paddingChanged) { + setPadding(mLeftInsetMode ? 0 : insets.left, + 0, + mLeftInsetMode ? insets.right : 0, + 0); + } + insets.left = 0; + insets.top = 0; + insets.right = 0; + } else { + boolean applyMargins = false; + if (mLeftInset != 0) { + mLeftInset = 0; + applyMargins = true; + } + if (mRightInset != 0) { + mRightInset = 0; + applyMargins = true; + } + if (applyMargins) { + applyMargins(); + } + boolean changed = getPaddingLeft() != 0 + || getPaddingRight() != 0 + || getPaddingTop() != 0 + || getPaddingBottom() != 0; + if (changed) { + setPadding(0, 0, 0, 0); + } + insets.top = 0; + } + return false; + } + + private void applyMargins() { + final int N = getChildCount(); + for (int i = 0; i < N; i++) { + View child = getChildAt(i); + if (child.getLayoutParams() instanceof InsetLayoutParams) { + InsetLayoutParams lp = (InsetLayoutParams) child.getLayoutParams(); + if (!lp.ignoreRightInset) { + if (mLeftInsetMode && lp.leftMargin != mLeftInset) { + lp.leftMargin = mLeftInset; + if (lp.rightMargin != 0) { + lp.rightMargin = 0; + } + } else if (lp.rightMargin != mRightInset) { + lp.rightMargin = mRightInset; + if (lp.leftMargin != 0) { + lp.leftMargin = 0; + } + } + child.requestLayout(); + } + } + } + } + + @Override + public FrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) { + return new InsetLayoutParams(getContext(), attrs); + } + + @Override + protected FrameLayout.LayoutParams generateDefaultLayoutParams() { + return new InsetLayoutParams(InsetLayoutParams.MATCH_PARENT, + InsetLayoutParams.MATCH_PARENT); + } + + private class SettingsObserver extends UserContentObserver { + + public SettingsObserver(Handler handler) { + super(handler); + } + + @Override + protected void observe() { + super.observe(); + mContext.getContentResolver().registerContentObserver( + CMSettings.System.getUriFor(CMSettings.System.NAVBAR_LEFT_IN_LANDSCAPE), false, + this, UserHandle.USER_CURRENT); + update(); + } + + @Override + protected void unobserve() { + super.unobserve(); + mContext.getContentResolver().unregisterContentObserver(this); + } + + @Override + protected void update() { + boolean before = mLeftInsetMode; + mLeftInsetMode = CMSettings.System.getIntForUser(mContext.getContentResolver(), + CMSettings.System.NAVBAR_LEFT_IN_LANDSCAPE, 0, UserHandle.USER_CURRENT) == 1; + if (mLeftInsetMode != before) { + applyMargins(); + } + } + } + + public static class InsetLayoutParams extends FrameLayout.LayoutParams { + + public boolean ignoreRightInset; + + public InsetLayoutParams(int width, int height) { + super(width, height); + } + + public InsetLayoutParams(Context c, AttributeSet attrs) { + super(c, attrs); + + TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.StatusBarWindowView_Layout); + ignoreRightInset = a.getBoolean( + R.styleable.StatusBarWindowView_Layout_ignoreRightInset, false); + a.recycle(); + } + } +} + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index 75d2283..56ced84 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -64,8 +64,6 @@ public class StatusBarWindowView extends FrameLayout { private NotificationPanelView mNotificationPanel; private View mBrightnessMirror; - private int mRightInset = 0; - private PhoneStatusBar mService; private final Paint mTransparentSrcPaint = new Paint(); @@ -87,66 +85,6 @@ public class StatusBarWindowView extends FrameLayout { } @Override - protected boolean fitSystemWindows(Rect insets) { - if (getFitsSystemWindows()) { - boolean paddingChanged = insets.left != getPaddingLeft() - || insets.top != getPaddingTop() - || insets.bottom != getPaddingBottom(); - - // Super-special right inset handling, because scrims and backdrop need to ignore it. - if (insets.right != mRightInset) { - mRightInset = insets.right; - applyMargins(); - } - // Drop top inset, apply left inset and pass through bottom inset. - if (paddingChanged) { - setPadding(insets.left, 0, 0, 0); - } - insets.left = 0; - insets.top = 0; - insets.right = 0; - } else { - if (mRightInset != 0) { - mRightInset = 0; - applyMargins(); - } - boolean changed = getPaddingLeft() != 0 - || getPaddingRight() != 0 - || getPaddingTop() != 0 - || getPaddingBottom() != 0; - if (changed) { - setPadding(0, 0, 0, 0); - } - insets.top = 0; - } - return false; - } - - private void applyMargins() { - final int N = getChildCount(); - for (int i = 0; i < N; i++) { - View child = getChildAt(i); - if (child.getLayoutParams() instanceof LayoutParams) { - LayoutParams lp = (LayoutParams) child.getLayoutParams(); - if (!lp.ignoreRightInset && lp.rightMargin != mRightInset) { - lp.rightMargin = mRightInset; - child.requestLayout(); - } - } - } - } - - @Override - public FrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) { - return new LayoutParams(getContext(), attrs); - } - - @Override - protected FrameLayout.LayoutParams generateDefaultLayoutParams() { - return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); - } - - @Override protected void onFinishInflate() { super.onFinishInflate(); mStackScrollLayout = (NotificationStackScrollLayout) findViewById( @@ -190,11 +128,13 @@ public class StatusBarWindowView extends FrameLayout { // occur if our window is translucent. Since we are drawing the whole window anyway with // the scrim, we don't need the window to be cleared in the beginning. if (mService.isScrimSrcModeEnabled()) { - IBinder windowToken = getWindowToken(); - WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams(); - lp.token = windowToken; - setLayoutParams(lp); - WindowManagerGlobal.getInstance().changeCanvasOpacity(windowToken, true); + if (getLayoutParams() instanceof WindowManager.LayoutParams) { + WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams(); + IBinder windowToken = getWindowToken(); + lp.token = windowToken; + setLayoutParams(lp); + WindowManagerGlobal.getInstance().changeCanvasOpacity(windowToken, true); + } setWillNotDraw(false); } else { setWillNotDraw(!DEBUG); @@ -208,6 +148,16 @@ public class StatusBarWindowView extends FrameLayout { } @Override + protected boolean fitSystemWindows(Rect insets) { + insets.bottom = 0; + insets.top = 0; + insets.right = 0; + insets.left = 0; + super.fitSystemWindows(insets); + return false; + } + + @Override public boolean dispatchKeyEvent(KeyEvent event) { boolean down = event.getAction() == KeyEvent.ACTION_DOWN; switch (event.getKeyCode()) { @@ -300,7 +250,7 @@ public class StatusBarWindowView extends FrameLayout { } @Override - public void onDraw(Canvas canvas) { + protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mService.isScrimSrcModeEnabled()) { // We need to ensure that our window is always drawn fully even when we have paddings, @@ -351,24 +301,6 @@ public class StatusBarWindowView extends FrameLayout { removeView(content); } - public class LayoutParams extends FrameLayout.LayoutParams { - - public boolean ignoreRightInset; - - public LayoutParams(int width, int height) { - super(width, height); - } - - public LayoutParams(Context c, AttributeSet attrs) { - super(c, attrs); - - TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.StatusBarWindowView_Layout); - ignoreRightInset = a.getBoolean( - R.styleable.StatusBarWindowView_Layout_ignoreRightInset, false); - a.recycle(); - } - } - class SettingsObserver extends ContentObserver { SettingsObserver(Handler handler) { super(handler); |