blob: 1a6d3d770f9f1345f651eb798753d512aa81593a [file] [log] [blame]
John Spurlock7edfbca2013-09-14 11:58:55 -04001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.systemui.statusbar.phone;
18
Winson Chung1aa24b92019-04-24 15:17:33 -070019import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
20
Vinit Nayak3f35db52019-08-08 17:31:48 -070021import static com.android.systemui.util.Utils.isGesturalModeOnDefaultDisplay;
Winson Chunge89f4b52019-03-29 15:01:49 -070022
John Spurlock7edfbca2013-09-14 11:58:55 -040023import android.content.Context;
Winson Chung775d2872019-03-27 14:14:01 -070024import android.graphics.Rect;
Jason Monk2044e6e2017-10-13 10:34:40 -040025import android.os.Handler;
26import android.os.RemoteException;
John Spurlock7edfbca2013-09-14 11:58:55 -040027import android.os.ServiceManager;
Jorim Jaggi40db0292016-06-27 17:58:03 -070028import android.util.SparseArray;
Jason Monk2044e6e2017-10-13 10:34:40 -040029import android.view.Display;
30import android.view.IWallpaperVisibilityListener;
31import android.view.IWindowManager;
John Spurlock7edfbca2013-09-14 11:58:55 -040032import android.view.View;
John Spurlock7edfbca2013-09-14 11:58:55 -040033
34import com.android.internal.statusbar.IStatusBarService;
Jason Monk2044e6e2017-10-13 10:34:40 -040035import com.android.systemui.Dependency;
John Spurlock7edfbca2013-09-14 11:58:55 -040036import com.android.systemui.R;
Dave Mankoffbcaca8a2019-10-31 18:04:08 -040037import com.android.systemui.statusbar.CommandQueue;
John Spurlock7edfbca2013-09-14 11:58:55 -040038
James O'Leary4335c702019-05-29 12:38:51 -040039import java.util.ArrayList;
40import java.util.List;
41
Winson Chunge89f4b52019-03-29 15:01:49 -070042public final class NavigationBarTransitions extends BarTransitions implements
43 LightBarTransitionsController.DarkIntensityApplier {
John Spurlock7edfbca2013-09-14 11:58:55 -040044
Vinit Nayak3f35db52019-08-08 17:31:48 -070045 public static final int MIN_COLOR_ADAPT_TRANSITION_TIME = 400;
46 public static final int DEFAULT_COLOR_ADAPT_TRANSITION_TIME = 1700;
47
James O'Leary4335c702019-05-29 12:38:51 -040048 /**
49 * Notified when the color of nav bar elements changes.
50 */
51 public interface DarkIntensityListener {
52 /**
53 * Called when the color of nav bar elements changes.
54 * @param darkIntensity 0 is the lightest color, 1 is the darkest.
55 */
56 void onDarkIntensity(float darkIntensity);
57 }
58
John Spurlock7edfbca2013-09-14 11:58:55 -040059 private final NavigationBarView mView;
John Spurlock7edfbca2013-09-14 11:58:55 -040060 private final IStatusBarService mBarService;
Jorim Jaggi40db0292016-06-27 17:58:03 -070061 private final LightBarTransitionsController mLightTransitionsController;
Matthew Ng3107d992017-11-21 15:56:19 -080062 private final boolean mAllowAutoDimWallpaperNotVisible;
Jason Monk2044e6e2017-10-13 10:34:40 -040063 private boolean mWallpaperVisible;
John Spurlock7edfbca2013-09-14 11:58:55 -040064
65 private boolean mLightsOut;
Jason Monkc2beef52017-08-29 18:58:00 -040066 private boolean mAutoDim;
Jason Monk0e3aab22018-01-18 19:05:52 -050067 private View mNavButtons;
Winson Chung1aa24b92019-04-24 15:17:33 -070068 private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
James O'Leary4335c702019-05-29 12:38:51 -040069 private List<DarkIntensityListener> mDarkIntensityListeners;
John Spurlock7edfbca2013-09-14 11:58:55 -040070
Winson Chungb03d44d2018-09-18 12:42:45 -070071 private final Handler mHandler = Handler.getMain();
72 private final IWallpaperVisibilityListener mWallpaperVisibilityListener =
73 new IWallpaperVisibilityListener.Stub() {
74 @Override
75 public void onWallpaperVisibilityChanged(boolean newVisibility,
76 int displayId) throws RemoteException {
77 mWallpaperVisible = newVisibility;
78 mHandler.post(() -> applyLightsOut(true, false));
79 }
80 };
81
Dave Mankoffbcaca8a2019-10-31 18:04:08 -040082 public NavigationBarTransitions(NavigationBarView view, CommandQueue commandQueue) {
John Spurlock7057d2c2013-10-02 10:00:37 -040083 super(view, R.drawable.nav_background);
John Spurlock7edfbca2013-09-14 11:58:55 -040084 mView = view;
John Spurlock7edfbca2013-09-14 11:58:55 -040085 mBarService = IStatusBarService.Stub.asInterface(
86 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
Dave Mankoffbcaca8a2019-10-31 18:04:08 -040087 mLightTransitionsController = new LightBarTransitionsController(
88 view.getContext(), this, commandQueue);
Matthew Ng3107d992017-11-21 15:56:19 -080089 mAllowAutoDimWallpaperNotVisible = view.getContext().getResources()
90 .getBoolean(R.bool.config_navigation_bar_enable_auto_dim_no_visible_wallpaper);
James O'Leary4335c702019-05-29 12:38:51 -040091 mDarkIntensityListeners = new ArrayList();
Jason Monk2044e6e2017-10-13 10:34:40 -040092
93 IWindowManager windowManagerService = Dependency.get(IWindowManager.class);
Jason Monk2044e6e2017-10-13 10:34:40 -040094 try {
95 mWallpaperVisible = windowManagerService.registerWallpaperVisibilityListener(
Winson Chungb03d44d2018-09-18 12:42:45 -070096 mWallpaperVisibilityListener, Display.DEFAULT_DISPLAY);
Jason Monk2044e6e2017-10-13 10:34:40 -040097 } catch (RemoteException e) {
98 }
Jason Monk0e3aab22018-01-18 19:05:52 -050099 mView.addOnLayoutChangeListener(
100 (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
101 View currentView = mView.getCurrentView();
102 if (currentView != null) {
103 mNavButtons = currentView.findViewById(R.id.nav_buttons);
104 applyLightsOut(false, true);
105 }
106 });
107 View currentView = mView.getCurrentView();
108 if (currentView != null) {
109 mNavButtons = currentView.findViewById(R.id.nav_buttons);
110 }
John Spurlock7edfbca2013-09-14 11:58:55 -0400111 }
112
Adrian Roos8a8ffd42015-05-26 18:30:37 -0700113 public void init() {
John Spurlocke631b412013-09-18 16:33:57 -0400114 applyModeBackground(-1, getMode(), false /*animate*/);
Jason Monkc2beef52017-08-29 18:58:00 -0400115 applyLightsOut(false /*animate*/, true /*force*/);
116 }
117
118 @Override
Winson Chungb03d44d2018-09-18 12:42:45 -0700119 public void destroy() {
120 IWindowManager windowManagerService = Dependency.get(IWindowManager.class);
121 try {
122 windowManagerService.unregisterWallpaperVisibilityListener(mWallpaperVisibilityListener,
123 Display.DEFAULT_DISPLAY);
124 } catch (RemoteException e) {
125 }
126 }
127
128 @Override
Jason Monkc2beef52017-08-29 18:58:00 -0400129 public void setAutoDim(boolean autoDim) {
Winson Chungebeed022019-05-14 16:22:57 -0700130 // Ensure we aren't in gestural nav if we are triggering auto dim
Vinit Nayak3f35db52019-08-08 17:31:48 -0700131 if (autoDim && isGesturalModeOnDefaultDisplay(mView.getContext(), mNavBarMode)) return;
Jason Monkc2beef52017-08-29 18:58:00 -0400132 if (mAutoDim == autoDim) return;
133 mAutoDim = autoDim;
134 applyLightsOut(true, false);
135 }
136
Winson Chung775d2872019-03-27 14:14:01 -0700137 void setBackgroundFrame(Rect frame) {
138 mBarBackground.setFrame(frame);
139 }
140
Jason Monkc2beef52017-08-29 18:58:00 -0400141 @Override
142 protected boolean isLightsOut(int mode) {
Matthew Ng3107d992017-11-21 15:56:19 -0800143 return super.isLightsOut(mode) || (mAllowAutoDimWallpaperNotVisible && mAutoDim
144 && !mWallpaperVisible && mode != MODE_WARNING);
John Spurlock7edfbca2013-09-14 11:58:55 -0400145 }
146
Jorim Jaggi40db0292016-06-27 17:58:03 -0700147 public LightBarTransitionsController getLightTransitionsController() {
148 return mLightTransitionsController;
149 }
150
John Spurlock7edfbca2013-09-14 11:58:55 -0400151 @Override
152 protected void onTransition(int oldMode, int newMode, boolean animate) {
153 super.onTransition(oldMode, newMode, animate);
Jason Monkc2beef52017-08-29 18:58:00 -0400154 applyLightsOut(animate, false /*force*/);
Winson Chung775d2872019-03-27 14:14:01 -0700155 mView.onBarTransition(newMode);
John Spurlock7edfbca2013-09-14 11:58:55 -0400156 }
157
Jason Monkc2beef52017-08-29 18:58:00 -0400158 private void applyLightsOut(boolean animate, boolean force) {
John Spurlock7edfbca2013-09-14 11:58:55 -0400159 // apply to lights out
Jason Monkc2beef52017-08-29 18:58:00 -0400160 applyLightsOut(isLightsOut(getMode()), animate, force);
John Spurlock7edfbca2013-09-14 11:58:55 -0400161 }
162
John Spurlock7edfbca2013-09-14 11:58:55 -0400163 private void applyLightsOut(boolean lightsOut, boolean animate, boolean force) {
164 if (!force && lightsOut == mLightsOut) return;
165
166 mLightsOut = lightsOut;
Jason Monk0e3aab22018-01-18 19:05:52 -0500167 if (mNavButtons == null) return;
John Spurlock7edfbca2013-09-14 11:58:55 -0400168
169 // ok, everyone, stop it right there
Jason Monk0e3aab22018-01-18 19:05:52 -0500170 mNavButtons.animate().cancel();
John Spurlock7edfbca2013-09-14 11:58:55 -0400171
Jason Monkcdec5ff2017-11-08 15:51:59 -0500172 // Bump percentage by 10% if dark.
173 float darkBump = mLightTransitionsController.getCurrentDarkIntensity() / 10;
174 final float navButtonsAlpha = lightsOut ? 0.6f + darkBump : 1f;
John Spurlock7edfbca2013-09-14 11:58:55 -0400175
176 if (!animate) {
Jason Monk0e3aab22018-01-18 19:05:52 -0500177 mNavButtons.setAlpha(navButtonsAlpha);
John Spurlock7edfbca2013-09-14 11:58:55 -0400178 } else {
179 final int duration = lightsOut ? LIGHTS_OUT_DURATION : LIGHTS_IN_DURATION;
Jason Monk0e3aab22018-01-18 19:05:52 -0500180 mNavButtons.animate()
John Spurlock7edfbca2013-09-14 11:58:55 -0400181 .alpha(navButtonsAlpha)
182 .setDuration(duration)
183 .start();
John Spurlock7edfbca2013-09-14 11:58:55 -0400184 }
185 }
186
Jorim Jaggi40db0292016-06-27 17:58:03 -0700187 public void reapplyDarkIntensity() {
188 applyDarkIntensity(mLightTransitionsController.getCurrentDarkIntensity());
189 }
190
James O'Leary4335c702019-05-29 12:38:51 -0400191 @Override
Jorim Jaggi40db0292016-06-27 17:58:03 -0700192 public void applyDarkIntensity(float darkIntensity) {
193 SparseArray<ButtonDispatcher> buttonDispatchers = mView.getButtonDispatchers();
194 for (int i = buttonDispatchers.size() - 1; i >= 0; i--) {
195 buttonDispatchers.valueAt(i).setDarkIntensity(darkIntensity);
196 }
Tracy Zhou24fd0282019-05-20 14:40:38 -0700197 mView.getRotationButtonController().setDarkIntensity(darkIntensity);
James O'Leary4335c702019-05-29 12:38:51 -0400198 for (DarkIntensityListener listener : mDarkIntensityListeners) {
199 listener.onDarkIntensity(darkIntensity);
200 }
Jason Monkcdec5ff2017-11-08 15:51:59 -0500201 if (mAutoDim) {
202 applyLightsOut(false, true);
203 }
Jorim Jaggi40db0292016-06-27 17:58:03 -0700204 }
Winson Chunge89f4b52019-03-29 15:01:49 -0700205
206 @Override
207 public int getTintAnimationDuration() {
Vinit Nayak3f35db52019-08-08 17:31:48 -0700208 if (isGesturalModeOnDefaultDisplay(mView.getContext(), mNavBarMode)) {
Winson Chunge89f4b52019-03-29 15:01:49 -0700209 return Math.max(DEFAULT_COLOR_ADAPT_TRANSITION_TIME, MIN_COLOR_ADAPT_TRANSITION_TIME);
210 }
211 return LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION;
212 }
Winson Chung1aa24b92019-04-24 15:17:33 -0700213
214 public void onNavigationModeChanged(int mode) {
215 mNavBarMode = mode;
216 }
James O'Leary4335c702019-05-29 12:38:51 -0400217
218 /**
219 * Register {@code listener} to be notified when the color of nav bar elements changes.
Miranda Kephart2c464b82019-06-05 16:09:15 -0400220 *
221 * Returns the current nav bar color.
James O'Leary4335c702019-05-29 12:38:51 -0400222 */
Miranda Kephart2c464b82019-06-05 16:09:15 -0400223 public float addDarkIntensityListener(DarkIntensityListener listener) {
James O'Leary4335c702019-05-29 12:38:51 -0400224 mDarkIntensityListeners.add(listener);
Miranda Kephart2c464b82019-06-05 16:09:15 -0400225 return mLightTransitionsController.getCurrentDarkIntensity();
James O'Leary4335c702019-05-29 12:38:51 -0400226 }
227
228 /**
229 * Remove {@code listener} from being notified when the color of nav bar elements changes.
230 */
231 public void removeDarkIntensityListener(DarkIntensityListener listener) {
232 mDarkIntensityListeners.remove(listener);
233 }
Jim Milleraf638c42013-09-20 01:33:28 +0000234}