Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73bfdfe0 authored by Daniel Sandler's avatar Daniel Sandler Committed by Android (Google) Code Review
Browse files

Merge "Implement new lights-out mode in system bar."

parents 0b92c44f b6d3dc68
Loading
Loading
Loading
Loading
+247 B
Loading image diff...
+100 −44
Original line number Diff line number Diff line
@@ -25,9 +25,10 @@
        android:id="@+id/bar_contents"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:animateLayoutChanges="true"
        android:animateLayoutChanges="false"
        >

        <!-- ticker: transient incoming notification information -->
        <FrameLayout
            android:id="@+id/ticker"
            android:layout_width="wrap_content"
@@ -39,6 +40,7 @@
            android:animateLayoutChanges="true"
            />

        <!-- notification icons & panel access -->
        <LinearLayout
            android:id="@+id/notificationArea"
            android:layout_width="wrap_content"
@@ -65,7 +67,7 @@
            <LinearLayout
                android:id="@+id/notificationTrigger"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_height="match_parent"
                >
                <!-- paddingLeft: 24 dips = 32dp (total space to icon) - 8dp in the icon.
                TODO: Make sure the font has a small enough leading that we don't need this
@@ -81,6 +83,11 @@
                    android:paddingLeft="24dip"
                    android:textColor="#2e2e2e"
                    />
                <LinearLayout
                    android:layout_width="48dip"
                    android:layout_height="match_parent"
                    android:orientation="horizontal"
                    >
                    <ImageView
                        android:id="@+id/battery"
                        android:layout_height="wrap_content"
@@ -96,47 +103,50 @@
                        />
                </LinearLayout>
            </LinearLayout>
        </LinearLayout>

        <!-- navigation controls -->
        <LinearLayout
            android:id="@+id/navigationArea"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentLeft="true"
            android:orientation="horizontal"
            android:animateLayoutChanges="true"
            android:animateLayoutChanges="false"
            >

            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
                android:layout_width="wrap_content"
                android:layout_width="96dip"
                android:layout_height="match_parent"
                android:paddingLeft="15dip"
                android:paddingRight="15dip"
                android:paddingLeft="18dip"
                android:paddingRight="18dip"
                android:src="@drawable/ic_sysbar_back"
                android:background="@drawable/ic_sysbar_icon_bg"
                systemui:keyCode="4"
                />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
                android:layout_width="wrap_content"
                android:layout_width="96dip"
                android:layout_height="match_parent"
                android:paddingLeft="15dip"
                android:paddingRight="15dip"
                android:paddingLeft="18dip"
                android:paddingRight="18dip"
                android:src="@drawable/ic_sysbar_home"
                android:background="@drawable/ic_sysbar_icon_bg"
                systemui:keyCode="3"
                />
            <ImageButton android:id="@+id/recent_apps"
                android:layout_width="wrap_content"
                android:layout_width="96dip"
                android:layout_height="match_parent"
                android:src="@drawable/ic_sysbar_recent"
                android:background="@drawable/ic_sysbar_icon_bg"
                android:paddingLeft="15dip"
                android:paddingRight="15dip"
                android:paddingLeft="18dip"
                android:clickable="true"
                android:paddingRight="18dip"
                />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
                android:layout_width="wrap_content"
                android:layout_width="96dip"
                android:layout_height="match_parent"
                android:paddingLeft="15dip"
                android:paddingRight="15dip"
                android:paddingLeft="18dip"
                android:paddingRight="18dip"
                android:src="@drawable/ic_sysbar_menu"
                android:background="@drawable/ic_sysbar_icon_bg"
                systemui:keyCode="82"
@@ -144,11 +154,11 @@
                />
            <com.android.systemui.statusbar.tablet.ShirtPocket
                android:id="@+id/pocket"
                android:layout_width="71dip"
                android:layout_width="96dip"
                android:layout_height="match_parent"
                android:background="@drawable/ic_sysbar_icon_bg"
                android:paddingLeft="15dip"
                android:paddingRight="15dip"
                android:paddingLeft="18dip"
                android:paddingRight="18dip"
                android:animateLayoutChanges="true"
                android:clickable="true"
                android:descendantFocusability="blocksDescendants"
