It's lights out for you, navigation bar!

Views requesting lights out mode will cause the navbar to
disappear (this is useful for viewing videos/photos/etc
using every pixel of the screen).

But there's a catch: any user activity at all will cause the
lights to come back on and the navbar to return.

Change-Id: I535ed3ba9ae7fab3282c402be256add765395b6f
This commit is contained in:
Daniel Sandler
2011-04-28 12:35:29 -04:00
parent ed742306b3
commit 1d4d30aebd
10 changed files with 221 additions and 103 deletions

View File

@@ -34,5 +34,6 @@ oneway interface IStatusBar
void setMenuKeyVisible(boolean visible);
void setImeWindowStatus(in IBinder token, int vis, int backDisposition);
void setHardKeyboardStatus(boolean available, boolean enabled);
void userActivity();
}

View File

@@ -46,4 +46,5 @@ interface IStatusBarService
void onNotificationClear(String pkg, String tag, int id);
void setSystemUiVisibility(int vis);
void setHardKeyboardEnabled(boolean enabled);
void userActivity();
}

View File

@@ -25,100 +25,106 @@
android:layout_width="match_parent"
>
<LinearLayout android:id="@+id/rot0"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:paddingLeft="8dip"
android:paddingRight="8dip"
android:background="#FF000000"
android:orientation="horizontal"
>
<!-- navigation controls -->
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_back"
systemui:keyCode="4"
android:layout_weight="1"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_home"
systemui:keyCode="3"
android:layout_weight="1"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_menu"
systemui:keyCode="82"
android:layout_weight="1"
/>
</LinearLayout>
<LinearLayout android:id="@+id/rot90"
<FrameLayout
android:id="@+id/background"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="#FF000000"
android:orientation="vertical"
android:visibility="gone"
>
<!-- navigation controls -->
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
<LinearLayout android:id="@+id/rot0"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_sysbar_menu"
systemui:keyCode="82"
android:layout_weight="1"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_sysbar_home"
systemui:keyCode="3"
android:layout_weight="1"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_sysbar_back"
systemui:keyCode="4"
android:layout_weight="1"
/>
</LinearLayout>
android:paddingLeft="8dip"
android:paddingRight="8dip"
android:orientation="horizontal"
>
<LinearLayout android:id="@+id/rot270"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="#FF000000"
android:orientation="vertical"
android:visibility="gone"
>
<!-- navigation controls -->
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_back"
systemui:keyCode="4"
android:layout_weight="1"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_home"
systemui:keyCode="3"
android:layout_weight="1"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_menu"
systemui:keyCode="82"
android:layout_weight="1"
/>
</LinearLayout>
<!-- navigation controls -->
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
<LinearLayout android:id="@+id/rot90"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_sysbar_back"
systemui:keyCode="4"
android:layout_weight="1"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
android:orientation="vertical"
android:visibility="gone"
>
<!-- navigation controls -->
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_sysbar_menu"
systemui:keyCode="82"
android:layout_weight="1"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_sysbar_home"
systemui:keyCode="3"
android:layout_weight="1"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_sysbar_back"
systemui:keyCode="4"
android:layout_weight="1"
/>
</LinearLayout>
<LinearLayout android:id="@+id/rot270"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_sysbar_home"
systemui:keyCode="3"
android:layout_weight="1"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_sysbar_menu"
systemui:keyCode="82"
android:layout_weight="1"
/>
</LinearLayout>
android:orientation="vertical"
android:visibility="gone"
>
<!-- navigation controls -->
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_sysbar_back"
systemui:keyCode="4"
android:layout_weight="1"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_sysbar_home"
systemui:keyCode="3"
android:layout_weight="1"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_sysbar_menu"
systemui:keyCode="82"
android:layout_weight="1"
/>
</LinearLayout>
</FrameLayout>
</com.android.systemui.statusbar.phone.NavigationBarView>

View File

