Move navigation bar logic to its own class

Start hacking away at PhoneStatusBar by trying to pull out
as much NavigationBar logic as possible.

Test: runtest systemui
Change-Id: I23b904428be31b91f0747fd60c9f6e0dd323eb44
This commit is contained in:
Jason Monk
2017-01-11 09:21:56 -05:00
parent 0872c2455e
commit 49fa016a98
18 changed files with 980 additions and 618 deletions

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2017, The Android Open Source 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.
*/
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation_bar_frame"
android:layout_height="match_parent"
android:layout_width="match_parent">
</FrameLayout>

View File

@@ -0,0 +1,23 @@
/*
* Copyright (C) 2017 The Android Open Source 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;
/**
* The interface for getting core components of SysUI. Exists for Testability
* since tests don't have SystemUIApplication as their ApplicationContext.
*/
public interface SysUiServiceProvider {
<T> T getComponent(Class<T> interfaceType);
}

View File

@@ -25,7 +25,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Map;
public abstract class SystemUI {
public abstract class SystemUI implements SysUiServiceProvider {
public Context mContext;
public Map<Class<?>, Object> mComponents;

View File

@@ -55,7 +55,7 @@ import java.util.Map;
/**
* Application class for SystemUI.
*/
public class SystemUIApplication extends Application {
public class SystemUIApplication extends Application implements SysUiServiceProvider {
private static final String TAG = "SystemUIService";
private static final boolean DEBUG = false;
@@ -239,4 +239,8 @@ public class SystemUIApplication extends Application {
public SystemUI[] getServices() {
return mServices;
}
public static <T> T getComponent(Context context, Class<T> interfaceType) {
return ((SysUiServiceProvider) context.getApplicationContext()).getComponent(interfaceType);
}
}

View File

@@ -52,7 +52,7 @@ public class FragmentHostManager {
private FragmentLifecycleCallbacks mLifecycleCallbacks;
FragmentHostManager(Context context, FragmentService manager, View rootView) {
mContext = PluginManager.getInstance(context).getAllPluginContext(context);
mContext = context;
mManager = manager;
mRootView = rootView;
mConfigChanges.applyNewConfig(context.getResources());

View File

@@ -185,9 +185,6 @@ public abstract class BaseStatusBar extends SystemUI implements
protected int mLayoutDirection = -1; // invalid
protected AccessibilityManager mAccessibilityManager;
// on-screen navigation buttons
protected NavigationBarView mNavigationBarView = null;
protected boolean mDeviceInteractive;
protected boolean mVisible;
@@ -238,8 +235,6 @@ public abstract class BaseStatusBar extends SystemUI implements
protected WindowManager mWindowManager;
protected IWindowManager mWindowManagerService;
protected abstract void refreshLayout(int layoutDirection);
protected Display mDisplay;
private boolean mDeviceProvisioned = false;
@@ -945,8 +940,6 @@ public abstract class BaseStatusBar extends SystemUI implements
@Override
protected void onConfigurationChanged(Configuration newConfig) {
final Locale locale = mContext.getResources().getConfiguration().locale;
final int ld = TextUtils.getLayoutDirectionFromLocale(locale);
final float fontScale = newConfig.fontScale;
final int density = newConfig.densityDpi;
if (density != mDensity || mFontScale != fontScale) {
@@ -954,16 +947,6 @@ public abstract class BaseStatusBar extends SystemUI implements
mDensity = density;
mFontScale = fontScale;
}
if (! locale.equals(mLocale) || ld != mLayoutDirection) {
if (DEBUG) {
Log.v(TAG, String.format(
"config changed locale/LD: %s (%d) -> %s (%d)", mLocale, mLayoutDirection,
locale, ld));
}
mLocale = locale;
mLayoutDirection = ld;
refreshLayout(ld);
}
}
protected void onDensityOrFontScaleChanged() {
@@ -1285,26 +1268,6 @@ public abstract class BaseStatusBar extends SystemUI implements
protected abstract View getStatusBarView();
protected View.OnTouchListener mRecentsPreloadOnTouchListener = new View.OnTouchListener() {
// additional optimization when we have software system buttons - start loading the recent
// tasks on touch down
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction() & MotionEvent.ACTION_MASK;
if (action == MotionEvent.ACTION_DOWN) {
preloadRecents();
} else if (action == MotionEvent.ACTION_CANCEL) {
cancelPreloadingRecents();
} else if (action == MotionEvent.ACTION_UP) {
if (!v.isPressed()) {
cancelPreloadingRecents();
}
}
return false;
}
};
/**
* Toggle docking the app window
*
@@ -2256,7 +2219,6 @@ public abstract class BaseStatusBar extends SystemUI implements
protected abstract void setAreThereNotifications();
protected abstract void updateNotifications();
public abstract boolean shouldDisableNavbarGestures();
public abstract void addNotification(StatusBarNotification notification,
RankingMap ranking, Entry oldEntry);

View File

@@ -32,6 +32,8 @@ import com.android.internal.statusbar.IStatusBar;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.SystemUI;
import java.util.ArrayList;
/**
* This class takes the functions from IStatusBar that come in on
* binder pool threads and posts messages to get them onto the main
@@ -91,7 +93,7 @@ public class CommandQueue extends IStatusBar.Stub {
private static final String SHOW_IME_SWITCHER_KEY = "showImeSwitcherKey";
private final Object mLock = new Object();
private Callbacks[] mCallbacks = new Callbacks[0];
private ArrayList<Callbacks> mCallbacks = new ArrayList<>();
private Handler mHandler = new H(Looper.getMainLooper());
/**
@@ -144,15 +146,11 @@ public class CommandQueue extends IStatusBar.Stub {
}
public void addCallbacks(Callbacks callbacks) {
Callbacks[] newArray = new Callbacks[mCallbacks.length + 1];
for (int i = 0; i < newArray.length - 1; i++) {
newArray[i] = mCallbacks[i];
if (newArray[i] == callbacks) {
throw new IllegalArgumentException("Callback was already added");
}
}
newArray[newArray.length - 1] = callbacks;
mCallbacks = newArray;
mCallbacks.add(callbacks);
}
public void removeCallbacks(Callbacks callbacks) {
mCallbacks.remove(callbacks);
}
public void setIcon(String slot, StatusBarIcon icon) {
@@ -427,182 +425,182 @@ public class CommandQueue extends IStatusBar.Stub {
switch (msg.arg1) {
case OP_SET_ICON: {
Pair<String, StatusBarIcon> p = (Pair<String, StatusBarIcon>) msg.obj;
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].setIcon(p.first, p.second);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).setIcon(p.first, p.second);
}
break;
}
case OP_REMOVE_ICON:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].removeIcon((String) msg.obj);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).removeIcon((String) msg.obj);
}
break;
}
break;
}
case MSG_DISABLE:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].disable(msg.arg1, msg.arg2, true /* animate */);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).disable(msg.arg1, msg.arg2, true /* animate */);
}
break;
case MSG_EXPAND_NOTIFICATIONS:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].animateExpandNotificationsPanel();
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).animateExpandNotificationsPanel();
}
break;
case MSG_COLLAPSE_PANELS:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].animateCollapsePanels(0);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).animateCollapsePanels(0);
}
break;
case MSG_EXPAND_SETTINGS:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].animateExpandSettingsPanel((String) msg.obj);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).animateExpandSettingsPanel((String) msg.obj);
}
break;
case MSG_SET_SYSTEMUI_VISIBILITY:
SomeArgs args = (SomeArgs) msg.obj;
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].setSystemUiVisibility(args.argi1, args.argi2, args.argi3,
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).setSystemUiVisibility(args.argi1, args.argi2, args.argi3,
args.argi4, (Rect) args.arg1, (Rect) args.arg2);
}
args.recycle();
break;
case MSG_TOP_APP_WINDOW_CHANGED:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].topAppWindowChanged(msg.arg1 != 0);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).topAppWindowChanged(msg.arg1 != 0);
}
break;
case MSG_SHOW_IME_BUTTON:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].setImeWindowStatus((IBinder) msg.obj, msg.arg1, msg.arg2,
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).setImeWindowStatus((IBinder) msg.obj, msg.arg1, msg.arg2,
msg.getData().getBoolean(SHOW_IME_SWITCHER_KEY, false));
}
break;
case MSG_SHOW_RECENT_APPS:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].showRecentApps(msg.arg1 != 0, msg.arg2 != 0);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).showRecentApps(msg.arg1 != 0, msg.arg2 != 0);
}
break;
case MSG_HIDE_RECENT_APPS:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].hideRecentApps(msg.arg1 != 0, msg.arg2 != 0);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).hideRecentApps(msg.arg1 != 0, msg.arg2 != 0);
}
break;
case MSG_TOGGLE_RECENT_APPS:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].toggleRecentApps();
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).toggleRecentApps();
}
break;
case MSG_PRELOAD_RECENT_APPS:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].preloadRecentApps();
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).preloadRecentApps();
}
break;
case MSG_CANCEL_PRELOAD_RECENT_APPS:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].cancelPreloadRecentApps();
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).cancelPreloadRecentApps();
}
break;
case MSG_DISMISS_KEYBOARD_SHORTCUTS:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].dismissKeyboardShortcutsMenu();
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).dismissKeyboardShortcutsMenu();
}
break;
case MSG_TOGGLE_KEYBOARD_SHORTCUTS:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].toggleKeyboardShortcutsMenu(msg.arg1);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).toggleKeyboardShortcutsMenu(msg.arg1);
}
break;
case MSG_SET_WINDOW_STATE:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].setWindowState(msg.arg1, msg.arg2);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).setWindowState(msg.arg1, msg.arg2);
}
break;
case MSG_BUZZ_BEEP_BLINKED:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].buzzBeepBlinked();
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).buzzBeepBlinked();
}
break;
case MSG_NOTIFICATION_LIGHT_OFF:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].notificationLightOff();
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).notificationLightOff();
}
break;
case MSG_NOTIFICATION_LIGHT_PULSE:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].notificationLightPulse((Integer) msg.obj, msg.arg1, msg.arg2);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).notificationLightPulse((Integer) msg.obj, msg.arg1, msg.arg2);
}
break;
case MSG_SHOW_SCREEN_PIN_REQUEST:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].showScreenPinningRequest(msg.arg1);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).showScreenPinningRequest(msg.arg1);
}
break;
case MSG_APP_TRANSITION_PENDING:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].appTransitionPending();
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).appTransitionPending();
}
break;
case MSG_APP_TRANSITION_CANCELLED:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].appTransitionCancelled();
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).appTransitionCancelled();
}
break;
case MSG_APP_TRANSITION_STARTING:
for (int i = 0; i < mCallbacks.length; i++) {
for (int i = 0; i < mCallbacks.size(); i++) {
Pair<Long, Long> data = (Pair<Long, Long>) msg.obj;
mCallbacks[i].appTransitionStarting(data.first, data.second);
mCallbacks.get(i).appTransitionStarting(data.first, data.second);
}
break;
case MSG_APP_TRANSITION_FINISHED:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].appTransitionFinished();
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).appTransitionFinished();
}
break;
case MSG_ASSIST_DISCLOSURE:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].showAssistDisclosure();
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).showAssistDisclosure();
}
break;
case MSG_START_ASSIST:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].startAssist((Bundle) msg.obj);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).startAssist((Bundle) msg.obj);
}
break;
case MSG_CAMERA_LAUNCH_GESTURE:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].onCameraLaunchGestureDetected(msg.arg1);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onCameraLaunchGestureDetected(msg.arg1);
}
break;
case MSG_SHOW_TV_PICTURE_IN_PICTURE_MENU:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].showTvPictureInPictureMenu();
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).showTvPictureInPictureMenu();
}
break;
case MSG_ADD_QS_TILE:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].addQsTile((ComponentName) msg.obj);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).addQsTile((ComponentName) msg.obj);
}
break;
case MSG_REMOVE_QS_TILE:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].remQsTile((ComponentName) msg.obj);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).remQsTile((ComponentName) msg.obj);
}
break;
case MSG_CLICK_QS_TILE:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].clickTile((ComponentName) msg.obj);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).clickTile((ComponentName) msg.obj);
}
break;
case MSG_TOGGLE_APP_SPLIT_SCREEN:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].toggleSplitScreen();
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).toggleSplitScreen();
}
break;
case MSG_HANDLE_SYSNAV_KEY:
for (int i = 0; i < mCallbacks.length; i++) {
mCallbacks[i].handleSystemNavigationKey(msg.arg1);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).handleSystemNavigationKey(msg.arg1);
}
break;
}