@@ -173,18 +183,64 @@
                android:visibility="invisible"
                />
        </LinearLayout>
    </RelativeLayout>

    <!-- It's curtains for you. -->
        <!-- lights out mode: "shadow" views -->
        <ImageView
        android:id="@+id/lights_out"
        android:src="@drawable/ic_sysbar_lightsout"
        android:gravity="center"
        android:background="#FF000000"
        android:layout_width="match_parent"
            android:id="@+id/notification_shadow"
            android:layout_width="176dip"
            android:layout_height="match_parent"
        android:visibility="invisible"
        android:clickable="true"
            android:paddingRight="48dip"
            android:layout_alignParentRight="true"
            android:layout_alignParentBottom="true"
            android:src="@drawable/ic_sysbar_shadow"
            android:visibility="gone"
            android:scaleType="fitXY"
            />

        <ImageView
            android:id="@+id/back_shadow"
            android:layout_width="96dip"
            android:layout_height="match_parent"
            android:paddingLeft="18dip"
            android:paddingRight="18dip"
            android:layout_alignParentLeft="true"
            android:layout_alignParentBottom="true"
            android:src="@drawable/ic_sysbar_shadow"
            android:visibility="gone"
            />
        <ImageView
            android:id="@+id/home_shadow"
            android:layout_width="96dip"
            android:layout_height="match_parent"
            android:paddingLeft="18dip"
            android:paddingRight="18dip"
            android:layout_toRightOf="@id/back_shadow"
            android:layout_alignParentBottom="true"
            android:src="@drawable/ic_sysbar_shadow"
            android:visibility="gone"
            />
        <ImageView
            android:id="@+id/recent_shadow"
            android:layout_width="96dip"
            android:layout_height="match_parent"
            android:paddingLeft="18dip"
            android:paddingRight="18dip"
            android:layout_toRightOf="@id/home_shadow"
            android:layout_alignParentBottom="true"
            android:src="@drawable/ic_sysbar_shadow"
            android:visibility="gone"
            />
        <ImageView
            android:id="@+id/menu_shadow"
            android:layout_width="96dip"
            android:layout_height="match_parent"
            android:paddingLeft="18dip"
            android:paddingRight="18dip"
            android:layout_toRightOf="@id/recent_shadow"
            android:layout_alignParentBottom="true"
            android:src="@drawable/ic_sysbar_shadow"
            android:visibility="gone"
            />
</com.android.systemui.statusbar.tablet.TabletStatusBarView>

    </RelativeLayout>
