diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java index 08cd955a54..2b59ede476 100644 --- a/src/com/android/launcher3/BaseActivity.java +++ b/src/com/android/launcher3/BaseActivity.java @@ -22,11 +22,13 @@ import android.content.ContextWrapper; import android.view.View.AccessibilityDelegate; import com.android.launcher3.logging.UserEventDispatcher; +import com.android.launcher3.util.SystemUiController; public abstract class BaseActivity extends Activity { protected DeviceProfile mDeviceProfile; protected UserEventDispatcher mUserEventDispatcher; + protected SystemUiController mSystemUiController; public DeviceProfile getDeviceProfile() { return mDeviceProfile; @@ -54,4 +56,11 @@ public abstract class BaseActivity extends Activity { } return ((BaseActivity) ((ContextWrapper) context).getBaseContext()); } + + public SystemUiController getSystemUiController() { + if (mSystemUiController == null) { + mSystemUiController = new SystemUiController(getWindow()); + } + return mSystemUiController; + } } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index bb32a4563b..66aab43283 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -126,6 +126,7 @@ import com.android.launcher3.util.MultiHashMap; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.PendingRequestArgs; +import com.android.launcher3.util.SystemUiController; import com.android.launcher3.util.TestingUtils; import com.android.launcher3.util.Themes; import com.android.launcher3.util.Thunk; @@ -470,9 +471,8 @@ public class Launcher extends BaseActivity // Listen for broadcasts screen off registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF)); - if (Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText)) { - activateLightSystemBars(true, true, true); - } + getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW, + Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText)); } @Override @@ -519,36 +519,6 @@ public class Launcher extends BaseActivity } } - /** - * Sets the status and/or nav bar to be light or not. Light status bar means dark icons. - * @param isLight make sure the system bar is light. - * @param statusBar if true, make the status bar theme match the isLight param. - * @param navBar if true, make the nav bar theme match the isLight param. - */ - public void activateLightSystemBars(boolean isLight, boolean statusBar, boolean navBar) { - int oldSystemUiFlags = getWindow().getDecorView().getSystemUiVisibility(); - int newSystemUiFlags = oldSystemUiFlags; - if (isLight) { - if (statusBar) { - newSystemUiFlags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; - } - if (navBar && Utilities.isAtLeastO()) { - newSystemUiFlags |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; - } - } else { - if (statusBar) { - newSystemUiFlags &= ~(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); - } - if (navBar && Utilities.isAtLeastO()) { - newSystemUiFlags &= ~(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); - } - } - - if (newSystemUiFlags != oldSystemUiFlags) { - getWindow().getDecorView().setSystemUiVisibility(newSystemUiFlags); - } - } - private LauncherCallbacks mLauncherCallbacks; public void onPostCreate(Bundle savedInstanceState) { diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index 2d8310bbe4..faadce4c92 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -28,6 +28,7 @@ import com.android.launcher3.graphics.GradientView; import com.android.launcher3.graphics.ScrimView; import com.android.launcher3.userevent.nano.LauncherLogProto.Action; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; +import com.android.launcher3.util.SystemUiController; import com.android.launcher3.util.Themes; import com.android.launcher3.util.TouchController; @@ -71,7 +72,6 @@ public class AllAppsTransitionController implements TouchController, VerticalPul private final VerticalPullDetector mDetector; private final ArgbEvaluator mEvaluator; private final boolean mIsDarkTheme; - private final boolean mIsWorkspaceDarkText; // Animation in this class is controlled by a single variable {@link mProgress}. // Visually, it represents top y coordinate of the all apps container if multiplied with @@ -114,7 +114,6 @@ public class AllAppsTransitionController implements TouchController, VerticalPul mEvaluator = new ArgbEvaluator(); mAllAppsBackgroundColor = Themes.getAttrColor(l, android.R.attr.colorPrimary); mIsDarkTheme = Themes.getAttrBoolean(mLauncher, R.attr.isMainColorDark); - mIsWorkspaceDarkText = Themes.getAttrBoolean(mLauncher, R.attr.isWorkspaceDarkText); } @Override @@ -278,15 +277,21 @@ public class AllAppsTransitionController implements TouchController, VerticalPul } private void updateLightStatusBar(float shift) { - // Do not modify status bar in dark theme or on landscape as all apps is not full bleed. - if (mIsDarkTheme || mIsWorkspaceDarkText || (!FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS - && mLauncher.getDeviceProfile().isVerticalBarLayout())) { + // Do not modify status bar on landscape as all apps is not full bleed. + if (!FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS + && mLauncher.getDeviceProfile().isVerticalBarLayout()) { return; } - // Use a light status bar (dark icons) if all apps is behind at least half of the status - // bar. If the status bar is already light due to wallpaper extraction, keep it that way. - boolean forceLight = shift <= mStatusBarHeight / 2; - mLauncher.activateLightSystemBars(forceLight, true /* statusBar */, true /* navBar */); + + // Use a light system UI (dark icons) if all apps is behind at least half of the status bar. + boolean forceChange = shift <= mStatusBarHeight / 2; + if (forceChange) { + mLauncher.getSystemUiController().updateUiState( + SystemUiController.UI_STATE_ALL_APPS, !mIsDarkTheme); + } else { + mLauncher.getSystemUiController().updateUiState( + SystemUiController.UI_STATE_ALL_APPS, 0); + } } private void updateAllAppsBg(float progress) { diff --git a/src/com/android/launcher3/dynamicui/WallpaperColorInfo.java b/src/com/android/launcher3/dynamicui/WallpaperColorInfo.java index 856a26ca86..512e89a419 100644 --- a/src/com/android/launcher3/dynamicui/WallpaperColorInfo.java +++ b/src/com/android/launcher3/dynamicui/WallpaperColorInfo.java @@ -61,7 +61,7 @@ public class WallpaperColorInfo implements WallpaperManagerCompat.OnColorsChange @Override public void onColorsChanged(WallpaperColorsCompat colors, int which) { - if (which == FLAG_SYSTEM) { + if ((which & FLAG_SYSTEM) != 0) { boolean wasDarkTheme = mIsDark; boolean didSupportDarkText = mSupportsDarkText; update(colors); diff --git a/src/com/android/launcher3/util/SystemUiController.java b/src/com/android/launcher3/util/SystemUiController.java new file mode 100644 index 0000000000..6b5b095c78 --- /dev/null +++ b/src/com/android/launcher3/util/SystemUiController.java @@ -0,0 +1,79 @@ +/* + * 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.launcher3.util; + +import android.view.View; +import android.view.Window; + +import com.android.launcher3.Utilities; + +/** + * Utility class to manage various window flags to control system UI. + */ +public class SystemUiController { + + // Various UI states in increasing order of priority + public static final int UI_STATE_BASE_WINDOW = 0; + public static final int UI_STATE_ALL_APPS = 1; + public static final int UI_STATE_WIDGET_BOTTOM_SHEET = 2; + + public static final int FLAG_LIGHT_NAV = 1 << 0; + public static final int FLAG_DARK_NAV = 1 << 1; + public static final int FLAG_LIGHT_STATUS = 1 << 2; + public static final int FLAG_DARK_STATUS = 1 << 3; + + private final Window mWindow; + private final int[] mStates = new int[3]; + + public SystemUiController(Window window) { + mWindow = window; + } + + public void updateUiState(int uiState, boolean isLight) { + updateUiState(uiState, isLight + ? (FLAG_LIGHT_NAV | FLAG_LIGHT_STATUS) : (FLAG_DARK_NAV | FLAG_DARK_STATUS)); + } + + public void updateUiState(int uiState, int flags) { + if (mStates[uiState] == flags) { + return; + } + mStates[uiState] = flags; + + int oldFlags = mWindow.getDecorView().getSystemUiVisibility(); + // Apply the state flags in priority order + int newFlags = oldFlags; + for (int stateFlag : mStates) { + if (Utilities.isAtLeastO()) { + if ((stateFlag & FLAG_LIGHT_NAV) != 0) { + newFlags |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; + } else if ((stateFlag & FLAG_DARK_NAV) != 0) { + newFlags &= ~(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); + } + } + + if ((stateFlag & FLAG_LIGHT_STATUS) != 0) { + newFlags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + } else if ((stateFlag & FLAG_DARK_STATUS) != 0) { + newFlags &= ~(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + } + } + if (newFlags != oldFlags) { + mWindow.getDecorView().setSystemUiVisibility(newFlags); + } + } +} diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java index 5fe00c2d59..cea58b9945 100644 --- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java +++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java @@ -48,6 +48,7 @@ import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.model.WidgetItem; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.util.PackageUserKey; +import com.android.launcher3.util.SystemUiController; import com.android.launcher3.util.TouchController; import java.util.List; @@ -69,7 +70,6 @@ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettab private Interpolator mFastOutSlowInInterpolator; private VerticalPullDetector.ScrollInterpolator mScrollInterpolator; private Rect mInsets; - private boolean mWasNavBarLight; private VerticalPullDetector mVerticalPullDetector; public WidgetsBottomSheet(Context context, AttributeSet attrs) { @@ -103,8 +103,6 @@ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettab onWidgetsBound(); - mWasNavBarLight = (mLauncher.getWindow().getDecorView().getSystemUiVisibility() - & View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR) != 0; mLauncher.getDragLayer().addView(this); measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); setTranslationY(mTranslationYClosed); @@ -180,7 +178,8 @@ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettab return; } mIsOpen = true; - setLightNavBar(true); + mLauncher.getSystemUiController().updateUiState( + SystemUiController.UI_STATE_WIDGET_BOTTOM_SHEET, SystemUiController.FLAG_LIGHT_NAV); if (animate) { mOpenCloseAnimator.setValues(new PropertyListBuilder() .translationY(mTranslationYOpen).build()); @@ -211,7 +210,8 @@ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettab mIsOpen = false; mVerticalPullDetector.finishedScrolling(); ((ViewGroup) getParent()).removeView(WidgetsBottomSheet.this); - setLightNavBar(mWasNavBarLight); + mLauncher.getSystemUiController().updateUiState( + SystemUiController.UI_STATE_WIDGET_BOTTOM_SHEET, 0); } }); mOpenCloseAnimator.setInterpolator(mVerticalPullDetector.isIdleState() @@ -219,15 +219,12 @@ public class WidgetsBottomSheet extends AbstractFloatingView implements Insettab mOpenCloseAnimator.start(); } else { setTranslationY(mTranslationYClosed); - setLightNavBar(mWasNavBarLight); + mLauncher.getSystemUiController().updateUiState( + SystemUiController.UI_STATE_WIDGET_BOTTOM_SHEET, 0); mIsOpen = false; } } - private void setLightNavBar(boolean lightNavBar) { - mLauncher.activateLightSystemBars(lightNavBar, false /* statusBar */, true /* navBar */); - } - @Override protected boolean isOfType(@FloatingViewType int type) { return (type & TYPE_WIDGETS_BOTTOM_SHEET) != 0;