View File

@@ -64,6 +64,7 @@ public class CarStatusBar extends PhoneStatusBar implements
private ConnectedDeviceSignalController mConnectedDeviceSignalController;
private View mSignalsView;
private CarNavigationBarView mNavigationBarView;
@Override
public void start() {
@@ -121,7 +122,17 @@ public class CarStatusBar extends PhoneStatusBar implements
}
@Override
protected void addNavigationBar() {
protected void createNavigationBar() {
if (mNavigationBarView != null) {
return;
}
mCarNavigationBar =
(CarNavigationBarView) View.inflate(mContext, R.layout.car_navigation_bar, null);
mController = new CarNavigationBarController(mContext, mCarNavigationBar,
this /* ActivityStarter*/);
mNavigationBarView = mCarNavigationBar;
mCarNavigationBar.getBarTransitions().setAlwaysOpaque(true);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
@@ -137,19 +148,6 @@ public class CarStatusBar extends PhoneStatusBar implements
mWindowManager.addView(mNavigationBarView, lp);
}
@Override
protected void createNavigationBarView(Context context) {
if (mNavigationBarView != null) {
return;
}
mCarNavigationBar =
(CarNavigationBarView) View.inflate(context, R.layout.car_navigation_bar, null);
mController = new CarNavigationBarController(context, mCarNavigationBar,
this /* ActivityStarter*/);
mNavigationBarView = mCarNavigationBar;
mCarNavigationBar.getBarTransitions().setAlwaysOpaque(true);
}
@Override
public void showBatteryView() {
if (Log.isLoggable(TAG, Log.DEBUG)) {
@@ -191,12 +189,6 @@ public class CarStatusBar extends PhoneStatusBar implements
mContext.registerReceiver(mPackageChangeReceiver, filter);
}
@Override
protected void repositionNavigationBar() {
// The navigation bar for a vehicle will not need to be repositioned, as it is always
// set at the bottom.
}
public boolean hasDockedTask() {
return Recents.getSystemServices().hasDockedTask();
}

View File

@@ -34,8 +34,8 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
private final StatusBarIconController mStatusBarIconController;
private final BatteryController mBatteryController;
private FingerprintUnlockController mFingerprintUnlockController;
private final NavigationBarView mNavigationBarView;
private LightBarTransitionsController mNavigationBarController;
private int mSystemUiVisibility;
private int mFullscreenStackVisibility;
private int mDockedStackVisibility;
@@ -50,22 +50,24 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
private final Rect mLastDockedBounds = new Rect();
public LightBarController(StatusBarIconController statusBarIconController,
NavigationBarView navigationBarView,
BatteryController batteryController) {
mStatusBarIconController = statusBarIconController;
mNavigationBarView = navigationBarView;
mBatteryController = batteryController;
batteryController.addCallback(this);
}
public void setNavigationBar(LightBarTransitionsController navigationBar) {
mNavigationBarController = navigationBar;
}
public void setFingerprintUnlockController(
FingerprintUnlockController fingerprintUnlockController) {
mFingerprintUnlockController = fingerprintUnlockController;
}
public void onSystemUiVisibilityChanged(int vis, int fullscreenStackVis, int dockedStackVis,
public void onSystemUiVisibilityChanged(int fullscreenStackVis, int dockedStackVis,
int mask, Rect fullscreenStackBounds, Rect dockedStackBounds, boolean sbModeChanged,
int statusBarMode, boolean nbModeChanged, int navigationBarMode) {
int statusBarMode) {
int oldFullscreen = mFullscreenStackVisibility;
int newFullscreen = (oldFullscreen & ~mask) | (fullscreenStackVis & mask);
int diffFullscreen = newFullscreen ^ oldFullscreen;
@@ -84,6 +86,15 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
updateStatus(fullscreenStackBounds, dockedStackBounds);
}
mFullscreenStackVisibility = newFullscreen;
mDockedStackVisibility = newDocked;
mLastStatusBarMode = statusBarMode;
mLastFullscreenBounds.set(fullscreenStackBounds);
mLastDockedBounds.set(dockedStackBounds);
}
public void onNavigationVisibilityChanged(int vis, int mask, boolean nbModeChanged,
int navigationBarMode) {
int oldVis = mSystemUiVisibility;
int newVis = (oldVis & ~mask) | (vis & mask);
int diffVis = newVis ^ oldVis;
@@ -95,19 +106,15 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
updateNavigation();
}
}
mFullscreenStackVisibility = newFullscreen;
mDockedStackVisibility = newDocked;
mSystemUiVisibility = newVis;
mLastStatusBarMode = statusBarMode;
mLastNavigationBarMode = navigationBarMode;
mLastFullscreenBounds.set(fullscreenStackBounds);
mLastDockedBounds.set(dockedStackBounds);
}
private void reevaluate() {
onSystemUiVisibilityChanged(mSystemUiVisibility, mFullscreenStackVisibility,
onSystemUiVisibilityChanged(mFullscreenStackVisibility,
mDockedStackVisibility, 0 /* mask */, mLastFullscreenBounds, mLastDockedBounds,
true /* sbModeChange*/, mLastStatusBarMode, true /* nbModeChange*/,
true /* sbModeChange*/, mLastStatusBarMode);
onNavigationVisibilityChanged(mSystemUiVisibility, 0 /* mask */, true /* nbModeChanged */,
mLastNavigationBarMode);
}
@@ -169,8 +176,8 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
}
private void updateNavigation() {
if (mNavigationBarView != null) {
mNavigationBarView.getLightTransitionsController().setIconsDark(
if (mNavigationBarController != null) {
mNavigationBarController.setIconsDark(
mNavigationLight, animateChange());
}
}

View File

@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
@@ -28,6 +29,7 @@ import com.android.systemui.Interpolators;
public class LightBarTransitionsController {
public static final long DEFAULT_TINT_ANIMATION_DURATION = 120;
private static final String EXTRA_DARK_INTENSITY = "dark_intensity";
private final Handler mHandler;
private final DarkIntensityApplier mApplier;
@@ -40,6 +42,7 @@ public class LightBarTransitionsController {
private float mPendingDarkIntensity;
private ValueAnimator mTintAnimator;
private float mDarkIntensity;
private float mNextDarkIntensity;
private final Runnable mTransitionDeferringDoneRunnable = new Runnable() {
@Override
@@ -53,6 +56,16 @@ public class LightBarTransitionsController {
mHandler = new Handler();
}
public void saveState(Bundle outState) {
float intensity = mTintAnimator != null && mTintAnimator.isRunning()
? mNextDarkIntensity : mDarkIntensity;
outState.putFloat(EXTRA_DARK_INTENSITY, intensity);
}
public void restoreState(Bundle savedInstanceState) {
setIconTintInternal(savedInstanceState.getFloat(EXTRA_DARK_INTENSITY, 0));
}
public void appTransitionPending() {
mTransitionPending = true;
}
@@ -119,6 +132,7 @@ public class LightBarTransitionsController {
if (mDarkIntensity == targetDarkIntensity) {
return;
}
mNextDarkIntensity = targetDarkIntensity;
mTintAnimator = ValueAnimator.ofFloat(mDarkIntensity, targetDarkIntensity);
mTintAnimator.addUpdateListener(
animation -> setIconTintInternal((Float) animation.getAnimatedValue()));

View File

@@ -0,0 +1,666 @@
/*
* Copyright (C) 2017 The Android Open Source 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 static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.windowStateToString;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
import static com.android.systemui.statusbar.phone.PhoneStatusBar.DEBUG_WINDOW_STATE;
import static com.android.systemui.statusbar.phone.PhoneStatusBar.dumpBarTransitions;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.Fragment;
import android.app.IActivityManager;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.inputmethodservice.InputMethodService;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.UserHandle;
import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.IRotationWatcher.Stub;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.keyguard.LatencyTracker;
import com.android.systemui.R;
import com.android.systemui.SystemUIApplication;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
import com.android.systemui.recents.Recents;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CommandQueue.Callbacks;
import com.android.systemui.statusbar.policy.KeyButtonView;
import com.android.systemui.statusbar.stack.StackStateAnimator;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Locale;
/**
* Fragment containing the NavigationBarFragment. Contains logic for what happens
* on clicks and view states of the nav bar.
*/
public class NavigationBarFragment extends Fragment implements Callbacks {
private static final String TAG = "NavigationBar";
private static final boolean DEBUG = false;
private static final String EXTRA_DISABLE_STATE = "disabled_state";
/** Allow some time inbetween the long press for back and recents. */
private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
protected NavigationBarView mNavigationBarView = null;
protected AssistManager mAssistManager;
private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
private int mNavigationIconHints = 0;
private int mNavigationBarMode;
protected AccessibilityManager mAccessibilityManager;
private int mDisabledFlags1;
private PhoneStatusBar mPhoneStatusBar;
private Recents mRecents;
private Divider mDivider;
private WindowManager mWindowManager;
private CommandQueue mCommandQueue;
private long mLastLockToAppLongPress;
private Locale mLocale;
private int mLayoutDirection;
private int mSystemUiVisibility;
private LightBarController mLightBarController;
private boolean mKeyguardGoingAway;
public boolean mHomeBlockedThisTouch;
// ----- Fragment Lifecycle Callbacks -----
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCommandQueue = SystemUIApplication.getComponent(getContext(), CommandQueue.class);
mCommandQueue.addCallbacks(this);
mPhoneStatusBar = SystemUIApplication.getComponent(getContext(), PhoneStatusBar.class);
mRecents = SystemUIApplication.getComponent(getContext(), Recents.class);
mDivider = SystemUIApplication.getComponent(getContext(), Divider.class);
mWindowManager = getContext().getSystemService(WindowManager.class);
mAccessibilityManager = getContext().getSystemService(AccessibilityManager.class);
if (savedInstanceState != null) {
mDisabledFlags1 = savedInstanceState.getInt(EXTRA_DISABLE_STATE, 0);
}
try {
WindowManagerGlobal.getWindowManagerService()
.watchRotation(mRotationWatcher);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@Override
public void onDestroy() {
super.onDestroy();
mCommandQueue.removeCallbacks(this);
try {
WindowManagerGlobal.getWindowManagerService()
.removeRotationWatcher(mRotationWatcher);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.navigation_bar, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mNavigationBarView = (NavigationBarView) view;
mNavigationBarView.setDisabledFlags(mDisabledFlags1);
mNavigationBarView.setComponents(mRecents, mDivider);
mNavigationBarView.setOnVerticalChangedListener(this::onVerticalChanged);
mNavigationBarView.setOnTouchListener(this::onNavigationTouch);
if (savedInstanceState != null) {
mNavigationBarView.getLightTransitionsController().restoreState(savedInstanceState);
}
prepareNavigationBarView();
checkNavBarModes();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
PowerManager pm = getContext().getSystemService(PowerManager.class);
notifyNavigationBarScreenOn(pm.isScreenOn());
}
@Override
public void onDestroyView() {
super.onDestroyView();
getContext().unregisterReceiver(mBroadcastReceiver);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(EXTRA_DISABLE_STATE, mDisabledFlags1);
if (mNavigationBarView != null) {
mNavigationBarView.getLightTransitionsController().saveState(outState);
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
final Locale locale = getContext().getResources().getConfiguration().locale;
final int ld = TextUtils.getLayoutDirectionFromLocale(locale);
if (!locale.equals(mLocale) || ld != mLayoutDirection) {
if (DEBUG) {
Log.v(TAG, String.format(
"config changed locale/LD: %s (%d) -> %s (%d)", mLocale, mLayoutDirection,
locale, ld));
}
mLocale = locale;
mLayoutDirection = ld;
refreshLayout(ld);
}
repositionNavigationBar();
}
@Override
public void dump(String prefix, FileDescriptor fd, PrintWriter pw, String[] args) {
if (mNavigationBarView != null) {
pw.print(" mNavigationBarWindowState=");
pw.println(windowStateToString(mNavigationBarWindowState));
pw.print(" mNavigationBarMode=");
pw.println(BarTransitions.modeToString(mNavigationBarMode));
dumpBarTransitions(pw, "mNavigationBarView", mNavigationBarView.getBarTransitions());
}
pw.print(" mNavigationBarView=");
if (mNavigationBarView == null) {
pw.println("null");
} else {
mNavigationBarView.dump(fd, pw, args);
}
}
// ----- CommandQueue Callbacks -----
@Override
public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
boolean showImeSwitcher) {
boolean imeShown = (vis & InputMethodService.IME_VISIBLE) != 0;
int hints = mNavigationIconHints;
if ((backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS) || imeShown) {
hints |= NAVIGATION_HINT_BACK_ALT;
} else {
hints &= ~NAVIGATION_HINT_BACK_ALT;
}
if (showImeSwitcher) {
hints |= NAVIGATION_HINT_IME_SHOWN;
} else {
hints &= ~NAVIGATION_HINT_IME_SHOWN;
}
if (hints == mNavigationIconHints) return;
mNavigationIconHints = hints;
if (mNavigationBarView != null) {
mNavigationBarView.setNavigationIconHints(hints);
}
mPhoneStatusBar.checkBarModes();
}
@Override
public void topAppWindowChanged(boolean showMenu) {
if (mNavigationBarView != null) {
mNavigationBarView.setMenuVisibility(showMenu);
}
}
@Override
public void setWindowState(int window, int state) {
if (mNavigationBarView != null
&& window == StatusBarManager.WINDOW_NAVIGATION_BAR
&& mNavigationBarWindowState != state) {
mNavigationBarWindowState = state;
if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
}
}
@Override
public void appTransitionPending() {
mNavigationBarView.getLightTransitionsController().appTransitionPending();
}
@Override
public void appTransitionCancelled() {
mNavigationBarView.getLightTransitionsController().appTransitionCancelled();
}
@Override
public void appTransitionStarting(long startTime, long duration) {
if (mKeyguardGoingAway) return;
doAppTransitionStarting(startTime, duration);
}
/**
* Calls appTransitionStarting for the nav bar regardless of whether keyguard is going away.
* public so PhoneStatusBar can force this when needed.
*/
public void doAppTransitionStarting(long startTime, long duration) {
mNavigationBarView.getLightTransitionsController().appTransitionStarting(startTime,
duration);
}
// Injected from PhoneStatusBar at creation.
public void setCurrentSysuiVisibility(int systemUiVisibility) {
mSystemUiVisibility = systemUiVisibility;
mNavigationBarMode = mPhoneStatusBar.computeBarMode(0, mSystemUiVisibility,
View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT,
View.NAVIGATION_BAR_TRANSPARENT);
checkNavBarModes();
mPhoneStatusBar.touchAutoHide();
mLightBarController.onNavigationVisibilityChanged(mSystemUiVisibility, 0 /* mask */,
true /* nbModeChanged */, mNavigationBarMode);
}
@Override
public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
final int oldVal = mSystemUiVisibility;
final int newVal = (oldVal & ~mask) | (vis & mask);
final int diff = newVal ^ oldVal;
boolean nbModeChanged = false;
if (diff != 0) {
mSystemUiVisibility = newVal;
// update navigation bar mode
final int nbMode = getView() == null
? -1 : mPhoneStatusBar.computeBarMode(oldVal, newVal,
View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT,
View.NAVIGATION_BAR_TRANSPARENT);
nbModeChanged = nbMode != -1;
if (nbModeChanged) {
if (mNavigationBarMode != nbMode) {
mNavigationBarMode = nbMode;
checkNavBarModes();
}
mPhoneStatusBar.touchAutoHide();
}
}
mLightBarController.onNavigationVisibilityChanged(vis, mask, nbModeChanged,
mNavigationBarMode);
}
@Override
public void disable(int state1, int state2, boolean animate) {
// All navigation bar flags are in state1.
int masked = state1 & (StatusBarManager.DISABLE_HOME
| StatusBarManager.DISABLE_RECENT
| StatusBarManager.DISABLE_BACK
| StatusBarManager.DISABLE_SEARCH);
if (masked != mDisabledFlags1) {
mDisabledFlags1 = masked;
if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state1);
}
}
// ----- Internal stuffz -----
private void refreshLayout(int layoutDirection) {
if (mNavigationBarView != null) {
mNavigationBarView.setLayoutDirection(layoutDirection);
}
}
private boolean shouldDisableNavbarGestures() {
return !mPhoneStatusBar.isDeviceProvisioned()
|| (mDisabledFlags1 & StatusBarManager.DISABLE_SEARCH) != 0;
}
private void repositionNavigationBar() {
if (mNavigationBarView == null || !mNavigationBarView.isAttachedToWindow()) return;
prepareNavigationBarView();
mWindowManager.updateViewLayout((View) mNavigationBarView.getParent(),
((View) mNavigationBarView.getParent()).getLayoutParams());
}
private void notifyNavigationBarScreenOn(boolean screenOn) {
mNavigationBarView.notifyScreenOn(screenOn);
}
private void prepareNavigationBarView() {
mNavigationBarView.reorient();
ButtonDispatcher recentsButton = mNavigationBarView.getRecentsButton();
recentsButton.setOnClickListener(this::onRecentsClick);
recentsButton.setOnTouchListener(this::onRecentsTouch);
recentsButton.setLongClickable(true);
recentsButton.setOnLongClickListener(this::onLongPressBackRecents);
ButtonDispatcher backButton = mNavigationBarView.getBackButton();
backButton.setLongClickable(true);
backButton.setOnLongClickListener(this::onLongPressBackRecents);
ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
homeButton.setOnTouchListener(this::onHomeTouch);
homeButton.setOnLongClickListener(this::onHomeLongClick);
if (mAssistManager != null) {
mAssistManager.onConfigurationChanged();
}
}
private boolean onHomeTouch(View v, MotionEvent event) {
if (mHomeBlockedThisTouch && event.getActionMasked() != MotionEvent.ACTION_DOWN) {
return true;
}
// If an incoming call is ringing, HOME is totally disabled.
// (The user is already on the InCallUI at this point,
// and his ONLY options are to answer or reject the call.)
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mHomeBlockedThisTouch = false;
TelecomManager telecomManager =
getContext().getSystemService(TelecomManager.class);
if (telecomManager != null && telecomManager.isRinging()) {
if (mPhoneStatusBar.isKeyguardShowing()) {
Log.i(TAG, "Ignoring HOME; there's a ringing incoming call. " +
"No heads up");
mHomeBlockedThisTouch = true;
return true;
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mPhoneStatusBar.awakenDreams();
break;
}
return false;
}
private void onVerticalChanged(boolean isVertical) {
if (mAssistManager != null) {
// TODO: Clean this up.
mAssistManager.onConfigurationChanged();
}
mPhoneStatusBar.setQsScrimEnabled(!isVertical);
}
private boolean onNavigationTouch(View v, MotionEvent event) {
mPhoneStatusBar.checkUserAutohide(v, event);
return false;
}
private boolean onHomeLongClick(View v) {
if (shouldDisableNavbarGestures()) {
return false;
}
MetricsLogger.action(getContext(), MetricsEvent.ACTION_ASSIST_LONG_PRESS);
mAssistManager.startAssist(new Bundle() /* args */);
mPhoneStatusBar.awakenDreams();
if (mNavigationBarView != null) {
mNavigationBarView.abortCurrentGesture();
}
return true;
}
// additional optimization when we have software system buttons - start loading the recent
// tasks on touch down
private boolean onRecentsTouch(View v, MotionEvent event) {
int action = event.getAction() & MotionEvent.ACTION_MASK;
if (action == MotionEvent.ACTION_DOWN) {
mCommandQueue.preloadRecentApps();
} else if (action == MotionEvent.ACTION_CANCEL) {
mCommandQueue.cancelPreloadRecentApps();
} else if (action == MotionEvent.ACTION_UP) {
if (!v.isPressed()) {
mCommandQueue.cancelPreloadRecentApps();
}
}
return false;
}
private void onRecentsClick(View v) {
if (LatencyTracker.isEnabled(getContext())) {
LatencyTracker.getInstance(getContext()).onActionStart(
LatencyTracker.ACTION_TOGGLE_RECENTS);
}
mPhoneStatusBar.awakenDreams();
mCommandQueue.toggleRecentApps();
}
/**
* This handles long-press of both back and recents. They are
* handled together to capture them both being long-pressed
* at the same time to exit screen pinning (lock task).
*
* When accessibility mode is on, only a long-press from recents
* is required to exit.
*
* In all other circumstances we try to pass through long-press events
* for Back, so that apps can still use it. Which can be from two things.
* 1) Not currently in screen pinning (lock task).
* 2) Back is long-pressed without recents.
*/
private boolean onLongPressBackRecents(View v) {
try {
boolean sendBackLongPress = false;
IActivityManager activityManager = ActivityManagerNative.getDefault();
boolean touchExplorationEnabled = mAccessibilityManager.isTouchExplorationEnabled();
boolean inLockTaskMode = activityManager.isInLockTaskMode();
if (inLockTaskMode && !touchExplorationEnabled) {
long time = System.currentTimeMillis();
// If we recently long-pressed the other button then they were
// long-pressed 'together'
if ((time - mLastLockToAppLongPress) < LOCK_TO_APP_GESTURE_TOLERENCE) {
activityManager.stopLockTaskMode();
// When exiting refresh disabled flags.
mNavigationBarView.setDisabledFlags(mDisabledFlags1, true);
return true;
} else if ((v.getId() == R.id.back)
&& !mNavigationBarView.getRecentsButton().getCurrentView().isPressed()) {
// If we aren't pressing recents right now then they presses
// won't be together, so send the standard long-press action.
sendBackLongPress = true;
}
mLastLockToAppLongPress = time;
} else {
// If this is back still need to handle sending the long-press event.
if (v.getId() == R.id.back) {
sendBackLongPress = true;
} else if (touchExplorationEnabled && inLockTaskMode) {
// When in accessibility mode a long press that is recents (not back)
// should stop lock task.
activityManager.stopLockTaskMode();
// When exiting refresh disabled flags.
mNavigationBarView.setDisabledFlags(mDisabledFlags1, true);
return true;
} else if (v.getId() == R.id.recent_apps) {
return onLongPressRecents();
}
}
if (sendBackLongPress) {
KeyButtonView keyButtonView = (KeyButtonView) v;
keyButtonView.sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
keyButtonView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
return true;
}
} catch (RemoteException e) {
Log.d(TAG, "Unable to reach activity manager", e);
}
return false;
}
private boolean onLongPressRecents() {
if (mRecents == null || !ActivityManager.supportsMultiWindow()
|| !mDivider.getView().getSnapAlgorithm()
.isSplitScreenFeasible()) {
return false;
}
return mPhoneStatusBar.toggleSplitScreenMode(MetricsEvent.ACTION_WINDOW_DOCK_LONGPRESS,
MetricsEvent.ACTION_WINDOW_UNDOCK_LONGPRESS);
}
// ----- Methods that PhoneStatusBar talks to (should be minimized) -----
public void setAssistManager(AssistManager assistManager) {
mAssistManager = assistManager;
}
public void setLightBarController(LightBarController lightBarController) {
mLightBarController = lightBarController;
mLightBarController.setNavigationBar(mNavigationBarView.getLightTransitionsController());
}
public boolean isSemiTransparent() {
return mNavigationBarMode == MODE_SEMI_TRANSPARENT;
}
public void onKeyguardOccludedChanged(boolean keyguardOccluded) {
mNavigationBarView.onKeyguardOccludedChanged(keyguardOccluded);
}
public void disableAnimationsDuringHide(long delay) {
mNavigationBarView.setLayoutTransitionsEnabled(false);
mNavigationBarView.postDelayed(() -> mNavigationBarView.setLayoutTransitionsEnabled(true),
delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
}
public void setKeyguardGoingAway(boolean keyguardGoingAway) {
mKeyguardGoingAway = keyguardGoingAway;
}
public BarTransitions getBarTransitions() {
return mNavigationBarView.getBarTransitions();
}
public void checkNavBarModes() {
mPhoneStatusBar.checkBarMode(mNavigationBarMode,
mNavigationBarWindowState, mNavigationBarView.getBarTransitions());
}
public void finishBarAnimations() {
mNavigationBarView.getBarTransitions().finishAnimations();
}
private final Stub mRotationWatcher = new Stub() {
@Override
public void onRotationChanged(int rotation) throws RemoteException {
// We need this to be scheduled as early as possible to beat the redrawing of
// window in response to the orientation change.
Handler h = getView().getHandler();
Message msg = Message.obtain(h, () -> {
if (mNavigationBarView != null
&& mNavigationBarView.needsReorient(rotation)) {
repositionNavigationBar();
}
});
msg.setAsynchronous(true);
h.sendMessageAtFrontOfQueue(msg);
}
};
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_SCREEN_OFF.equals(action)) {
notifyNavigationBarScreenOn(false);
} else if (Intent.ACTION_SCREEN_ON.equals(action)) {
notifyNavigationBarScreenOn(true);
}
}
};
public static View create(Context context, FragmentListener listener) {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
| WindowManager.LayoutParams.FLAG_SLIPPERY,
PixelFormat.TRANSLUCENT);
lp.token = new Binder();
// this will allow the navbar to run in an overlay on devices that support this
if (ActivityManager.isHighEndGfx()) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
lp.setTitle("NavigationBar");
lp.windowAnimations = 0;
View navigationBarView = LayoutInflater.from(context).inflate(
R.layout.navigation_bar_window, null);
if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + navigationBarView);
if (navigationBarView == null) return null;
context.getSystemService(WindowManager.class).addView(navigationBarView, lp);
FragmentHostManager fragmentHost = FragmentHostManager.get(navigationBarView);
NavigationBarFragment fragment = new NavigationBarFragment();
fragmentHost.getFragmentManager().beginTransaction()
.replace(R.id.navigation_bar_frame, fragment, TAG)
.commit();
fragmentHost.addTagListener(TAG, listener);
return navigationBarView;
}
}

View File

@@ -70,7 +70,6 @@ public class NavigationBarInflaterView extends FrameLayout
protected LayoutInflater mLayoutInflater;
protected LayoutInflater mLandscapeInflater;
private int mDensity;
protected FrameLayout mRot0;
protected FrameLayout mRot90;
@@ -86,7 +85,6 @@ public class NavigationBarInflaterView extends FrameLayout
public NavigationBarInflaterView(Context context, AttributeSet attrs) {
super(context, attrs);
mDensity = context.getResources().getConfiguration().densityDpi;
createInflaters();
Display display = ((WindowManager)
context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
@@ -102,18 +100,6 @@ public class NavigationBarInflaterView extends FrameLayout
mLandscapeInflater = LayoutInflater.from(mContext.createConfigurationContext(landscape));
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (mDensity != newConfig.densityDpi) {
mDensity = newConfig.densityDpi;
createInflaters();
inflateChildren();
clearViews();
inflateLayout(mCurrentLayout);
}
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();

View File

@@ -434,7 +434,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
|| ((disabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0);
final boolean disableBack = ((disabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0)
&& ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) == 0);
final boolean disableSearch = ((disabledFlags & View.STATUS_BAR_DISABLE_SEARCH) != 0);
ViewGroup navButtons = (ViewGroup) getCurrentView().findViewById(R.id.nav_buttons);
if (navButtons != null) {
@@ -495,7 +494,8 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
}
private void setUseFadingAnimations(boolean useFadingAnimations) {
WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams();
WindowManager.LayoutParams lp = (WindowManager.LayoutParams) ((ViewGroup) getParent())
.getLayoutParams();
if (lp != null) {
boolean old = lp.windowAnimations != 0;
if (!old && useFadingAnimations) {
@@ -506,7 +506,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
return;
}
WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
wm.updateViewLayout(this, lp);
wm.updateViewLayout((View) getParent(), lp);
}
}

View File

@@ -289,7 +289,7 @@ public class NotificationPanelView extends PanelView implements
lp.width = panelWidth;
lp.gravity = panelGravity;
mQsFrame.setLayoutParams(lp);
mQs.getView().post(mUpdateHeader);
post(mUpdateHeader);
}
lp = (FrameLayout.LayoutParams) mNotificationStackScroller.getLayoutParams();

View File

@@ -17,8 +17,6 @@
package com.android.systemui.statusbar.phone;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.windowStateToString;
@@ -34,9 +32,7 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.ActivityOptions;
import android.app.IActivityManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -66,7 +62,6 @@ import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.inputmethodservice.InputMethodService;
import android.media.AudioAttributes;
import android.media.MediaMetadata;
import android.media.session.MediaController;
@@ -75,7 +70,6 @@ import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
@@ -95,26 +89,22 @@ import android.os.Vibrator;
import android.provider.Settings;
import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
import android.telecom.TelecomManager;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
import android.view.Display;
import android.view.IRotationWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.ThreadedRenderer;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewParent;
import android.view.ViewStub;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.DateTimeView;
@@ -129,7 +119,6 @@ import com.android.keyguard.KeyguardHostView.OnDismissAction;
import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.LatencyTracker;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.BatteryMeterView;
import com.android.systemui.DemoMode;
@@ -189,7 +178,6 @@ import com.android.systemui.statusbar.policy.EncryptionHelper;
import com.android.systemui.statusbar.policy.FlashlightControllerImpl;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.HotspotControllerImpl;
import com.android.systemui.statusbar.policy.KeyButtonView;
import com.android.systemui.statusbar.policy.KeyguardMonitorImpl;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
import com.android.systemui.statusbar.policy.LocationControllerImpl;
@@ -205,7 +193,7 @@ import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
import com.android.systemui.statusbar.stack.StackStateAnimator;
import com.android.systemui.volume.VolumeComponent;
import java.io.FileDescriptor;
@@ -270,9 +258,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
public static final int FADE_KEYGUARD_DURATION = 300;
public static final int FADE_KEYGUARD_DURATION_PULSING = 96;
/** Allow some time inbetween the long press for back and recents. */
private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
/** If true, the system is in the half-boot-to-decryption-screen state.
* Prudently disable QS and notifications. */
private static final boolean ONLY_CORE_APPS;
@@ -395,8 +380,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
boolean mExpandedVisible;
private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
// the tracker view
int mTrackingPosition; // the position of the top of the tracking view.
@@ -426,8 +409,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
: null;
private ScreenPinningRequest mScreenPinningRequest;
private int mNavigationIconHints = 0;
private HandlerThread mHandlerThread;
private HandlerThread mTimeTickThread;
private Handler mTimeTickHandler;
@@ -486,7 +467,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private int mInteractingWindows;
private boolean mAutohideSuspended;
private int mStatusBarMode;
private int mNavigationBarMode;
private int mMaxKeyguardNotifications;
private ViewMediatorCallback mKeyguardViewMediatorCallback;
@@ -675,7 +655,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private RankingMap mLatestRankingMap;
private boolean mNoAnimationOnNextBarModeChange;
private FalsingManager mFalsingManager;
private long mLastLockToAppLongPress;
private KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
@Override
@@ -686,6 +665,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
};
private NavigationBarFragment mNavigationBar;
private View mNavigationBarView;
@Override
public void start() {
mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
@@ -710,8 +692,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
// TODO: use MediaSessionManager.SessionListener to hook us up to future updates
// in session state
addNavigationBar();
// Lastly, call to the icon policy to install/update all the icons.
mIconPolicy = new PhoneStatusBarPolicy(mContext, mIconController, mCastController,
mHotspotController, mUserInfoController, mBluetoothController,
@@ -809,7 +789,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
boolean showNav = mWindowManagerService.hasNavigationBar();
if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
if (showNav) {
createNavigationBarView(context);
createNavigationBar();
}
} catch (RemoteException ex) {
// no window manager? good luck with that
@@ -874,8 +854,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
});
mLightBarController = new LightBarController(mIconController, mNavigationBarView,
mBatteryController);
mLightBarController = new LightBarController(mIconController, mBatteryController);
if (mNavigationBar != null) {
mNavigationBar.setLightBarController(mLightBarController);
}
ScrimView scrimBehind = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_behind);
ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
@@ -1002,8 +984,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mBroadcastReceiver.onReceive(mContext,
new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF));
if (!pm.isScreenOn()) {
mBroadcastReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF));
}
mGestureWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
"GestureWakeLock");
mVibrator = mContext.getSystemService(Vibrator.class);
@@ -1018,7 +1001,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG);
context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
@@ -1051,6 +1033,17 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
.getComponent(PhoneStatusBar.class).getTimeTickHandler();
}
protected void createNavigationBar() {
mNavigationBarView = NavigationBarFragment.create(mContext, (tag, fragment) -> {
mNavigationBar = (NavigationBarFragment) fragment;
mNavigationBar.setAssistManager(mAssistManager);
if (mLightBarController != null) {
mNavigationBar.setLightBarController(mLightBarController);
}
mNavigationBar.setCurrentSysuiVisibility(mSystemUiVisibility);
});
}
private void initEmergencyCryptkeeperText() {
View emergencyViewStub = mStatusBarWindow.findViewById(R.id.emergency_cryptkeeper_text);
if (mNetworkController.hasEmergencyCryptKeeperText()) {
@@ -1175,33 +1168,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
R.layout.super_status_bar, null);
}
protected void createNavigationBarView(Context context) {
inflateNavigationBarView(context);
mNavigationBarView.setDisabledFlags(mDisabled1);
mNavigationBarView.setComponents(mRecents, getComponent(Divider.class));
mNavigationBarView.setOnVerticalChangedListener(
new NavigationBarView.OnVerticalChangedListener() {
@Override
public void onVerticalChanged(boolean isVertical) {
if (mAssistManager != null) {
mAssistManager.onConfigurationChanged();
}
mNotificationPanel.setQsScrimEnabled(!isVertical);
}
});
mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
checkUserAutohide(v, event);
return false;
}});
}
protected void inflateNavigationBarView(Context context) {
mNavigationBarView = (NavigationBarView) View.inflate(
context, R.layout.navigation_bar, null);
}
protected void initSignalCluster(View containerView) {
SignalClusterView signalCluster =
(SignalClusterView) containerView.findViewById(R.id.signal_cluster);
@@ -1353,18 +1319,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
return mNaturalBarHeight;
}
private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (LatencyTracker.isEnabled(mContext)) {
LatencyTracker.getInstance(mContext).onActionStart(
LatencyTracker.ACTION_TOGGLE_RECENTS);
}
awakenDreams();
toggleRecentApps();
}
};
@Override
protected boolean toggleSplitScreenMode(int metricsDockAction, int metricsUndockAction) {
if (mRecents == null) {
@@ -1389,57 +1343,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
return true;
}
private final View.OnLongClickListener mLongPressHomeListener
= new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (shouldDisableNavbarGestures()) {
return false;
}
MetricsLogger.action(mContext, MetricsEvent.ACTION_ASSIST_LONG_PRESS);
mAssistManager.startAssist(new Bundle() /* args */);
awakenDreams();
if (mNavigationBarView != null) {
mNavigationBarView.abortCurrentGesture();
}
return true;
}
};
private final View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
public boolean mBlockedThisTouch;
@Override
public boolean onTouch(View v, MotionEvent event) {
if (mBlockedThisTouch && event.getActionMasked() != MotionEvent.ACTION_DOWN) {
return true;
}
// If an incoming call is ringing, HOME is totally disabled.
// (The user is already on the InCallUI at this point,
// and his ONLY options are to answer or reject the call.)
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mBlockedThisTouch = false;
TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
if (telecomManager != null && telecomManager.isRinging()) {
if (mStatusBarKeyguardViewManager.isShowing()) {
Log.i(TAG, "Ignoring HOME; there's a ringing incoming call. " +
"No heads up");
mBlockedThisTouch = true;
return true;
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
awakenDreams();
break;
}
return false;
}
};
private void awakenDreams() {
void awakenDreams() {
if (mDreamManager != null) {
try {
mDreamManager.awaken();
@@ -1449,93 +1353,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
}
private void prepareNavigationBarView() {
mNavigationBarView.reorient();
ButtonDispatcher recentsButton = mNavigationBarView.getRecentsButton();
recentsButton.setOnClickListener(mRecentsClickListener);
recentsButton.setOnTouchListener(mRecentsPreloadOnTouchListener);
recentsButton.setLongClickable(true);
recentsButton.setOnLongClickListener(this::handleLongPressBackRecents);
ButtonDispatcher backButton = mNavigationBarView.getBackButton();
backButton.setLongClickable(true);
backButton.setOnLongClickListener(this::handleLongPressBackRecents);
ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
homeButton.setOnTouchListener(mHomeActionListener);
homeButton.setOnLongClickListener(mLongPressHomeListener);
mAssistManager.onConfigurationChanged();
}
// For small-screen devices (read: phones) that lack hardware navigation buttons
protected void addNavigationBar() {
if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
if (mNavigationBarView == null) return;
try {
WindowManagerGlobal.getWindowManagerService()
.watchRotation(new IRotationWatcher.Stub() {
@Override
public void onRotationChanged(int rotation) throws RemoteException {
// We need this to be scheduled as early as possible to beat the redrawing of
// window in response to the orientation change.
Message msg = Message.obtain(mHandler, () -> {
if (mNavigationBarView != null
&& mNavigationBarView.needsReorient(rotation)) {
repositionNavigationBar();
}
});
msg.setAsynchronous(true);
mHandler.sendMessageAtFrontOfQueue(msg);
}
});
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
prepareNavigationBarView();
mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
}
protected void repositionNavigationBar() {
if (mNavigationBarView == null || !mNavigationBarView.isAttachedToWindow()) return;
prepareNavigationBarView();
mWindowManager.updateViewLayout(mNavigationBarView, mNavigationBarView.getLayoutParams());
}
private void notifyNavigationBarScreenOn(boolean screenOn) {
if (mNavigationBarView == null) return;
mNavigationBarView.notifyScreenOn(screenOn);
}
private WindowManager.LayoutParams getNavigationBarLayoutParams() {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
0
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
| WindowManager.LayoutParams.FLAG_SLIPPERY,
PixelFormat.TRANSLUCENT);
lp.token = new Binder();
// this will allow the navbar to run in an overlay on devices that support this
if (ActivityManager.isHighEndGfx()) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
lp.setTitle("NavigationBar");
lp.windowAnimations = 0;
return lp;
}
@Override
public void setIcon(String slot, StatusBarIcon icon) {
mIconController.setIcon(slot, icon);
@@ -1752,13 +1569,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
super.performRemoveNotification(n);
}
@Override
protected void refreshLayout(int layoutDirection) {
if (mNavigationBarView != null) {
mNavigationBarView.setLayoutDirection(layoutDirection);
}
}
private void updateNotificationShade() {
if (mStackScroller == null) return;
@@ -2496,9 +2306,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
| StatusBarManager.DISABLE_RECENT
| StatusBarManager.DISABLE_BACK
| StatusBarManager.DISABLE_SEARCH)) != 0) {
// the nav bar will take care of these
if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state1);
if ((state1 & StatusBarManager.DISABLE_RECENT) != 0) {
// close recents if it's visible
mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
@@ -2560,10 +2367,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
return mLeaveOpenOnKeyguardHide;
}
public boolean isQsExpanded() {
return mNotificationPanel.isQsExpanded();
}
public boolean isWakeUpComingFromTouch() {
return mWakeUpComingFromTouch;
}
@@ -3040,17 +2843,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
return mFingerprintUnlockController;
}
private void setNavigationIconHints(int hints) {
if (hints == mNavigationIconHints) return;
mNavigationIconHints = hints;
if (mNavigationBarView != null) {
mNavigationBarView.setNavigationIconHints(hints);
}
checkBarModes();
}
@Override // CommandQueue
public void setWindowState(int window, int state) {
boolean showing = state == WINDOW_STATE_SHOWING;
@@ -3064,12 +2856,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
1.0f /* speedUpFactor */);
}
}
if (mNavigationBarView != null
&& window == StatusBarManager.WINDOW_NAVIGATION_BAR
&& mNavigationBarWindowState != state) {
mNavigationBarWindowState = state;
if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
}
}
@Override // CommandQueue
@@ -3105,7 +2891,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
Integer.toHexString(oldVal), Integer.toHexString(newVal),
Integer.toHexString(diff)));
boolean sbModeChanged = false;
boolean nbModeChanged = false;
if (diff != 0) {
mSystemUiVisibility = newVal;
@@ -3123,32 +2908,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
// update status bar mode
final int sbMode = computeStatusBarMode(oldVal, newVal);
// update navigation bar mode
final int nbMode = mNavigationBarView == null ? -1 : computeBarMode(
oldVal, newVal, mNavigationBarView.getBarTransitions(),
View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT,
View.NAVIGATION_BAR_TRANSPARENT);
sbModeChanged = sbMode != -1;
nbModeChanged = nbMode != -1;
boolean checkBarModes = false;
if (sbModeChanged && sbMode != mStatusBarMode) {
mStatusBarMode = sbMode;
checkBarModes = true;
}
if (nbModeChanged && nbMode != mNavigationBarMode) {
mNavigationBarMode = nbMode;
checkBarModes = true;
}
if (checkBarModes) {
checkBarModes();
}
if (sbModeChanged || nbModeChanged) {
// update transient bar autohide
if (mStatusBarMode == MODE_SEMI_TRANSPARENT || mNavigationBarMode == MODE_SEMI_TRANSPARENT) {
scheduleAutohide();
} else {
cancelAutohide();
if (sbMode != mStatusBarMode) {
mStatusBarMode = sbMode;
checkBarModes();
}
touchAutoHide();
}
if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) {
@@ -3159,22 +2925,30 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
notifyUiVisibilityChanged(mSystemUiVisibility);
}
mLightBarController.onSystemUiVisibilityChanged(vis, fullscreenStackVis, dockedStackVis,
mask, fullscreenStackBounds, dockedStackBounds, sbModeChanged, mStatusBarMode,
nbModeChanged, mNavigationBarMode);
mLightBarController.onSystemUiVisibilityChanged(fullscreenStackVis, dockedStackVis,
mask, fullscreenStackBounds, dockedStackBounds, sbModeChanged, mStatusBarMode);
}
void touchAutoHide() {
// update transient bar autohide
if (mStatusBarMode == MODE_SEMI_TRANSPARENT || (mNavigationBar != null
&& mNavigationBar.isSemiTransparent())) {
scheduleAutohide();
} else {
cancelAutohide();
}
}
protected int computeStatusBarMode(int oldVal, int newVal) {
return computeBarMode(oldVal, newVal, getStatusBarTransitions(),
View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_TRANSLUCENT,
View.STATUS_BAR_TRANSPARENT);
return computeBarMode(oldVal, newVal, View.STATUS_BAR_TRANSIENT,
View.STATUS_BAR_TRANSLUCENT, View.STATUS_BAR_TRANSPARENT);
}
protected BarTransitions getStatusBarTransitions() {
return mStatusBarView.getBarTransitions();
}
protected int computeBarMode(int oldVis, int newVis, BarTransitions transitions,
protected int computeBarMode(int oldVis, int newVis,
int transientFlag, int translucentFlag, int transparentFlag) {
final int oldMode = barMode(oldVis, transientFlag, translucentFlag, transparentFlag);
final int newMode = barMode(newVis, transientFlag, translucentFlag, transparentFlag);
@@ -3194,22 +2968,21 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
: MODE_OPAQUE;
}
private void checkBarModes() {
void checkBarModes() {
if (mDemoMode) return;
checkBarMode(mStatusBarMode, mStatusBarWindowState, getStatusBarTransitions(),
mNoAnimationOnNextBarModeChange);
if (mNavigationBarView != null) {
checkBarMode(mNavigationBarMode,
mNavigationBarWindowState, mNavigationBarView.getBarTransitions(),
mNoAnimationOnNextBarModeChange);
}
checkBarMode(mStatusBarMode, mStatusBarWindowState, getStatusBarTransitions());
if (mNavigationBar != null) mNavigationBar.checkNavBarModes();
mNoAnimationOnNextBarModeChange = false;
}
private void checkBarMode(int mode, int windowState, BarTransitions transitions,
boolean noAnimation) {
// Called by NavigationBarFragment
void setQsScrimEnabled(boolean scrimEnabled) {
mNotificationPanel.setQsScrimEnabled(scrimEnabled);
}
void checkBarMode(int mode, int windowState, BarTransitions transitions) {
final boolean powerSave = mBatteryController.isPowerSave();
final boolean anim = !noAnimation && mDeviceInteractive
final boolean anim = !mNoAnimationOnNextBarModeChange && mDeviceInteractive
&& windowState != WINDOW_STATE_HIDDEN && !powerSave;
if (powerSave && getBarState() == StatusBarState.SHADE) {
mode = MODE_WARNING;
@@ -3219,8 +2992,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private void finishBarAnimations() {
mStatusBarView.getBarTransitions().finishAnimations();
if (mNavigationBarView != null) {
mNavigationBarView.getBarTransitions().finishAnimations();
if (mNavigationBar != null) {
mNavigationBar.finishBarAnimations();
}
}
@@ -3278,7 +3051,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS);
}
private void checkUserAutohide(View v, MotionEvent event) {
void checkUserAutohide(View v, MotionEvent event) {
if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0 // a transient bar is revealed
&& event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
&& event.getX() == 0 && event.getY() == 0 // a touch outside both bars
@@ -3331,33 +3104,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (SPEW) {
Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
}
if (mNavigationBarView != null) {
mNavigationBarView.setMenuVisibility(showMenu);
}
// See above re: lights-out policy for legacy apps.
if (showMenu) setLightsOn(true);
}
@Override
public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
boolean showImeSwitcher) {
boolean imeShown = (vis & InputMethodService.IME_VISIBLE) != 0;
int flags = mNavigationIconHints;
if ((backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS) || imeShown) {
flags |= NAVIGATION_HINT_BACK_ALT;
} else {
flags &= ~NAVIGATION_HINT_BACK_ALT;
}
if (showImeSwitcher) {
flags |= NAVIGATION_HINT_IME_SHOWN;
} else {
flags &= ~NAVIGATION_HINT_IME_SHOWN;
}
setNavigationIconHints(flags);
}
public static String viewInfo(View v) {
return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
+ ") " + v.getWidth() + "x" + v.getHeight() + "]";
@@ -3388,20 +3139,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
pw.print(" mUseHeadsUp=");
pw.println(mUseHeadsUp);
dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
if (mNavigationBarView != null) {
pw.print(" mNavigationBarWindowState=");
pw.println(windowStateToString(mNavigationBarWindowState));
pw.print(" mNavigationBarMode=");
pw.println(BarTransitions.modeToString(mNavigationBarMode));
dumpBarTransitions(pw, "mNavigationBarView", mNavigationBarView.getBarTransitions());
}
pw.print(" mNavigationBarView=");
if (mNavigationBarView == null) {
pw.println("null");
} else {
mNavigationBarView.dump(fd, pw, args);
}
pw.print(" mMediaSessionManager=");
pw.println(mMediaSessionManager);
@@ -3510,7 +3247,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
}
private static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
pw.print(" "); pw.print(var); pw.print(".BarTransitions.mMode=");
pw.println(BarTransitions.modeToString(transitions.getMode()));
}
@@ -3652,14 +3389,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
}
else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
notifyNavigationBarScreenOn(false);
notifyHeadsUpScreenOff();
finishBarAnimations();
resetUserExpandedStates();
}
else if (Intent.ACTION_SCREEN_ON.equals(action)) {
notifyNavigationBarScreenOn(true);
}
else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
mQSPanel.showDeviceMonitoringDialog();
}
@@ -3728,7 +3461,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
}
repositionNavigationBar();
updateRowStates();
mScreenPinningRequest.onConfigurationChanged();
mNetworkController.onConfigurationChanged();
@@ -3872,7 +3604,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
public void onKeyguardOccludedChanged(boolean keyguardOccluded) {
mNavigationBarView.onKeyguardOccludedChanged(keyguardOccluded);
mNavigationBar.onKeyguardOccludedChanged(keyguardOccluded);
}
// State logging
@@ -3950,11 +3682,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
};
@Override
public boolean shouldDisableNavbarGestures() {
return !isDeviceProvisioned() || (mDisabled1 & StatusBarManager.DISABLE_SEARCH) != 0;
}
public void postQSRunnableDismissingKeyguard(final Runnable runnable) {
mHandler.post(new Runnable() {
@Override
@@ -4111,8 +3838,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (mStatusBarView != null) {
mStatusBarView.getBarTransitions().transitionTo(barMode, animate);
}
if (mNavigationBarView != null) {
mNavigationBarView.getBarTransitions().transitionTo(barMode, animate);
if (mNavigationBar != null) {
mNavigationBar.getBarTransitions().transitionTo(barMode, animate);
}
}
}
@@ -4233,8 +3960,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mIconController.getTransitionsController().appTransitionStarting(
SystemClock.uptimeMillis(),
LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION);
if (mNavigationBarView != null) {
mNavigationBarView.getLightTransitionsController().appTransitionStarting(
if (mNavigationBar != null) {
mNavigationBar.doAppTransitionStarting(
SystemClock.uptimeMillis(),
LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION);
}
@@ -4318,14 +4045,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
// Disable layout transitions in navbar for this transition because the load is just
// too heavy for the CPU and GPU on any device.
if (mNavigationBarView != null) {
mNavigationBarView.setLayoutTransitionsEnabled(false);
mNavigationBarView.postDelayed(new Runnable() {
@Override
public void run() {
mNavigationBarView.setLayoutTransitionsEnabled(true);
}
}, delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
if (mNavigationBar != null) {
mNavigationBar.disableAnimationsDuringHide(delay);
}
} else if (!mNotificationPanel.isCollapsing()) {
instantCollapseNotificationPanel();
@@ -4369,8 +4090,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
// bar.
mKeyguardGoingAway = true;
mIconController.getTransitionsController().appTransitionPending();
if (mNavigationBarView != null) {
mNavigationBarView.getLightTransitionsController().appTransitionPending();
if (mNavigationBar != null) {
mNavigationBar.setKeyguardGoingAway(true);
mNavigationBar.appTransitionPending();
}
}
@@ -4391,8 +4113,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
- LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION);
recomputeDisableFlags(fadeoutDuration > 0 /* animate */);
if (mNavigationBarView != null) {
mNavigationBarView.getLightTransitionsController().appTransitionStarting(
if (mNavigationBar != null) {
mNavigationBar.doAppTransitionStarting(
startTime - LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION);
}
@@ -4408,6 +4130,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
public void finishKeyguardFadingAway() {
mKeyguardFadingAway = false;
mKeyguardGoingAway = false;
if (mNavigationBar != null) {
mNavigationBar.setKeyguardGoingAway(false);
}
}
public void stopWaitingForKeyguardExit() {
@@ -4596,10 +4321,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mStackScroller.setActivatedChild(view);
}
public ButtonDispatcher getHomeButton() {
return mNavigationBarView.getHomeButton();
}
/**
* @param state The {@link StatusBarState} to set.
*/
@@ -4696,8 +4417,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
return getMaxKeyguardNotifications(false /* recompute */);
}
// TODO: Figure out way to remove this.
public NavigationBarView getNavigationBarView() {
return mNavigationBarView;
return (NavigationBarView) mNavigationBar.getView();
}
// ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
@@ -4983,79 +4705,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mDozeScrimController.onScreenTurnedOn();
}
/**
* This handles long-press of both back and recents. They are
* handled together to capture them both being long-pressed
* at the same time to exit screen pinning (lock task).
*
* When accessibility mode is on, only a long-press from recents
* is required to exit.
*
* In all other circumstances we try to pass through long-press events
* for Back, so that apps can still use it. Which can be from two things.
* 1) Not currently in screen pinning (lock task).
* 2) Back is long-pressed without recents.
*/
private boolean handleLongPressBackRecents(View v) {
try {
boolean sendBackLongPress = false;
IActivityManager activityManager = ActivityManagerNative.getDefault();
boolean touchExplorationEnabled = mAccessibilityManager.isTouchExplorationEnabled();
boolean inLockTaskMode = activityManager.isInLockTaskMode();
if (inLockTaskMode && !touchExplorationEnabled) {
long time = System.currentTimeMillis();
// If we recently long-pressed the other button then they were
// long-pressed 'together'
if ((time - mLastLockToAppLongPress) < LOCK_TO_APP_GESTURE_TOLERENCE) {
activityManager.stopLockTaskMode();
// When exiting refresh disabled flags.
mNavigationBarView.setDisabledFlags(mDisabled1, true);
return true;
} else if ((v.getId() == R.id.back)
&& !mNavigationBarView.getRecentsButton().getCurrentView().isPressed()) {
// If we aren't pressing recents right now then they presses
// won't be together, so send the standard long-press action.
sendBackLongPress = true;
}
mLastLockToAppLongPress = time;
} else {
// If this is back still need to handle sending the long-press event.
if (v.getId() == R.id.back) {
sendBackLongPress = true;
} else if (touchExplorationEnabled && inLockTaskMode) {
// When in accessibility mode a long press that is recents (not back)
// should stop lock task.
activityManager.stopLockTaskMode();
// When exiting refresh disabled flags.
mNavigationBarView.setDisabledFlags(mDisabled1, true);
return true;
} else if (v.getId() == R.id.recent_apps) {
return handleLongPressRecents();
}
}
if (sendBackLongPress) {
KeyButtonView keyButtonView = (KeyButtonView) v;
keyButtonView.sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
keyButtonView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
return true;
}
} catch (RemoteException e) {
Log.d(TAG, "Unable to reach activity manager", e);
}
return false;
}
private boolean handleLongPressRecents() {
if (mRecents == null || !ActivityManager.supportsMultiWindow()
|| !getComponent(Divider.class).getView().getSnapAlgorithm()
.isSplitScreenFeasible()) {
return false;
}
return toggleSplitScreenMode(MetricsEvent.ACTION_WINDOW_DOCK_LONGPRESS,
MetricsEvent.ACTION_WINDOW_UNDOCK_LONGPRESS);
}
@Override
public void showScreenPinningRequest(int taskId) {
if (mKeyguardMonitor.isShowing()) {
@@ -5088,37 +4737,25 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
@Override
public void appTransitionPending() {
// Use own timings when Keyguard is going away, see keyguardGoingAway and
// setKeyguardFadingAway
if (!mKeyguardFadingAway) {
mIconController.getTransitionsController().appTransitionPending();
if (mNavigationBarView != null) {
mNavigationBarView.getLightTransitionsController().appTransitionPending();
}
}
}
@Override
public void appTransitionCancelled() {
mIconController.getTransitionsController().appTransitionCancelled();
if (mNavigationBarView != null) {
mNavigationBarView.getLightTransitionsController().appTransitionCancelled();
}
EventBus.getDefault().send(new AppTransitionFinishedEvent());
}
@Override
public void appTransitionStarting(long startTime, long duration) {
// Use own timings when Keyguard is going away, see keyguardGoingAway and
// setKeyguardFadingAway.
if (!mKeyguardGoingAway) {
mIconController.getTransitionsController().appTransitionStarting(startTime, duration);
if (mNavigationBarView != null) {
mNavigationBarView.getLightTransitionsController().appTransitionStarting(
startTime, duration);
}
}
if (mIconPolicy != null) {
mIconPolicy.appTransitionStarting(startTime, duration);
@@ -5188,6 +4825,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
Trace.endSection();
}
public boolean isKeyguardShowing() {
return mStatusBarKeyguardViewManager.isShowing();
}
private final class ShadeUpdates {
private final ArraySet<String> mVisibleNotifications = new ArraySet<String>();
private final ArraySet<String> mNewVisibleNotifications = new ArraySet<String>();

View File

@@ -106,11 +106,6 @@ public class TvStatusBar extends BaseStatusBar {
protected void updateNotifications() {
}
@Override
public boolean shouldDisableNavbarGestures() {
return true;
}
public View getStatusBarView() {
return null;
}
@@ -142,10 +137,6 @@ public class TvStatusBar extends BaseStatusBar {
protected void createAndAddWindows() {
}
@Override
protected void refreshLayout(int layoutDirection) {
}
@Override
public void onActivated(ActivatableNotificationView view) {
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2017 The Android Open Source 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 static org.mockito.Mockito.mock;
import com.android.systemui.FragmentTestCase;
import com.android.systemui.recents.Recents;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
import org.junit.Before;
public class NavigationBarFragmentTest extends FragmentTestCase {
public NavigationBarFragmentTest() {
super(NavigationBarFragment.class);
}
@Before
public void setup() {
mContext.putComponent(CommandQueue.class, mock(CommandQueue.class));
mContext.putComponent(PhoneStatusBar.class, mock(PhoneStatusBar.class));
mContext.putComponent(Recents.class, mock(Recents.class));
mContext.putComponent(Divider.class, mock(Divider.class));
}
}

View File

@@ -31,10 +31,11 @@ import android.os.UserHandle;
import android.provider.Settings;
import android.util.ArrayMap;
import com.android.systemui.SysUiServiceProvider;
import com.android.systemui.utils.leaks.Tracker;
import com.android.systemui.SysuiTestCase;
public class TestableContext extends ContextWrapper {
public class TestableContext extends ContextWrapper implements SysUiServiceProvider {
private final FakeContentResolver mFakeContentResolver;
private final FakeSettingsProvider mSettingsProvider;
@@ -42,6 +43,7 @@ public class TestableContext extends ContextWrapper {
private ArrayMap<String, Object> mMockSystemServices;
private ArrayMap<ComponentName, IBinder> mMockServices;
private ArrayMap<ServiceConnection, ComponentName> mActiveServices;
private ArrayMap<Class<?>, Object> mComponents;
private PackageManager mMockPackageManager;
private Tracker mReceiver;
@@ -201,4 +203,14 @@ public class TestableContext extends ContextWrapper {
if (mComponent != null) mComponent.getLeakInfo(callback).clearAllocations();
super.unregisterComponentCallbacks(callback);
}
@SuppressWarnings("unchecked")
public <T> T getComponent(Class<T> interfaceType) {
return (T) (mComponents != null ? mComponents.get(interfaceType) : null);
}
public <T, C extends T> void putComponent(Class<T> interfaceType, C component) {
mComponents = lazyInit(mComponents);
mComponents.put(interfaceType, component);
}
}