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

This commit is contained in:
Daniel Sandler
2010-11-17 17:11:30 -08:00
committed by Android (Google) Code Review
4 changed files with 249 additions and 76 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

View File

@@ -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,62 +83,70 @@
android:paddingLeft="24dip"
android:textColor="#2e2e2e"
/>
<ImageView
android:id="@+id/battery"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical"
/>
<ImageView
android:id="@+id/network"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_sysbar_wifi_mini"
/>
<LinearLayout
android:layout_width="48dip"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<ImageView
android:id="@+id/battery"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical"
/>
<ImageView
android:id="@+id/network"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_sysbar_wifi_mini"
/>
</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>
<!-- lights out mode: "shadow" views -->
<ImageView
android:id="@+id/notification_shadow"
android:layout_width="176dip"
android:layout_height="match_parent"
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"
/>
</RelativeLayout>
<!-- It's curtains for you. -->
<ImageView
android:id="@+id/lights_out"
android:src="@drawable/ic_sysbar_lightsout"
android:gravity="center"
android:background="#FF000000"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible"
android:clickable="true"
/>
</com.android.systemui.statusbar.tablet.TabletStatusBarView>

View File

@@ -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);
SetLightsOnListener on = new SetLightsOnListener(true);
mCurtains.setOnClickListener(on);
mCurtains.setOnLongClickListener(on);
mShadowController = new ShadowController(false);
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);
return true;
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 {

View File

@@ -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;
}
}