</com.android.systemui.statusbar.tablet.TabletStatusBarView>
+142 −32
Original line number Diff line number Diff line
@@ -75,12 +75,15 @@ public class TabletStatusBar extends StatusBar {
    public static final int MSG_CLOSE_NOTIFICATION_PEEK = 1003;
    public static final int MSG_OPEN_RECENTS_PANEL = 1020;
    public static final int MSG_CLOSE_RECENTS_PANEL = 1021;
    public static final int MSG_LIGHTS_ON = 1030;
    public static final int MSG_LIGHTS_OUT = 1031;
    public static final int MSG_HIDE_SHADOWS = 1030;
    public static final int MSG_SHOW_SHADOWS = 1031;
    public static final int MSG_SHOW_SHADOWS_NO_COLLAPSE = 1032;

    private static final int MAX_IMAGE_LEVEL = 10000;
    private static final boolean USE_2D_RECENTS = true;

    public static final int LIGHTS_ON_DELAY = 5000;

    int mIconSize;

    H mHandler = new H();
@@ -93,6 +96,9 @@ public class TabletStatusBar extends StatusBar {
    View mNotificationTrigger;
    NotificationIconArea mNotificationIconArea;
    View mNavigationArea;

    View mBackButton;
    View mHomeButton;
    View mMenuButton;
    View mRecentButton;

@@ -113,7 +119,10 @@ public class TabletStatusBar extends StatusBar {
    NetworkController mNetworkController;

    View mBarContents;
    View mCurtains;

    // lights out support
    View mBackShadow, mHomeShadow, mRecentShadow, mMenuShadow, mNotificationShadow;
    ShadowController mShadowController;

    NotificationIconArea.IconLayout mIconLayout;

@@ -245,14 +254,21 @@ public class TabletStatusBar extends StatusBar {
        sb.setHandler(mHandler);

        mBarContents = sb.findViewById(R.id.bar_contents);
        mCurtains = sb.findViewById(R.id.lights_out);

        mRecentButton = sb.findViewById(R.id.recent_apps);
        mRecentButton.setOnClickListener(mOnClickListener);
        // "shadows" of the status bar features, for lights-out mode
        mBackShadow = sb.findViewById(R.id.back_shadow);
        mHomeShadow = sb.findViewById(R.id.home_shadow);
        mRecentShadow = sb.findViewById(R.id.recent_shadow);
        mMenuShadow = sb.findViewById(R.id.menu_shadow);
        mNotificationShadow = sb.findViewById(R.id.notification_shadow);

        mShadowController = new ShadowController(false);

        SetLightsOnListener on = new SetLightsOnListener(true);
        mCurtains.setOnClickListener(on);
        mCurtains.setOnLongClickListener(on);
        mBackShadow.setOnTouchListener(mShadowController.makeTouchListener());
        mHomeShadow.setOnTouchListener(mShadowController.makeTouchListener());
        mRecentShadow.setOnTouchListener(mShadowController.makeTouchListener());
        mMenuShadow.setOnTouchListener(mShadowController.makeTouchListener());
        mNotificationShadow.setOnTouchListener(mShadowController.makeTouchListener());

        // the whole right-hand side of the bar
        mNotificationArea = sb.findViewById(R.id.notificationArea);
@@ -282,10 +298,15 @@ public class TabletStatusBar extends StatusBar {

        // The navigation buttons
        mNavigationArea = sb.findViewById(R.id.navigationArea);
        mBackButton = mNavigationArea.findViewById(R.id.back);
        mHomeButton = mNavigationArea.findViewById(R.id.home);
        mMenuButton = mNavigationArea.findViewById(R.id.menu);
        mRecentButton = mNavigationArea.findViewById(R.id.recent_apps);
        Slog.d(TAG, "rec=" + mRecentButton + ", listener=" + mOnClickListener);
        mRecentButton.setOnClickListener(mOnClickListener);

        // The bar contents buttons
        mInputMethodButton = (InputMethodButton) mBarContents.findViewById(R.id.imeButton);
        mInputMethodButton = (InputMethodButton) sb.findViewById(R.id.imeButton);

        // set the initial view visibility
        setAreThereNotifications();
@@ -362,6 +383,8 @@ public class TabletStatusBar extends StatusBar {
                        mNotificationPeekWindow.setVisibility(View.GONE);

                        mNotificationPanel.setVisibility(View.VISIBLE);

                        // XXX: need to synchronize with shadows here
                        mNotificationArea.setVisibility(View.GONE);
                    }
                    break;
@@ -369,6 +392,8 @@ public class TabletStatusBar extends StatusBar {
                    if (DEBUG) Slog.d(TAG, "closing notifications panel");
                    if (mNotificationPanel.getVisibility() == View.VISIBLE) {
                        mNotificationPanel.setVisibility(View.GONE);

                        // XXX: need to synchronize with shadows here
                        mNotificationArea.setVisibility(View.VISIBLE);
                    }
                    break;
@@ -380,14 +405,14 @@ public class TabletStatusBar extends StatusBar {
                    if (DEBUG) Slog.d(TAG, "closing recents panel");
                    if (mRecentsPanel != null) mRecentsPanel.setVisibility(View.GONE);
                    break;
                case MSG_LIGHTS_ON:
                    setViewVisibility(mCurtains, View.GONE, R.anim.lights_out_out);
                    setViewVisibility(mBarContents, View.VISIBLE, R.anim.status_bar_in);
                case MSG_HIDE_SHADOWS:
                    mShadowController.hideAllShadows();
                    break;
                case MSG_LIGHTS_OUT:
                case MSG_SHOW_SHADOWS:
                    animateCollapse();
                    setViewVisibility(mCurtains, View.VISIBLE, R.anim.lights_out_in);
                    setViewVisibility(mBarContents, View.GONE, R.anim.status_bar_out);
                    // fall through
                case MSG_SHOW_SHADOWS_NO_COLLAPSE:
                    mShadowController.showAllShadows();
                    break;
            }
        }
@@ -605,16 +630,16 @@ public class TabletStatusBar extends StatusBar {
    // called by StatusBar
    @Override
    public void setLightsOn(boolean on) {
        mHandler.removeMessages(MSG_LIGHTS_OUT);
        mHandler.removeMessages(MSG_LIGHTS_ON);
        mHandler.sendEmptyMessage(on ? MSG_LIGHTS_ON : MSG_LIGHTS_OUT);
        mHandler.removeMessages(MSG_SHOW_SHADOWS);
        mHandler.removeMessages(MSG_HIDE_SHADOWS);
        mHandler.sendEmptyMessage(on ? MSG_HIDE_SHADOWS : MSG_SHOW_SHADOWS);
    }

    public void setMenuKeyVisible(boolean visible) {
        if (DEBUG) {
            Slog.d(TAG, (visible?"showing":"hiding") + " the MENU button");
        }
        mMenuButton.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
        mMenuButton.setVisibility(visible ? View.VISIBLE : View.GONE);
    }

    public void setIMEButtonVisible(boolean visible) {
@@ -664,7 +689,7 @@ public class TabletStatusBar extends StatusBar {
    };

    public void onClickNotificationTrigger() {
        if (DEBUG) Slog.d(TAG, "clicked notification icons");
        if (DEBUG) Slog.d(TAG, "clicked notification icons; disabled=" + mDisabled);
        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
            if (!mNotificationsOn) {
                mNotificationsOn = true;
@@ -681,7 +706,7 @@ public class TabletStatusBar extends StatusBar {
    }

    public void onClickRecentButton() {
        if (DEBUG) Slog.d(TAG, "clicked recent apps");
        if (DEBUG) Slog.d(TAG, "clicked recent apps; disabled=" + mDisabled);
        if (mRecentsPanel == null) {
            Intent intent = new Intent();
            intent.setClass(mContext, RecentApplicationsActivity.class);
@@ -1006,23 +1031,108 @@ public class TabletStatusBar extends StatusBar {
        return true;
    }

    public class SetLightsOnListener implements View.OnLongClickListener,
           View.OnClickListener {
        private boolean mOn;
    public class ShadowController {
        boolean mShowShadows;
        View mTouchTarget;

        SetLightsOnListener(boolean on) {
            mOn = on;
        ShadowController(boolean showShadows) {
            mShowShadows = showShadows;
            mTouchTarget = null;
        }

        public void onClick(View v) {
            setLightsOn(mOn);
        public boolean getShadowState() {
            return mShowShadows;
        }

        public boolean onLongClick(View v) {
            setLightsOn(mOn);
        public View.OnTouchListener makeTouchListener() {
            return new View.OnTouchListener() {
                public boolean onTouch(View v, MotionEvent ev) {
                    final int action = ev.getAction();

                    if (DEBUG) Slog.d(TAG, "ShadowController: v=" + v + ", ev=" + ev);

                    // currently redirecting events?
                    if (mTouchTarget == null) {
                        if (v == mBackShadow) {
                            mTouchTarget = mBackButton;
                        } else if (v == mHomeShadow) {
                            mTouchTarget = mHomeButton;
                        } else if (v == mMenuShadow) {
                            mTouchTarget = mMenuButton;
                        } else if (v == mRecentShadow) {
                            mTouchTarget = mRecentButton;
                        } else if (v == mNotificationShadow) {
                            mTouchTarget = mNotificationArea;
                        }
                    }

                    if (mTouchTarget != null && mTouchTarget.getVisibility() != View.GONE) {
                        boolean last = false;
                        switch (action) {
                            case MotionEvent.ACTION_CANCEL:
                            case MotionEvent.ACTION_UP:
                                mHandler.removeMessages(MSG_SHOW_SHADOWS_NO_COLLAPSE);
                                if (mShowShadows) {
                                    mHandler.sendEmptyMessageDelayed(MSG_SHOW_SHADOWS_NO_COLLAPSE, 
                                            v == mNotificationShadow ? 5000 : 500);
                                }
                                last = true;
                                break;
                            case MotionEvent.ACTION_DOWN:
                                mHandler.removeMessages(MSG_SHOW_SHADOWS_NO_COLLAPSE);
                                setShadowForButton(mTouchTarget, false);
                                break;
                        }
                        mTouchTarget.dispatchTouchEvent(ev);
                        if (last) mTouchTarget = null;
                        return true;
                    }

                    return false;
                }
            };
        }

        public void showAllShadows() {
            mShowShadows = true;
            setShadowForButton(mBackButton, true);
            setShadowForButton(mHomeButton, true);
            setShadowForButton(mRecentButton, true);
            setShadowForButton(mMenuButton, true);
            setShadowForButton(mNotificationArea, true);
        }

        public void hideAllShadows() {
            mShowShadows = false;
            setShadowForButton(mBackButton, false);
            setShadowForButton(mHomeButton, false);
            setShadowForButton(mRecentButton, false);
            setShadowForButton(mMenuButton, false);
            setShadowForButton(mNotificationArea, false);
        }

        // Use View.INVISIBLE for things hidden due to shadowing, and View.GONE for things that are
        // disabled (and should not be shadowed or re-shown)
        public void setShadowForButton(View button, boolean shade) {
            View shadow = null;
            if (button == mBackButton) {
                shadow = mBackShadow;
            } else if (button == mHomeButton) {
                shadow = mHomeShadow;
            } else if (button == mMenuButton) {
                shadow = mMenuShadow;
            } else if (button == mRecentButton) {
                shadow = mRecentShadow;
            } else if (button == mNotificationArea) {
                shadow = mNotificationShadow;
            }
            if (shadow != null) {
                if (button.getVisibility() != View.GONE) {
                    shadow.setVisibility(shade ? View.VISIBLE : View.INVISIBLE);
                    button.setVisibility(shade ? View.INVISIBLE : View.VISIBLE);
                }
            }
        }
    }

    public class TouchOutsideListener implements View.OnTouchListener {
+7 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.tablet;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Slog;
import android.view.View;
import android.view.MotionEvent;
import android.widget.FrameLayout;
@@ -40,6 +41,9 @@ public class TabletStatusBarView extends FrameLayout {

    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            if (TabletStatusBar.DEBUG) {
                Slog.d(TabletStatusBar.TAG, "TabletStatusBarView intercepting touch event: " + ev);
            }
            mHandler.removeMessages(TabletStatusBar.MSG_CLOSE_NOTIFICATION_PANEL);
            mHandler.sendEmptyMessage(TabletStatusBar.MSG_CLOSE_NOTIFICATION_PANEL);
            mHandler.removeMessages(TabletStatusBar.MSG_CLOSE_RECENTS_PANEL);
@@ -48,6 +52,9 @@ public class TabletStatusBarView extends FrameLayout {
            for (int i=0; i < mPanels.length; i++) {
                if (mPanels[i] != null && mPanels[i].getVisibility() == View.VISIBLE) {
                    if (eventInside(mIgnoreChildren[i], ev)) {
                        if (TabletStatusBar.DEBUG) {
                            Slog.d(TabletStatusBar.TAG, "TabletStatusBarView eating event for view: " + mIgnoreChildren[i]);
                        }
                        return true;
                    }
                }