blob: 61cb61ce1df43ace0b4861ed802d9be16bd4eea7 [file] [log] [blame]
Jason Monkaa573e92017-01-27 17:00:29 -05001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11 * KIND, either express or implied. See the License for the specific language governing
12 * permissions and limitations under the License.
13 */
14
15package com.android.systemui.statusbar.phone;
16
Jason Monkd3ee70c2017-08-30 17:05:24 -040017import static android.app.StatusBarManager.DISABLE_NOTIFICATION_ICONS;
18import static android.app.StatusBarManager.DISABLE_SYSTEM_INFO;
19
Jason Monkaa573e92017-01-27 17:00:29 -050020import static com.android.systemui.statusbar.phone.StatusBar.reinflateSignalCluster;
21
22import android.annotation.Nullable;
23import android.app.Fragment;
24import android.app.StatusBarManager;
25import android.os.Bundle;
26import android.view.LayoutInflater;
27import android.view.View;
28import android.view.ViewGroup;
Yoshinori Hirano2696aa32017-04-10 20:33:49 +090029import android.view.ViewStub;
Jason Monkaa573e92017-01-27 17:00:29 -050030import android.widget.LinearLayout;
31
32import com.android.systemui.Dependency;
33import com.android.systemui.Interpolators;
34import com.android.systemui.R;
35import com.android.systemui.SysUiServiceProvider;
36import com.android.systemui.statusbar.CommandQueue;
37import com.android.systemui.statusbar.SignalClusterView;
38import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager;
39import com.android.systemui.statusbar.policy.DarkIconDispatcher;
40import com.android.systemui.statusbar.policy.EncryptionHelper;
41import com.android.systemui.statusbar.policy.KeyguardMonitor;
42import com.android.systemui.statusbar.policy.NetworkController;
Yoshinori Hirano2696aa32017-04-10 20:33:49 +090043import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
Jason Monkaa573e92017-01-27 17:00:29 -050044
45/**
46 * Contains the collapsed status bar and handles hiding/showing based on disable flags
47 * and keyguard state. Also manages lifecycle to make sure the views it contains are being
48 * updated by the StatusBarIconController and DarkIconManager while it is attached.
49 */
50public class CollapsedStatusBarFragment extends Fragment implements CommandQueue.Callbacks {
51
52 public static final String TAG = "CollapsedStatusBarFragment";
Jason Monk0a7d9f22017-03-15 11:03:06 -040053 private static final String EXTRA_PANEL_STATE = "panel_state";
Jason Monkaa573e92017-01-27 17:00:29 -050054 private PhoneStatusBarView mStatusBar;
55 private KeyguardMonitor mKeyguardMonitor;
56 private NetworkController mNetworkController;
57 private LinearLayout mSystemIconArea;
Evan Laird2cf56822017-12-18 11:22:39 -050058 private View mClockView;
Jason Monkaa573e92017-01-27 17:00:29 -050059 private View mNotificationIconAreaInner;
60 private int mDisabled1;
61 private StatusBar mStatusBarComponent;
62 private DarkIconManager mDarkIconManager;
63 private SignalClusterView mSignalClusterView;
Kensuke Matsui21d1bf12017-03-14 13:27:20 +090064 private View mOperatorNameFrame;
Jason Monkaa573e92017-01-27 17:00:29 -050065
Yoshinori Hirano2696aa32017-04-10 20:33:49 +090066 private SignalCallback mSignalCallback = new SignalCallback() {
67 @Override
68 public void setIsAirplaneMode(NetworkController.IconState icon) {
69 mStatusBarComponent.recomputeDisableFlags(true /* animate */);
70 }
71 };
72
Jason Monkaa573e92017-01-27 17:00:29 -050073 @Override
74 public void onCreate(@Nullable Bundle savedInstanceState) {
75 super.onCreate(savedInstanceState);
76 mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
77 mNetworkController = Dependency.get(NetworkController.class);
78 mStatusBarComponent = SysUiServiceProvider.getComponent(getContext(), StatusBar.class);
79 }
80
81 @Override
82 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
83 Bundle savedInstanceState) {
84 return inflater.inflate(R.layout.status_bar, container, false);
85 }
86
87 @Override
88 public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
89 super.onViewCreated(view, savedInstanceState);
90 mStatusBar = (PhoneStatusBarView) view;
Jason Monk0a7d9f22017-03-15 11:03:06 -040091 if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_PANEL_STATE)) {
92 mStatusBar.go(savedInstanceState.getInt(EXTRA_PANEL_STATE));
93 }
94 mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons));
Jason Monkaa573e92017-01-27 17:00:29 -050095 Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager);
Jason Monk0a7d9f22017-03-15 11:03:06 -040096 mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area);
Evan Laird2cf56822017-12-18 11:22:39 -050097 mClockView = mStatusBar.findViewById(R.id.clock);
Jason Monkd60a72f2017-04-21 10:10:35 -040098 mSignalClusterView = mStatusBar.findViewById(R.id.signal_cluster);
Jason Monkaa573e92017-01-27 17:00:29 -050099 Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mSignalClusterView);
Jason Monk60033fc2017-03-24 11:26:35 -0400100 // Default to showing until we know otherwise.
101 showSystemIconArea(false);
Yoshinori Hirano2696aa32017-04-10 20:33:49 +0900102 initEmergencyCryptkeeperText();
Kensuke Matsui21d1bf12017-03-14 13:27:20 +0900103 initOperatorName();
Jason Monkaa573e92017-01-27 17:00:29 -0500104 }
105
106 @Override
Jason Monk0a7d9f22017-03-15 11:03:06 -0400107 public void onSaveInstanceState(Bundle outState) {
108 super.onSaveInstanceState(outState);
109 outState.putInt(EXTRA_PANEL_STATE, mStatusBar.getState());
110 }
111
112 @Override
Jason Monkaa573e92017-01-27 17:00:29 -0500113 public void onResume() {
114 super.onResume();
115 SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallbacks(this);
116 }
117
118 @Override
119 public void onPause() {
120 super.onPause();
121 SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).removeCallbacks(this);
122 }
123
124 @Override
125 public void onDestroyView() {
126 super.onDestroyView();
127 Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(mSignalClusterView);
128 Dependency.get(StatusBarIconController.class).removeIconGroup(mDarkIconManager);
Yoshinori Hirano2696aa32017-04-10 20:33:49 +0900129 if (mNetworkController.hasEmergencyCryptKeeperText()) {
130 mNetworkController.removeCallback(mSignalCallback);
131 }
Jason Monkaa573e92017-01-27 17:00:29 -0500132 }
133
134 public void initNotificationIconArea(NotificationIconAreaController
135 notificationIconAreaController) {
Jason Monk0a7d9f22017-03-15 11:03:06 -0400136 ViewGroup notificationIconArea = mStatusBar.findViewById(R.id.notification_icon_area);
Jason Monkaa573e92017-01-27 17:00:29 -0500137 mNotificationIconAreaInner =
138 notificationIconAreaController.getNotificationInnerAreaView();
139 if (mNotificationIconAreaInner.getParent() != null) {
140 ((ViewGroup) mNotificationIconAreaInner.getParent())
141 .removeView(mNotificationIconAreaInner);
142 }
143 notificationIconArea.addView(mNotificationIconAreaInner);
Jason Monk60033fc2017-03-24 11:26:35 -0400144 // Default to showing until we know otherwise.
145 showNotificationIconArea(false);
Jason Monkaa573e92017-01-27 17:00:29 -0500146 }
147
148 @Override
149 public void disable(int state1, int state2, boolean animate) {
150 state1 = adjustDisableFlags(state1);
151 final int old1 = mDisabled1;
152 final int diff1 = state1 ^ old1;
153 mDisabled1 = state1;
Jason Monkd3ee70c2017-08-30 17:05:24 -0400154 if ((diff1 & DISABLE_SYSTEM_INFO) != 0) {
155 if ((state1 & DISABLE_SYSTEM_INFO) != 0) {
Jason Monkaa573e92017-01-27 17:00:29 -0500156 hideSystemIconArea(animate);
Kensuke Matsui21d1bf12017-03-14 13:27:20 +0900157 hideOperatorName(animate);
Jason Monkaa573e92017-01-27 17:00:29 -0500158 } else {
159 showSystemIconArea(animate);
Kensuke Matsui21d1bf12017-03-14 13:27:20 +0900160 showOperatorName(animate);
Jason Monkaa573e92017-01-27 17:00:29 -0500161 }
162 }
Jason Monkd3ee70c2017-08-30 17:05:24 -0400163 if ((diff1 & DISABLE_NOTIFICATION_ICONS) != 0) {
164 if ((state1 & DISABLE_NOTIFICATION_ICONS) != 0) {
Jason Monkaa573e92017-01-27 17:00:29 -0500165 hideNotificationIconArea(animate);
166 } else {
167 showNotificationIconArea(animate);
168 }
169 }
170 }
171
172 protected int adjustDisableFlags(int state) {
173 if (!mStatusBarComponent.isLaunchTransitionFadingAway()
174 && !mKeyguardMonitor.isKeyguardFadingAway()
175 && shouldHideNotificationIcons()) {
Jason Monkd3ee70c2017-08-30 17:05:24 -0400176 state |= DISABLE_NOTIFICATION_ICONS;
177 state |= DISABLE_SYSTEM_INFO;
Jason Monkaa573e92017-01-27 17:00:29 -0500178 }
179 if (mNetworkController != null && EncryptionHelper.IS_DATA_ENCRYPTED) {
180 if (mNetworkController.hasEmergencyCryptKeeperText()) {
Jason Monkd3ee70c2017-08-30 17:05:24 -0400181 state |= DISABLE_NOTIFICATION_ICONS;
Jason Monkaa573e92017-01-27 17:00:29 -0500182 }
183 if (!mNetworkController.isRadioOn()) {
Jason Monkd3ee70c2017-08-30 17:05:24 -0400184 state |= DISABLE_SYSTEM_INFO;
Jason Monkaa573e92017-01-27 17:00:29 -0500185 }
186 }
187 return state;
188 }
189
190 private boolean shouldHideNotificationIcons() {
Selim Cinek3a49ba22017-08-10 11:17:39 -0700191 if (!mStatusBar.isClosed() && mStatusBarComponent.hideStatusBarIconsWhenExpanded()) {
192 return true;
193 }
194 if (mStatusBarComponent.hideStatusBarIconsForBouncer()) {
195 return true;
196 }
197 return false;
Jason Monkaa573e92017-01-27 17:00:29 -0500198 }
199
200 public void hideSystemIconArea(boolean animate) {
201 animateHide(mSystemIconArea, animate);
Evan Laird2cf56822017-12-18 11:22:39 -0500202 animateHide(mClockView, animate);
Jason Monkaa573e92017-01-27 17:00:29 -0500203 }
204
205 public void showSystemIconArea(boolean animate) {
206 animateShow(mSystemIconArea, animate);
Evan Laird2cf56822017-12-18 11:22:39 -0500207 animateShow(mClockView, animate);
Jason Monkaa573e92017-01-27 17:00:29 -0500208 }
209
210 public void hideNotificationIconArea(boolean animate) {
211 animateHide(mNotificationIconAreaInner, animate);
212 }
213
214 public void showNotificationIconArea(boolean animate) {
215 animateShow(mNotificationIconAreaInner, animate);
216 }
217
Kensuke Matsui21d1bf12017-03-14 13:27:20 +0900218 public void hideOperatorName(boolean animate) {
219 if (mOperatorNameFrame != null) {
220 animateHide(mOperatorNameFrame, animate);
221 }
222 }
223
224 public void showOperatorName(boolean animate) {
225 if (mOperatorNameFrame != null) {
226 animateShow(mOperatorNameFrame, animate);
227 }
228 }
229
Jason Monkaa573e92017-01-27 17:00:29 -0500230 /**
231 * Hides a view.
232 */
233 private void animateHide(final View v, boolean animate) {
234 v.animate().cancel();
235 if (!animate) {
236 v.setAlpha(0f);
237 v.setVisibility(View.INVISIBLE);
238 return;
239 }
240 v.animate()
241 .alpha(0f)
242 .setDuration(160)
243 .setStartDelay(0)
244 .setInterpolator(Interpolators.ALPHA_OUT)
245 .withEndAction(() -> v.setVisibility(View.INVISIBLE));
246 }
247
248 /**
249 * Shows a view, and synchronizes the animation with Keyguard exit animations, if applicable.
250 */
251 private void animateShow(View v, boolean animate) {
252 v.animate().cancel();
253 v.setVisibility(View.VISIBLE);
254 if (!animate) {
255 v.setAlpha(1f);
256 return;
257 }
258 v.animate()
259 .alpha(1f)
260 .setDuration(320)
261 .setInterpolator(Interpolators.ALPHA_IN)
262 .setStartDelay(50)
263
264 // We need to clean up any pending end action from animateHide if we call
265 // both hide and show in the same frame before the animation actually gets started.
266 // cancel() doesn't really remove the end action.
267 .withEndAction(null);
268
269 // Synchronize the motion with the Keyguard fading if necessary.
270 if (mKeyguardMonitor.isKeyguardFadingAway()) {
271 v.animate()
272 .setDuration(mKeyguardMonitor.getKeyguardFadingAwayDuration())
273 .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
274 .setStartDelay(mKeyguardMonitor.getKeyguardFadingAwayDelay())
275 .start();
276 }
277 }
Yoshinori Hirano2696aa32017-04-10 20:33:49 +0900278
279 private void initEmergencyCryptkeeperText() {
280 View emergencyViewStub = mStatusBar.findViewById(R.id.emergency_cryptkeeper_text);
281 if (mNetworkController.hasEmergencyCryptKeeperText()) {
282 if (emergencyViewStub != null) {
283 ((ViewStub) emergencyViewStub).inflate();
284 }
285 mNetworkController.addCallback(mSignalCallback);
286 } else if (emergencyViewStub != null) {
287 ViewGroup parent = (ViewGroup) emergencyViewStub.getParent();
288 parent.removeView(emergencyViewStub);
289 }
290 }
Kensuke Matsui21d1bf12017-03-14 13:27:20 +0900291
292 private void initOperatorName() {
293 if (getResources().getBoolean(R.bool.config_showOperatorNameInStatusBar)) {
294 ViewStub stub = mStatusBar.findViewById(R.id.operator_name);
295 mOperatorNameFrame = stub.inflate();
296 }
297 }
Jason Monkaa573e92017-01-27 17:00:29 -0500298}