@@ -35,28 +35,33 @@ import com.android.internal.statusbar.StatusBarNotification;
public class CommandQueue extends IStatusBar.Stub {
private static final String TAG = "StatusBar.CommandQueue";
private static final int MSG_MASK = 0xffff0000;
private static final int INDEX_MASK = 0x0000ffff;
private static final int INDEX_MASK = 0xffff;
private static final int MSG_SHIFT = 16;
private static final int MSG_MASK = 0xffff << MSG_SHIFT;
private static final int MSG_ICON = 0x00010000;
private static final int OP_SET_ICON = 1;
private static final int MSG_ICON = 1 << MSG_SHIFT;
private static final int OP_SET_ICON = 1;
private static final int OP_REMOVE_ICON = 2;
private static final int MSG_ADD_NOTIFICATION = 0x00020000;
private static final int MSG_UPDATE_NOTIFICATION = 0x00030000;
private static final int MSG_REMOVE_NOTIFICATION = 0x00040000;
private static final int MSG_ADD_NOTIFICATION = 2 << MSG_SHIFT;
private static final int MSG_UPDATE_NOTIFICATION = 3 << MSG_SHIFT;
private static final int MSG_REMOVE_NOTIFICATION = 4 << MSG_SHIFT;
private static final int MSG_DISABLE = 0x00050000;
private static final int MSG_DISABLE = 5 << MSG_SHIFT;
private static final int MSG_SET_VISIBILITY = 0x00060000;
private static final int OP_EXPAND = 1;
private static final int OP_COLLAPSE = 2;
private static final int MSG_SET_VISIBILITY = 6 << MSG_SHIFT;
private static final int OP_EXPAND = 1;
private static final int OP_COLLAPSE = 2;
private static final int MSG_SET_LIGHTS_ON = 0x00070000;
private static final int MSG_SET_LIGHTS_ON = 7 << MSG_SHIFT;
private static final int MSG_SHOW_MENU = 8 << MSG_SHIFT;
private static final int MSG_SHOW_IME_BUTTON = 9 << MSG_SHIFT;
private static final int MSG_SET_HARD_KEYBOARD_STATUS = 10 << MSG_SHIFT;
private static final int MSG_USER_ACTIVITY = 11 << MSG_SHIFT;
private static final int MSG_SHOW_MENU = 0x00080000;
private static final int MSG_SHOW_IME_BUTTON = 0x00090000;
private static final int MSG_SET_HARD_KEYBOARD_STATUS = 0x000a0000;
private StatusBarIconList mList;
private Callbacks mCallbacks;
@@ -85,6 +90,7 @@ public class CommandQueue extends IStatusBar.Stub {
public void setMenuKeyVisible(boolean visible);
public void setImeWindowStatus(IBinder token, int vis, int backDisposition);
public void setHardKeyboardStatus(boolean available, boolean enabled);
public void userActivity();
}
public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
@@ -183,6 +189,13 @@ public class CommandQueue extends IStatusBar.Stub {
}
}
public void userActivity() {
synchronized (mList) {
mHandler.removeMessages(MSG_USER_ACTIVITY);
mHandler.obtainMessage(MSG_USER_ACTIVITY, 0, 0, null).sendToTarget();
}
}
private final class H extends Handler {
public void handleMessage(Message msg) {
final int what = msg.what & MSG_MASK;
@@ -249,6 +262,9 @@ public class CommandQueue extends IStatusBar.Stub {
case MSG_SET_HARD_KEYBOARD_STATUS:
mCallbacks.setHardKeyboardStatus(msg.arg1 != 0, msg.arg2 != 0);
break;
case MSG_USER_ACTIVITY:
mCallbacks.userActivity();
break;
}
}
}

View File

