1 /* 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 15 package com.android.systemui.statusbar.phone; 16 17 import static com.android.systemui.statusbar.phone.StatusBar.reinflateSignalCluster; 18 19 import android.annotation.Nullable; 20 import android.app.Fragment; 21 import android.app.StatusBarManager; 22 import android.os.Bundle; 23 import android.view.LayoutInflater; 24 import android.view.View; 25 import android.view.ViewGroup; 26 import android.view.ViewStub; 27 import android.widget.LinearLayout; 28 29 import com.android.systemui.Dependency; 30 import com.android.systemui.Interpolators; 31 import com.android.systemui.R; 32 import com.android.systemui.SysUiServiceProvider; 33 import com.android.systemui.statusbar.CommandQueue; 34 import com.android.systemui.statusbar.SignalClusterView; 35 import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager; 36 import com.android.systemui.statusbar.policy.DarkIconDispatcher; 37 import com.android.systemui.statusbar.policy.EncryptionHelper; 38 import com.android.systemui.statusbar.policy.KeyguardMonitor; 39 import com.android.systemui.statusbar.policy.NetworkController; 40 import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; 41 42 /** 43 * Contains the collapsed status bar and handles hiding/showing based on disable flags 44 * and keyguard state. Also manages lifecycle to make sure the views it contains are being 45 * updated by the StatusBarIconController and DarkIconManager while it is attached. 46 */ 47 public class CollapsedStatusBarFragment extends Fragment implements CommandQueue.Callbacks { 48 49 public static final String TAG = "CollapsedStatusBarFragment"; 50 private static final String EXTRA_PANEL_STATE = "panel_state"; 51 private PhoneStatusBarView mStatusBar; 52 private KeyguardMonitor mKeyguardMonitor; 53 private NetworkController mNetworkController; 54 private LinearLayout mSystemIconArea; 55 private View mNotificationIconAreaInner; 56 private int mDisabled1; 57 private StatusBar mStatusBarComponent; 58 private DarkIconManager mDarkIconManager; 59 private SignalClusterView mSignalClusterView; 60 61 private SignalCallback mSignalCallback = new SignalCallback() { 62 @Override 63 public void setIsAirplaneMode(NetworkController.IconState icon) { 64 mStatusBarComponent.recomputeDisableFlags(true /* animate */); 65 } 66 }; 67 68 @Override onCreate(@ullable Bundle savedInstanceState)69 public void onCreate(@Nullable Bundle savedInstanceState) { 70 super.onCreate(savedInstanceState); 71 mKeyguardMonitor = Dependency.get(KeyguardMonitor.class); 72 mNetworkController = Dependency.get(NetworkController.class); 73 mStatusBarComponent = SysUiServiceProvider.getComponent(getContext(), StatusBar.class); 74 } 75 76 @Override onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState)77 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 78 Bundle savedInstanceState) { 79 return inflater.inflate(R.layout.status_bar, container, false); 80 } 81 82 @Override onViewCreated(View view, @Nullable Bundle savedInstanceState)83 public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 84 super.onViewCreated(view, savedInstanceState); 85 mStatusBar = (PhoneStatusBarView) view; 86 if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_PANEL_STATE)) { 87 mStatusBar.go(savedInstanceState.getInt(EXTRA_PANEL_STATE)); 88 } 89 mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons)); 90 Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager); 91 mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area); 92 mSignalClusterView = mStatusBar.findViewById(R.id.signal_cluster); 93 Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mSignalClusterView); 94 // Default to showing until we know otherwise. 95 showSystemIconArea(false); 96 initEmergencyCryptkeeperText(); 97 } 98 99 @Override onSaveInstanceState(Bundle outState)100 public void onSaveInstanceState(Bundle outState) { 101 super.onSaveInstanceState(outState); 102 outState.putInt(EXTRA_PANEL_STATE, mStatusBar.getState()); 103 } 104 105 @Override onResume()106 public void onResume() { 107 super.onResume(); 108 SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallbacks(this); 109 } 110 111 @Override onPause()112 public void onPause() { 113 super.onPause(); 114 SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).removeCallbacks(this); 115 } 116 117 @Override onDestroyView()118 public void onDestroyView() { 119 super.onDestroyView(); 120 Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(mSignalClusterView); 121 Dependency.get(StatusBarIconController.class).removeIconGroup(mDarkIconManager); 122 if (mNetworkController.hasEmergencyCryptKeeperText()) { 123 mNetworkController.removeCallback(mSignalCallback); 124 } 125 } 126 initNotificationIconArea(NotificationIconAreaController notificationIconAreaController)127 public void initNotificationIconArea(NotificationIconAreaController 128 notificationIconAreaController) { 129 ViewGroup notificationIconArea = mStatusBar.findViewById(R.id.notification_icon_area); 130 mNotificationIconAreaInner = 131 notificationIconAreaController.getNotificationInnerAreaView(); 132 if (mNotificationIconAreaInner.getParent() != null) { 133 ((ViewGroup) mNotificationIconAreaInner.getParent()) 134 .removeView(mNotificationIconAreaInner); 135 } 136 notificationIconArea.addView(mNotificationIconAreaInner); 137 // Default to showing until we know otherwise. 138 showNotificationIconArea(false); 139 } 140 141 @Override disable(int state1, int state2, boolean animate)142 public void disable(int state1, int state2, boolean animate) { 143 state1 = adjustDisableFlags(state1); 144 final int old1 = mDisabled1; 145 final int diff1 = state1 ^ old1; 146 mDisabled1 = state1; 147 if ((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) { 148 if ((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) { 149 hideSystemIconArea(animate); 150 } else { 151 showSystemIconArea(animate); 152 } 153 } 154 if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { 155 if ((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { 156 hideNotificationIconArea(animate); 157 } else { 158 showNotificationIconArea(animate); 159 } 160 } 161 } 162 adjustDisableFlags(int state)163 protected int adjustDisableFlags(int state) { 164 if (!mStatusBarComponent.isLaunchTransitionFadingAway() 165 && !mKeyguardMonitor.isKeyguardFadingAway() 166 && shouldHideNotificationIcons()) { 167 state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS; 168 state |= StatusBarManager.DISABLE_SYSTEM_INFO; 169 } 170 if (mNetworkController != null && EncryptionHelper.IS_DATA_ENCRYPTED) { 171 if (mNetworkController.hasEmergencyCryptKeeperText()) { 172 state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS; 173 } 174 if (!mNetworkController.isRadioOn()) { 175 state |= StatusBarManager.DISABLE_SYSTEM_INFO; 176 } 177 } 178 return state; 179 } 180 shouldHideNotificationIcons()181 private boolean shouldHideNotificationIcons() { 182 return !mStatusBar.isClosed() && mStatusBarComponent.hideStatusBarIconsWhenExpanded(); 183 } 184 hideSystemIconArea(boolean animate)185 public void hideSystemIconArea(boolean animate) { 186 animateHide(mSystemIconArea, animate); 187 } 188 showSystemIconArea(boolean animate)189 public void showSystemIconArea(boolean animate) { 190 animateShow(mSystemIconArea, animate); 191 } 192 hideNotificationIconArea(boolean animate)193 public void hideNotificationIconArea(boolean animate) { 194 animateHide(mNotificationIconAreaInner, animate); 195 } 196 showNotificationIconArea(boolean animate)197 public void showNotificationIconArea(boolean animate) { 198 animateShow(mNotificationIconAreaInner, animate); 199 } 200 201 /** 202 * Hides a view. 203 */ animateHide(final View v, boolean animate)204 private void animateHide(final View v, boolean animate) { 205 v.animate().cancel(); 206 if (!animate) { 207 v.setAlpha(0f); 208 v.setVisibility(View.INVISIBLE); 209 return; 210 } 211 v.animate() 212 .alpha(0f) 213 .setDuration(160) 214 .setStartDelay(0) 215 .setInterpolator(Interpolators.ALPHA_OUT) 216 .withEndAction(() -> v.setVisibility(View.INVISIBLE)); 217 } 218 219 /** 220 * Shows a view, and synchronizes the animation with Keyguard exit animations, if applicable. 221 */ animateShow(View v, boolean animate)222 private void animateShow(View v, boolean animate) { 223 v.animate().cancel(); 224 v.setVisibility(View.VISIBLE); 225 if (!animate) { 226 v.setAlpha(1f); 227 return; 228 } 229 v.animate() 230 .alpha(1f) 231 .setDuration(320) 232 .setInterpolator(Interpolators.ALPHA_IN) 233 .setStartDelay(50) 234 235 // We need to clean up any pending end action from animateHide if we call 236 // both hide and show in the same frame before the animation actually gets started. 237 // cancel() doesn't really remove the end action. 238 .withEndAction(null); 239 240 // Synchronize the motion with the Keyguard fading if necessary. 241 if (mKeyguardMonitor.isKeyguardFadingAway()) { 242 v.animate() 243 .setDuration(mKeyguardMonitor.getKeyguardFadingAwayDuration()) 244 .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN) 245 .setStartDelay(mKeyguardMonitor.getKeyguardFadingAwayDelay()) 246 .start(); 247 } 248 } 249 initEmergencyCryptkeeperText()250 private void initEmergencyCryptkeeperText() { 251 View emergencyViewStub = mStatusBar.findViewById(R.id.emergency_cryptkeeper_text); 252 if (mNetworkController.hasEmergencyCryptKeeperText()) { 253 if (emergencyViewStub != null) { 254 ((ViewStub) emergencyViewStub).inflate(); 255 } 256 mNetworkController.addCallback(mSignalCallback); 257 } else if (emergencyViewStub != null) { 258 ViewGroup parent = (ViewGroup) emergencyViewStub.getParent(); 259 parent.removeView(emergencyViewStub); 260 } 261 } 262 } 263