创作不易,请尊重原创,转载须注明出处:https://blog.youkuaiyun.com/An_Times/article/details/120027015
一、前言
本文将分析PhoneWindowMananger按键响应power键长按事件到SystemUI弹出关机界面dialog的流程。Android 原生的关机界面有两种,一种是LegacyGlobalActions中的dialog (第二张图),另一种是SystemUI中的GlobalActionsDialog(第一张图),常规情况下默认是弹出SystemUI中的关机界面,当SystemUI没有正常工作时才会弹出LegacyGlobalActions中的关机界面。
环境:本文基于MTK 6765 Android 11.0
二、PhoneWindowManager处理长按power键事件
- 代码路径:frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java
- 按键事件从input子系统传递上来首选是经过PhoneWindowManager处理的,像一些系统比如关机键、音量键等等是在interceptKeyBeforeQueueing中处理并不会继续往下分发。
- power键按下的时候调用的是interceptPowerKeyDown方法。
@Override
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
...此处省略部分代码
case KeyEvent.KEYCODE_POWER: {
EventLogTags.writeInterceptPower(
KeyEvent.actionToString(event.getAction()),
mPowerKeyHandled ? 1 : 0, mPowerKeyPressCounter);
// Any activity on the power button stops the accessibility shortcut
cancelPendingAccessibilityShortcutAction();
result &= ~ACTION_PASS_TO_USER;
isWakeKey = false; // wake-up will be handled separately
if (down) {
interceptPowerKeyDown(event, interactive);
} else {
interceptPowerKeyUp(event, interactive, canceled);
}
break;
}
...此处省略部分代码
}
- 长按power键最终调用的是powerLongPress() 方法。
private void powerLongPress() {
final int behavior = getResolvedLongPressOnPowerBehavior();
switch (behavior) {
case LONG_PRESS_POWER_NOTHING:
break;
case LONG_PRESS_POWER_GLOBAL_ACTIONS:
mPowerKeyHandled = true;
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,
"Power - Long Press - Global Actions");
showGlobalActionsInternal();
break;
...此处省略部分代码
}
}
- 长按power键弹框是调用showGlobalActionsInternal()方法。这个方法实际上调用的是GlobalActions 的showDialog 方法。
void showGlobalActionsInternal() {
if (mGlobalActions == null) {
mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs);
}
final boolean keyguardShowing = isKeyguardShowingAndNotOccluded();
mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());
// since it took two seconds of long press to bring this up,
// poke the wake lock so they have some time to see the dialog.
mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
}
三、弹出关机界面Dialog
-
代码路径:frameworks\base\services\core\java\com\android\server\policy\GlobalActions.java
} else {
-
showDialog方法中根据mGlobalActionsAvailable 变量来判断弹出哪一种关机界面dialog,即开头所说的,SystemUI弹的关机界面是mGlobalActionsProvider.showGlobalActions(),也就是下图这种,framework中原因的关机界面是mLegacyGlobalActions.showDialog。这里通过log打印mGlobalActionsAvailable的值为true,即说明正常用的是SystemUI中的关机界面。

public void showDialog(boolean keyguardShowing, boolean deviceProvisioned) {
if (DEBUG) Slog.d(TAG, "showDialog " + keyguardShowing + " " + deviceProvisioned);
if (mGlobalActionsProvider != null && mGlobalActionsProvider.isGlobalActionsDisabled()) {
return;
}
mKeyguardShowing = keyguardShowing;
mDeviceProvisioned = deviceProvisioned;
mShowing = true;
if (mGlobalActionsAvailable) {
mHandler.postDelayed(mShowTimeout, 5000);
mGlobalActionsProvider.showGlobalActions();
} else {
// SysUI isn't alive, show legacy menu.
ensureLegacyCreated();
mLegacyGlobalActions.showDialog(mKeyguardShowing, mDeviceProvisioned);
}
}
三、GlobalActionsProvider 与SystemUI关联起来的过程
-
代码路径:frameworks\base\services\core\java\com\android\server\policy\GlobalActionsProvider.java
-
GlobalActionsProvider是一个接口类,包含一个子接口类GlobalActionsListener,弹出关机界面主要是showGlobalActions 方法。其他地方是哪里调用了showGlobalActions呢,这里全局搜索一下GlobalActionsProvider即可。
package com.android.server.policy;
/** Used with LocalServices to add custom handling to global actions. */
public interface GlobalActionsProvider {
/** @return {@code true} if the dialog is enabled. */
boolean isGlobalActionsDisabled();
/** Set the listener that will handle various global actions evetns. */
void setGlobalActionsListener(GlobalActionsListener listener);
/** Show the global actions UI to the user. */
void showGlobalActions();
/** Listener to pass global actions events back to system. */
public interface GlobalActionsListener {
/**
* Called when sysui starts and connects its status bar, or when the status bar binder
* dies indicating sysui is no longer alive.
*/
void onGlobalActionsAvailableChanged(boolean available);
/**
* Callback from sysui to notify system that global actions has been successfully shown.
*/
void onGlobalActionsShown();
/**
* Callback from sysui to notify system that the user has dismissed global actions and
* it no longer needs to be displayed (even if sysui dies).
*/
void onGlobalActionsDismissed();
}
}
3.2、StatusBarManagerService 登场
-
代码路径:frameworks\base\services\core\java\com\android\server\statusbar\StatusBarManagerService.java
-
第2节中 mGlobalActionsProvider.showGlobalActions()调用的实际上是mBar.showGlobalActionsMenu(),这里mBar就是IStatusBar。StatusBarManagerService相当于是客户端,全局搜索一下谁继承了IStatusBar.Stub 就是服务端了。
-
CommandQueue extends IStatusBar.Stub,说明CommandQueue是服务端。
private final GlobalActionsProvider mGlobalActionsProvider = new GlobalActionsProvider() {
@Override
public boolean isGlobalActionsDisabled() {
// TODO(b/118592525): support global actions for multi-display.
final int disabled2 = mDisplayUiState.get(DEFAULT_DISPLAY).getDisabled2();
return (disabled2 & DISABLE2_GLOBAL_ACTIONS) != 0;
}
@Override
public void setGlobalActionsListener(GlobalActionsProvider.GlobalActionsListener listener) {
mGlobalActionListener = listener;
mGlobalActionListener.onGlobalActionsAvailableChanged(mBar != null);
}
@Override
public void showGlobalActions() {
if (mBar != null) {
try {
mBar.showGlobalActionsMenu();
} catch (RemoteException ex) {
}
}
}
};
3.3、CommandQueue的 showGlobalActionsMenu 方法
- 上文中提到mGlobalActionsProvider.showGlobalActions() 调用的实际上是CommandQueue 的showGlobalActionsMenu。
- 紧接着又调用了mCallbacks.get(i).handleShowGlobalActionsMenu(),这个Callbacks 是CommandQueue内部的一个接口类。我们看谁实现了这个Callbacks 接口就知道下一步调用的哪里了。
- 使用命令“grep -rn “implements Callbacks” vendor/mediatek/proprietary/packages/apps/SystemUI/” 最终查到是GlobalActionsComponent.java,那么下一步就看GlobalActionsComponent 的handleShowGlobalActionsMenu()方法就好了。
@Override
public void showGlobalActionsMenu() {
synchronized (mLock) {
mHandler.removeMessages(MSG_SHOW_GLOBAL_ACTIONS);
mHandler.obtainMessage(MSG_SHOW_GLOBAL_ACTIONS).sendToTarget();
}
}
...此处省略部分代码
case MSG_SHOW_GLOBAL_ACTIONS:
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).handleShowGlobalActionsMenu();
}
3.4、GlobalActionsComponent 的handleShowGlobalActionsMenu()方法
- 看下mExtension定义:private Extension mExtension,那么实际是调用GlobalActions的showGlobalActions。
@Override
public void handleShowGlobalActionsMenu() {
mStatusBarKeyguardViewManager.setGlobalActionsVisible(true);
mExtension.get().showGlobalActions(this);
}
3.5、SystemUI的GlobalActions
-
代码路径:vendor\mediatek\proprietary\packages\apps\SystemUI\plugin\src\com\android\systemui\plugins\GlobalActions.java
-
SystemUI的GlobalActions 跟framework中的GlobalActions 差不多,都是一个接口类,这里绕了一大圈还是调用同名的GlobalActions,这个过程确实很繁琐,可能是为了适配SystemUI的架构这样搞的。
-
“grep -rn “showGlobalActions” vendor/mediatek/proprietary/packages/apps/SystemUI/” 可以搜索到GlobalActionsImpl 中调用了showGlobalActions。
package com.android.systemui.plugins;
import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
import com.android.systemui.plugins.annotations.DependsOn;
import com.android.systemui.plugins.annotations.ProvidesInterface;
@ProvidesInterface(action = GlobalActions.ACTION, version = GlobalActions.VERSION)
@DependsOn(target = GlobalActionsManager.class)
public interface GlobalActions extends Plugin {
String ACTION = "com.android.systemui.action.PLUGIN_GLOBAL_ACTIONS";
int VERSION = 1;
void showGlobalActions(GlobalActionsManager manager);
default void showShutdownUi(boolean isReboot, String reason) {
}
default void destroy() {
}
@ProvidesInterface(version = GlobalActionsManager.VERSION)
public interface GlobalActionsManager {
int VERSION = 1;
void onGlobalActionsShown();
void onGlobalActionsHidden();
void shutdown();
void reboot(boolean safeMode);
}
}
3.6、GlobalActionsImpl 调用showGlobalActions
- 代码路径:vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\globalactions\GlobalActionsImpl.java
- GlobalActionsImpl 的showGlobalActions实际上是mGlobalActionsDialog.showOrHideDialog,这里mGlobalActionsDialog 就是mGlobalActionsDialog,终于找到最终调用关机界面的地方了。
@Override
public void showGlobalActions(GlobalActionsManager manager) {
if (mDisabled) return;
mGlobalActionsDialog = mGlobalActionsDialogLazy.get();
mGlobalActionsDialog.showOrHideDialog(mKeyguardStateController.isShowing(),
mDeviceProvisionedController.isDeviceProvisioned(),
mWalletPluginProvider.get());
Dependency.get(KeyguardUpdateMonitor.class).requestFaceAuth();
}
四、最终的关机界面 GlobalActionsDialog
-
代码路径:vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\globalactions\GlobalActionsDialog.java
-
GlobalActionsDialog中有几个重要的方法,createDialog创建关机对话框;
-
关机界面有很多功能 例如关机、重启、静音都是像“ShutDownAction extends SinglePressAction implements LongPressAction” 这样形式实现的内部类。并且个功能单按点击是onPress() 方法,长按点击是
onLongPress() 方法。
/*
* 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.globalactions;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_GLOBAL_ACTIONS;
import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_GLOBAL_ACTIONS_SHOWING;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.Dialog;
import android.app.IActivityManager;
import android.app.PendingIntent;
import android.app.StatusBarManager;
import android.app.WallpaperManager;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.UserInfo;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.Vibrator;
import android.provider.Settings;
import android.service.dreams.IDreamManager;
import android.sysprop.TelephonyProperties;
import android.telecom.TelecomManager;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.transition.AutoTransition;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.util.ArraySet;
import android.util.FeatureFlagUtils;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.IWindowManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.ListPopupWindow;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
import com.android.internal.colorextraction.drawable.ScrimDrawable;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.EmergencyAffordanceManager;
import com.android.internal.util.ScreenRecordHelper;
import com.android.internal.util.ScreenshotHelper;
import com.android.internal.view.RotationPolicy;
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.Interpolators;
import com.android.systemui.MultiListLayout;
import com.android.systemui.MultiListLayout.MultiListAdapter;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.controls.ControlsServiceInfo;
import com.android.systemui.controls.controller.ControlsController;
import com.android.systemui.controls.dagger.ControlsComponent;
import com.android.systemui.controls.management.ControlsAnimations;
import com.android.systemui.controls.ui.ControlsUiController;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.model.SysUiState;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
import com.android.systemui.plugins.GlobalActionsPanelPlugin;
import com.android.systemui.settings.CurrentUserContextTracker;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.EmergencyDialerConstants;
import com.android.systemui.util.RingerModeTracker;
import com.android.systemui.util.leak.RotationUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Executor;
import javax.inject.Inject;
/**
* Helper to show the global actions dialog. Each item is an {@link Action} that may show depending
* on whether the keyguard is showing, and whether the device is provisioned.
*/
public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
DialogInterface.OnShowListener,
ConfigurationController.ConfigurationListener,
GlobalActionsPanelPlugin.Callbacks,
LifecycleOwner {
public static final String SYSTEM_DIALOG_REASON_KEY = "reason";
public static final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
public static final String SYSTEM_DIALOG_REASON_DREAM = "dream";
private static final String TAG = "GlobalActionsDialog";
private static final boolean SHOW_SILENT_TOGGLE = true;
/* Valid settings for global actions keys.
* see config.xml config_globalActionList */
@VisibleForTesting
static final String GLOBAL_ACTION_KEY_POWER = "power";
private static final String GLOBAL_ACTION_KEY_AIRPLANE = "airplane";
static final String GLOBAL_ACTION_KEY_BUGREPORT = "bugreport";
private static final String GLOBAL_ACTION_KEY_SILENT = "silent";
private static final String GLOBAL_ACTION_KEY_USERS = "users";
private static final String GLOBAL_ACTION_KEY_SETTINGS = "settings";
static final String GLOBAL_ACTION_KEY_LOCKDOWN = "lockdown";
private static final String GLOBAL_ACTION_KEY_VOICEASSIST = "voiceassist";
private static final String GLOBAL_ACTION_KEY_ASSIST = "assist";
static final String GLOBAL_ACTION_KEY_RESTART = "restart";
private static final String GLOBAL_ACTION_KEY_LOGOUT = "logout";
static final String GLOBAL_ACTION_KEY_EMERGENCY = "emergency";
static final String GLOBAL_ACTION_KEY_SCREENSHOT = "screenshot";
public static final String PREFS_CONTROLS_SEEDING_COMPLETED = "SeedingCompleted";
public static final String PREFS_CONTROLS_FILE = "controls_prefs";
private static final int SEEDING_MAX = 2;
private final Context mContext;
private final GlobalActionsManager mWindowManagerFuncs;
private final AudioManager mAudioManager;
private final IDreamManager mDreamManager;
private final DevicePolicyManager mDevicePolicyManager;
private final LockPatternUtils mLockPatternUtils;
private final KeyguardStateController mKeyguardStateController;
private final BroadcastDispatcher mBroadcastDispatcher;
private final ContentResolver mContentResolver;
private final Resources mResources;
private final ConfigurationController mConfigurationController;
private final UserManager mUserManager;
private final TrustManager mTrustManager;
private final IActivityManager mIActivityManager;
private final TelecomManager mTelecomManager;
private final MetricsLogger mMetricsLogger;
private final UiEventLogger mUiEventLogger;
private final NotificationShadeDepthController mDepthController;
private final SysUiState mSysUiState;
// Used for RingerModeTracker
private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this);
@VisibleForTesting
protected final ArrayList<Action> mItems = new ArrayList<>();
@VisibleForTesting
protected final ArrayList<Action> mOverflowItems = new ArrayList<>();
@VisibleForTesting
protected final ArrayList<Action> mPowerItems = new ArrayList<>();
@VisibleForTesting
protected ActionsDialog mDialog;
private Action mSilentModeAction;
private ToggleAction mAirplaneModeOn;
private MyAdapter mAdapter;
private MyOverflowAdapter mOverflowAdapter;
private MyPowerOptionsAdapter mPowerAdapter;
private boolean mKeyguardShowing = false;
private boolean mDeviceProvisioned = false;
private ToggleState mAirplaneState = ToggleState.Off;
private boolean mIsWaitingForEcmExit = false;
private boolean mHasTelephony;
private boolean mHasVibrator;
private final boolean mShowSilentToggle;
private final EmergencyAffordanceManager mEmergencyAffordanceManager;
private final ScreenshotHelper mScreenshotHelper;
private final ScreenRecordHelper mScreenRecordHelper;
private final ActivityStarter mActivityStarter;
private final SysuiColorExtractor mSysuiColorExtractor;
private final IStatusBarService mStatusBarService;
private final NotificationShadeWindowController mNotificationShadeWindowController;
private GlobalActionsPanelPlugin mWalletPlugin;
private Optional<ControlsUiController> mControlsUiControllerOptional;
private final IWindowManager mIWindowManager;
private final Executor mBackgroundExecutor;
private List<ControlsServiceInfo> mControlsServiceInfos = new ArrayList<>();
private Optional<ControlsController> mControlsControllerOptional;
private final RingerModeTracker mRingerModeTracker;
private int mDialogPressDelay = DIALOG_PRESS_DELAY; // ms
private Handler mMainHandler;
private CurrentUserContextTracker mCurrentUserContextTracker;
@VisibleForTesting
boolean mShowLockScreenCardsAndControls = false;
@VisibleForTesting
public enum GlobalActionsEvent implements UiEventLogger.UiEventEnum {
@UiEvent(doc = "The global actions / power menu surface became visible on the screen.")
GA_POWER_MENU_OPEN(337),
@UiEvent(doc = "The global actions / power menu surface was dismissed.")
GA_POWER_MENU_CLOSE(471),
@UiEvent(doc = "The global actions bugreport button was pressed.")
GA_BUGREPORT_PRESS(344),
@UiEvent(doc = "The global actions bugreport button was long pressed.")
GA_BUGREPORT_LONG_PRESS(345),
@UiEvent(doc = "The global actions emergency button was pressed.")
GA_EMERGENCY_DIALER_PRESS(346),
@UiEvent(doc = "The global actions screenshot button was pressed.")
GA_SCREENSHOT_PRESS(347),
@UiEvent(doc = "The global actions screenshot button was long pressed.")
GA_SCREENSHOT_LONG_PRESS(348);
private final int mId;
GlobalActionsEvent(int id) {
mId = id;
}
@Override
public int getId() {
return mId;
}
}
/**
* @param context everything needs a context :(
*/
@Inject
public GlobalActionsDialog(Context context, GlobalActionsManager windowManagerFuncs,
AudioManager audioManager, IDreamManager iDreamManager,
DevicePolicyManager devicePolicyManager, LockPatternUtils lockPatternUtils,
BroadcastDispatcher broadcastDispatcher,
ConnectivityManager connectivityManager, TelephonyManager telephonyManager,
ContentResolver contentResolver, @Nullable Vibrator vibrator, @Main Resources resources,
ConfigurationController configurationController, ActivityStarter activityStarter,
KeyguardStateController keyguardStateController, UserManager userManager,
TrustManager trustManager, IActivityManager iActivityManager,
@Nullable TelecomManager telecomManager, MetricsLogger metricsLogger,
NotificationShadeDepthController depthController, SysuiColorExtractor colorExtractor,
IStatusBarService statusBarService,
NotificationShadeWindowController notificationShadeWindowController,
IWindowManager iWindowManager,
@Background Executor backgroundExecutor,
UiEventLogger uiEventLogger,
RingerModeTracker ringerModeTracker, SysUiState sysUiState, @Main Handler handler,
ControlsComponent controlsComponent,
CurrentUserContextTracker currentUserContextTracker) {
mContext = context;
mWindowManagerFuncs = windowManagerFuncs;
mAudioManager = audioManager;
mDreamManager = iDreamManager;
mDevicePolicyManager = devicePolicyManager;
mLockPatternUtils = lockPatternUtils;
mKeyguardStateController = keyguardStateController;
mBroadcastDispatcher = broadcastDispatcher;
mContentResolver = contentResolver;
mResources = resources;
mConfigurationController = configurationController;
mUserManager = userManager;
mTrustManager = trustManager;
mIActivityManager = iActivityManager;
mTelecomManager = telecomManager;
mMetricsLogger = metricsLogger;
mUiEventLogger = uiEventLogger;
mDepthController = depthController;
mSysuiColorExtractor = colorExtractor;
mStatusBarService = statusBarService;
mNotificationShadeWindowController = notificationShadeWindowController;
mControlsUiControllerOptional = controlsComponent.getControlsUiController();
mIWindowManager = iWindowManager;
mBackgroundExecutor = backgroundExecutor;
mRingerModeTracker = ringerModeTracker;
mControlsControllerOptional = controlsComponent.getControlsController();
mSysUiState = sysUiState;
mMainHandler = handler;
mCurrentUserContextTracker = currentUserContextTracker;
// receive broadcasts
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter);
mHasTelephony = connectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
// get notified of phone state changes
telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
contentResolver.registerContentObserver(
Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
mAirplaneModeObserver);
mHasVibrator = vibrator != null && vibrator.hasVibrator();
mShowSilentToggle = SHOW_SILENT_TOGGLE && !resources.getBoolean(
R