@@ -16,29 +16,73 @@
package com.android.systemui.statusbar.phone;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.os.ServiceManager;
import android.util.AttributeSet;
import android.view.Display;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.Surface;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.content.res.Configuration;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.R;
public class NavigationBarView extends LinearLayout {
protected IStatusBarService mBarService;
final Display mDisplay;
View[] mRotatedViews = new View[4];
View mBackground;
Animator mLastAnimator = null;
public NavigationBarView(Context context, AttributeSet attrs) {
super(context, attrs);
mDisplay = ((WindowManager)context.getSystemService(
Context.WINDOW_SERVICE)).getDefaultDisplay();
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
//setLayerType(View.LAYER_TYPE_HARDWARE, null);
setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
boolean on = (visibility == View.STATUS_BAR_VISIBLE);
android.util.Log.d("NavigationBarView", "LIGHTS "
+ (on ? "ON" : "OUT"));
setLights(on);
}
});
}
private void setLights(final boolean on) {
float oldAlpha = mBackground.getAlpha();
android.util.Log.d("NavigationBarView", "animating alpha: " + oldAlpha + " -> "
+ (on ? 1f : 0f));
if (mLastAnimator != null && mLastAnimator.isRunning()) mLastAnimator.cancel();
mLastAnimator = ObjectAnimator.ofFloat(mBackground, "alpha", oldAlpha, on ? 1f : 0f)
.setDuration(on ? 250 : 1500);
mLastAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator _a) {
mLastAnimator = null;
}
});
mLastAnimator.start();
}
public void onFinishInflate() {
mBackground = findViewById(R.id.background);
mRotatedViews[Surface.ROTATION_0] =
mRotatedViews[Surface.ROTATION_180] = findViewById(R.id.rot0);
@@ -47,6 +91,13 @@ public class NavigationBarView extends LinearLayout {
mRotatedViews[Surface.ROTATION_270] = findViewById(R.id.rot270);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// immediately bring up the lights
setLights(true);
return false; // pass it on
}
public void reorient() {
final int rot = mDisplay.getRotation();
for (int i=0; i<4; i++) {

View File

@@ -36,12 +36,14 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.os.Handler;
import android.os.Message;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Slog;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.IWindowManager;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -101,6 +103,8 @@ public class PhoneStatusBar extends StatusBar {
int mIconSize;
Display mDisplay;
IWindowManager mWindowManager;
PhoneStatusBarView mStatusBarView;
int mPixelFormat;
H mHandler = new H();
@@ -201,6 +205,9 @@ public class PhoneStatusBar extends StatusBar {
mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
mWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
super.start();
addNavigationBar();
@@ -1103,12 +1110,23 @@ public class PhoneStatusBar extends StatusBar {
}
public void setLightsOn(boolean on) {
Log.v(TAG, "lights " + (on ? "on" : "off"));
if (!on) {
// All we do for "lights out" mode on a phone is hide the status bar,
// which the window manager does. But we do need to hide the windowshade
// on our own.
animateCollapse();
}
notifyLightsChanged(on);
}
private void notifyLightsChanged(boolean shown) {
try {
Slog.d(TAG, "lights " + (shown?"on":"out"));
mWindowManager.statusBarVisibilityChanged(
shown ? View.STATUS_BAR_VISIBLE : View.STATUS_BAR_HIDDEN);
} catch (RemoteException ex) {
}
}
// Not supported
@@ -1519,6 +1537,12 @@ public class PhoneStatusBar extends StatusBar {
}
}
public void userActivity() {
try {
mBarService.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
} catch (RemoteException ex) { }
}
/**
* The LEDs are turned o)ff when the notification panel is shown, even just a little bit.
* This was added last-minute and is inconsistent with the way the rest of the notifications

View File

@@ -1565,6 +1565,9 @@ public class TabletStatusBar extends StatusBar implements
return true;
}
public void userActivity() {
}
public class TouchOutsideListener implements View.OnTouchListener {
private int mMsg;
private StatusBarPanel mPanel;

View File

@@ -2869,6 +2869,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout);
}
}
try {
mStatusBarService.userActivity();
} catch (RemoteException ex) {}
}
Runnable mScreenLockTimeout = new Runnable() {

View File

@@ -122,6 +122,11 @@ public class StatusBarManagerService extends IStatusBarService.Stub
// ================================================================================
// From IStatusBarService
// ================================================================================
public void userActivity() {
if (mBar != null) try {
mBar.userActivity();
} catch (RemoteException ex) {}
}
public void expand() {
enforceExpandStatusBar();

View File

@@ -79,15 +79,22 @@ public class StatusBarTest extends TestActivity
new Test("STATUS_BAR_HIDDEN") {
public void run() {
View v = findViewById(android.R.id.list);
v.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
v.setOnSystemUiVisibilityChangeListener(mOnSystemUiVisibilityChangeListener);
v.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
}
},
new Test("STATUS_BAR_VISIBLE") {
public void run() {
View v = findViewById(android.R.id.list);
v.setOnSystemUiVisibilityChangeListener(mOnSystemUiVisibilityChangeListener);
v.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
}
},
new Test("no setSystemUiVisibility") {
public void run() {
View v = findViewById(android.R.id.list);
v.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
v.setOnSystemUiVisibilityChangeListener(null);
v.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
}
},
new Test("Double Remove") {