1361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk/*
2361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk * Copyright (C) 2017 The Android Open Source Project
3361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk *
4361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk * except in compliance with the License. You may obtain a copy of the License at
6361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk *
7361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk *      http://www.apache.org/licenses/LICENSE-2.0
8361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk *
9361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk * Unless required by applicable law or agreed to in writing, software distributed under the
10361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk * KIND, either express or implied. See the License for the specific language governing
12361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk * permissions and limitations under the License.
13361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk */
14361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
15361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkpackage com.android.systemui.globalactions;
16361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
17361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport com.android.internal.R;
18361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport com.android.internal.app.AlertController;
19361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport com.android.internal.app.AlertController.AlertParams;
20361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport com.android.internal.logging.MetricsLogger;
21361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport com.android.internal.logging.nano.MetricsProto.MetricsEvent;
22361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport com.android.internal.util.EmergencyAffordanceManager;
23361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport com.android.internal.telephony.TelephonyIntents;
24361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport com.android.internal.telephony.TelephonyProperties;
25361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport com.android.internal.widget.LockPatternUtils;
26361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
27361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
28361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.app.ActivityManager;
29361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.app.Dialog;
30361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.content.BroadcastReceiver;
31361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.content.Context;
32361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.content.DialogInterface;
33361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.content.Intent;
34361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.content.IntentFilter;
35361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.content.pm.UserInfo;
36361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.database.ContentObserver;
37361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.graphics.drawable.Drawable;
38361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.media.AudioManager;
39361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.net.ConnectivityManager;
40361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.os.Build;
41361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.os.Bundle;
42361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.os.Handler;
43361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.os.Message;
44361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.os.RemoteException;
45361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.os.ServiceManager;
46361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.os.SystemProperties;
47361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.os.UserHandle;
48361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.os.UserManager;
49361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.os.Vibrator;
50361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.provider.Settings;
51361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.service.dreams.DreamService;
52361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.service.dreams.IDreamManager;
53361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.telephony.PhoneStateListener;
54361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.telephony.ServiceState;
55361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.telephony.TelephonyManager;
56361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.text.TextUtils;
57361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.util.ArraySet;
58361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.util.Log;
59361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.util.TypedValue;
60361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.view.KeyEvent;
61361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.view.LayoutInflater;
62361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.view.View;
63361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.view.ViewGroup;
64361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.view.WindowManager;
65361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.view.WindowManagerGlobal;
66361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.view.accessibility.AccessibilityEvent;
67361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.widget.AdapterView;
68361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.widget.BaseAdapter;
69361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.widget.ImageView;
70361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.widget.ImageView.ScaleType;
71361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.widget.ListView;
72361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport android.widget.TextView;
73361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
74361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport java.util.ArrayList;
75361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkimport java.util.List;
76361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
77361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk/**
78361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk * Helper to show the global actions dialog.  Each item is an {@link Action} that
79361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk * may show depending on whether the keyguard is showing, and whether the device
80361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk * is provisioned.
81361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk */
82361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monkclass GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener  {
83361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
84361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
85361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
86361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
87361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final String TAG = "GlobalActionsDialog";
88361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
89361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final boolean SHOW_SILENT_TOGGLE = true;
90361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
91361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    /* Valid settings for global actions keys.
92361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * see config.xml config_globalActionList */
93361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final String GLOBAL_ACTION_KEY_POWER = "power";
94361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final String GLOBAL_ACTION_KEY_AIRPLANE = "airplane";
95361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final String GLOBAL_ACTION_KEY_BUGREPORT = "bugreport";
96361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final String GLOBAL_ACTION_KEY_SILENT = "silent";
97361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final String GLOBAL_ACTION_KEY_USERS = "users";
98361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final String GLOBAL_ACTION_KEY_SETTINGS = "settings";
99361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final String GLOBAL_ACTION_KEY_LOCKDOWN = "lockdown";
100361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final String GLOBAL_ACTION_KEY_VOICEASSIST = "voiceassist";
101361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final String GLOBAL_ACTION_KEY_ASSIST = "assist";
102361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final String GLOBAL_ACTION_KEY_RESTART = "restart";
103361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
104361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private final Context mContext;
105361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private final GlobalActionsManager mWindowManagerFuncs;
106361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private final AudioManager mAudioManager;
107361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private final IDreamManager mDreamManager;
108361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
109361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private ArrayList<Action> mItems;
110361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private ActionsDialog mDialog;
111361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
112361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private Action mSilentModeAction;
113361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private ToggleAction mAirplaneModeOn;
114361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
115361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private MyAdapter mAdapter;
116361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
117361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private boolean mKeyguardShowing = false;
118361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private boolean mDeviceProvisioned = false;
119361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private ToggleAction.State mAirplaneState = ToggleAction.State.Off;
120361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private boolean mIsWaitingForEcmExit = false;
121361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private boolean mHasTelephony;
122361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private boolean mHasVibrator;
123361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private final boolean mShowSilentToggle;
124361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private final EmergencyAffordanceManager mEmergencyAffordanceManager;
125361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
126361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    /**
127361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * @param context everything needs a context :(
128361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     */
129361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    public GlobalActionsDialog(Context context, GlobalActionsManager windowManagerFuncs) {
130361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mContext = context;
131361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mWindowManagerFuncs = windowManagerFuncs;
132361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
133361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mDreamManager = IDreamManager.Stub.asInterface(
134361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                ServiceManager.getService(DreamService.DREAM_SERVICE));
135361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
136361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        // receive broadcasts
137361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        IntentFilter filter = new IntentFilter();
138361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
139361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        filter.addAction(Intent.ACTION_SCREEN_OFF);
140361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
141361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        context.registerReceiver(mBroadcastReceiver, filter);
142361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
143361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        ConnectivityManager cm = (ConnectivityManager)
144361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                context.getSystemService(Context.CONNECTIVITY_SERVICE);
145361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mHasTelephony = cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
146361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
147361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        // get notified of phone state changes
148361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        TelephonyManager telephonyManager =
149361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
150361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
151361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mContext.getContentResolver().registerContentObserver(
152361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
153361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mAirplaneModeObserver);
154361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
155361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mHasVibrator = vibrator != null && vibrator.hasVibrator();
156361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
157361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mShowSilentToggle = SHOW_SILENT_TOGGLE && !mContext.getResources().getBoolean(
158361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                R.bool.config_useFixedVolume);
159361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
160361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mEmergencyAffordanceManager = new EmergencyAffordanceManager(context);
161361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
162361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
163361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    /**
164361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * Show the global actions dialog (creating if necessary)
165361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * @param keyguardShowing True if keyguard is showing
166361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     */
167361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) {
168361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mKeyguardShowing = keyguardShowing;
169361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mDeviceProvisioned = isDeviceProvisioned;
170361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        if (mDialog != null) {
171361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mDialog.dismiss();
172361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mDialog = null;
173361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            // Show delayed, so that the dismiss of the previous dialog completes
174361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mHandler.sendEmptyMessage(MESSAGE_SHOW);
175361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        } else {
176361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            handleShow();
177361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
178361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
179361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
180361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private void awakenIfNecessary() {
181361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        if (mDreamManager != null) {
182361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            try {
183361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                if (mDreamManager.isDreaming()) {
184361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    mDreamManager.awaken();
185361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
186361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } catch (RemoteException e) {
187361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                // we tried
188361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
189361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
190361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
191361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
192361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private void handleShow() {
193361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        awakenIfNecessary();
194361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mDialog = createDialog();
195361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        prepareDialog();
196361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
197361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        // If we only have 1 item and it's a simple press action, just do this action.
198361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        if (mAdapter.getCount() == 1
199361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                && mAdapter.getItem(0) instanceof SinglePressAction
200361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                && !(mAdapter.getItem(0) instanceof LongPressAction)) {
201361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            ((SinglePressAction) mAdapter.getItem(0)).onPress();
202361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        } else {
203361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            WindowManager.LayoutParams attrs = mDialog.getWindow().getAttributes();
204361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            attrs.setTitle("ActionsDialog");
205361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mDialog.getWindow().setAttributes(attrs);
206361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mDialog.show();
207361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mWindowManagerFuncs.onGlobalActionsShown();
208361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);
209361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
210361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
211361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
212361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    /**
213361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * Create the global actions dialog.
214361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * @return A new dialog.
215361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     */
216361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private ActionsDialog createDialog() {
217361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        // Simple toggle style if there's no vibrator, otherwise use a tri-state
218361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        if (!mHasVibrator) {
219361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mSilentModeAction = new SilentModeToggleAction();
220361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        } else {
221361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mSilentModeAction = new SilentModeTriStateAction(mContext, mAudioManager, mHandler);
222361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
223361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mAirplaneModeOn = new ToggleAction(
224361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                R.drawable.ic_lock_airplane_mode,
225361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                R.drawable.ic_lock_airplane_mode_off,
226361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                R.string.global_actions_toggle_airplane_mode,
227361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                R.string.global_actions_airplane_mode_on_status,
228361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                R.string.global_actions_airplane_mode_off_status) {
229361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
230361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            void onToggle(boolean on) {
231361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                if (mHasTelephony && Boolean.parseBoolean(
232361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
233361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    mIsWaitingForEcmExit = true;
234361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    // Launch ECM exit dialog
235361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    Intent ecmDialogIntent =
236361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                            new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null);
237361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    ecmDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
238361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    mContext.startActivity(ecmDialogIntent);
239361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                } else {
240361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    changeAirplaneModeSystemSetting(on);
241361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
242361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
243361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
244361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            @Override
245361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            protected void changeStateFromPress(boolean buttonOn) {
246361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                if (!mHasTelephony) return;
247361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
248361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                // In ECM mode airplane state cannot be changed
249361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                if (!(Boolean.parseBoolean(
250361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)))) {
251361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    mState = buttonOn ? State.TurningOn : State.TurningOff;
252361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    mAirplaneState = mState;
253361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
254361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
255361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
256361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public boolean showDuringKeyguard() {
257361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return true;
258361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
259361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
260361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public boolean showBeforeProvisioning() {
261361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return false;
262361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
263361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        };
264361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        onAirplaneModeChanged();
265361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
266361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mItems = new ArrayList<Action>();
267361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        String[] defaultActions = mContext.getResources().getStringArray(
268361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                R.array.config_globalActionsList);
269361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
270361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        ArraySet<String> addedKeys = new ArraySet<String>();
271361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        for (int i = 0; i < defaultActions.length; i++) {
272361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            String actionKey = defaultActions[i];
273361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (addedKeys.contains(actionKey)) {
274361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                // If we already have added this, don't add it again.
275361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                continue;
276361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
277361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (GLOBAL_ACTION_KEY_POWER.equals(actionKey)) {
278361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mItems.add(new PowerAction());
279361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } else if (GLOBAL_ACTION_KEY_AIRPLANE.equals(actionKey)) {
280361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mItems.add(mAirplaneModeOn);
281361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } else if (GLOBAL_ACTION_KEY_BUGREPORT.equals(actionKey)) {
282361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                if (Settings.Global.getInt(mContext.getContentResolver(),
283361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        Settings.Global.BUGREPORT_IN_POWER_MENU, 0) != 0 && isCurrentUserOwner()) {
284361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    mItems.add(new BugReportAction());
285361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
286361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } else if (GLOBAL_ACTION_KEY_SILENT.equals(actionKey)) {
287361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                if (mShowSilentToggle) {
288361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    mItems.add(mSilentModeAction);
289361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
290361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } else if (GLOBAL_ACTION_KEY_USERS.equals(actionKey)) {
291361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                if (SystemProperties.getBoolean("fw.power_user_switcher", false)) {
292361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    addUsersToMenu(mItems);
293361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
294361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } else if (GLOBAL_ACTION_KEY_SETTINGS.equals(actionKey)) {
295361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mItems.add(getSettingsAction());
296361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } else if (GLOBAL_ACTION_KEY_LOCKDOWN.equals(actionKey)) {
297361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mItems.add(getLockdownAction());
298361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } else if (GLOBAL_ACTION_KEY_VOICEASSIST.equals(actionKey)) {
299361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mItems.add(getVoiceAssistAction());
300361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } else if (GLOBAL_ACTION_KEY_ASSIST.equals(actionKey)) {
301361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mItems.add(getAssistAction());
302361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } else if (GLOBAL_ACTION_KEY_RESTART.equals(actionKey)) {
303361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mItems.add(new RestartAction());
304361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } else {
305361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                Log.e(TAG, "Invalid global action key " + actionKey);
306361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
307361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            // Add here so we don't add more than one.
308361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            addedKeys.add(actionKey);
309361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
310361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
311361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        if (mEmergencyAffordanceManager.needsEmergencyAffordance()) {
312361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mItems.add(getEmergencyAction());
313361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
314361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
315361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mAdapter = new MyAdapter();
316361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
317361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        AlertParams params = new AlertParams(mContext);
318361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        params.mAdapter = mAdapter;
319361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        params.mOnClickListener = this;
320361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        params.mForceInverseBackground = true;
321361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
322361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        ActionsDialog dialog = new ActionsDialog(mContext, params);
323361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
324361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
325361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        dialog.getListView().setItemsCanFocus(true);
326361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        dialog.getListView().setLongClickable(true);
327361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        dialog.getListView().setOnItemLongClickListener(
328361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                new AdapterView.OnItemLongClickListener() {
329361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    @Override
330361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
331361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                            long id) {
332361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        final Action action = mAdapter.getItem(position);
333361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        if (action instanceof LongPressAction) {
334361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                            return ((LongPressAction) action).onLongPress();
335361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        }
336361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        return false;
337361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    }
338361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        });
339361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
340361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
341361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        dialog.setOnDismissListener(this);
342361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
343361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        return dialog;
344361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
345361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
346361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private final class PowerAction extends SinglePressAction implements LongPressAction {
347361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        private PowerAction() {
348361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            super(R.drawable.ic_lock_power_off,
349361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                R.string.global_action_power_off);
350361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
351361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
352361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
353361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean onLongPress() {
354361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
355361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (!um.hasUserRestriction(UserManager.DISALLOW_SAFE_BOOT)) {
356361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mWindowManagerFuncs.reboot(true);
357361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return true;
358361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
359361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return false;
360361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
361361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
362361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
363361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean showDuringKeyguard() {
364361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return true;
365361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
366361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
367361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
368361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean showBeforeProvisioning() {
369361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return true;
370361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
371361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
372361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
373361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public void onPress() {
374361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            // shutdown by making sure radio and power are handled accordingly.
375361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mWindowManagerFuncs.shutdown();
376361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
377361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
378361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
379361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private final class RestartAction extends SinglePressAction implements LongPressAction {
380361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        private RestartAction() {
381361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            super(R.drawable.ic_restart, R.string.global_action_restart);
382361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
383361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
384361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
385361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean onLongPress() {
386361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
387361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (!um.hasUserRestriction(UserManager.DISALLOW_SAFE_BOOT)) {
388361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mWindowManagerFuncs.reboot(true);
389361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return true;
390361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
391361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return false;
392361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
393361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
394361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
395361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean showDuringKeyguard() {
396361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return true;
397361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
398361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
399361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
400361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean showBeforeProvisioning() {
401361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return true;
402361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
403361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
404361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
405361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public void onPress() {
406361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mWindowManagerFuncs.reboot(false);
407361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
408361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
409361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
410361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
411361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private class BugReportAction extends SinglePressAction implements LongPressAction {
412361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
413361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public BugReportAction() {
414361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            super(R.drawable.ic_lock_bugreport, R.string.bugreport_title);
415361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
416361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
417361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
418361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public void onPress() {
419361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            // don't actually trigger the bugreport if we are running stability
420361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            // tests via monkey
421361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (ActivityManager.isUserAMonkey()) {
422361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return;
423361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
424361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            // Add a little delay before executing, to give the
425361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            // dialog a chance to go away before it takes a
426361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            // screenshot.
427361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mHandler.postDelayed(new Runnable() {
428361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                @Override
429361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                public void run() {
430361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    try {
431361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        // Take an "interactive" bugreport.
432361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        MetricsLogger.action(mContext,
433361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                                MetricsEvent.ACTION_BUGREPORT_FROM_POWER_MENU_INTERACTIVE);
434361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        ActivityManager.getService().requestBugReport(
435361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                                ActivityManager.BUGREPORT_OPTION_INTERACTIVE);
436361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    } catch (RemoteException e) {
437361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    }
438361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
439361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }, 500);
440361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
441361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
442361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
443361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean onLongPress() {
444361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            // don't actually trigger the bugreport if we are running stability
445361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            // tests via monkey
446361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (ActivityManager.isUserAMonkey()) {
447361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return false;
448361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
449361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            try {
450361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                // Take a "full" bugreport.
451361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                MetricsLogger.action(mContext, MetricsEvent.ACTION_BUGREPORT_FROM_POWER_MENU_FULL);
452361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                ActivityManager.getService().requestBugReport(
453361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        ActivityManager.BUGREPORT_OPTION_FULL);
454361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } catch (RemoteException e) {
455361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
456361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return false;
457361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
458361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
459361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean showDuringKeyguard() {
460361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return true;
461361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
462361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
463361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
464361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean showBeforeProvisioning() {
465361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return false;
466361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
467361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
468361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
469361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public String getStatus() {
470361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return mContext.getString(
471361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    R.string.bugreport_status,
472361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    Build.VERSION.RELEASE,
473361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    Build.ID);
474361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
475361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
476361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
477361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private Action getSettingsAction() {
478361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        return new SinglePressAction(R.drawable.ic_settings,
479361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                R.string.global_action_settings) {
480361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
481361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            @Override
482361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public void onPress() {
483361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                Intent intent = new Intent(Settings.ACTION_SETTINGS);
484361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
485361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mContext.startActivity(intent);
486361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
487361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
488361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            @Override
489361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public boolean showDuringKeyguard() {
490361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return true;
491361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
492361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
493361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            @Override
494361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public boolean showBeforeProvisioning() {
495361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return true;
496361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
497361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        };
498361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
499361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
500361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private Action getEmergencyAction() {
501361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        return new SinglePressAction(R.drawable.emergency_icon,
502361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                R.string.global_action_emergency) {
503361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            @Override
504361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public void onPress() {
505361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mEmergencyAffordanceManager.performEmergencyCall();
506361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
507361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
508361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            @Override
509361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public boolean showDuringKeyguard() {
510361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return true;
511361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
512361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
513361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            @Override
514361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public boolean showBeforeProvisioning() {
515361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return true;
516361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
517361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        };
518361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
519361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
520361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private Action getAssistAction() {
521361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        return new SinglePressAction(R.drawable.ic_action_assist_focused,
522361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                R.string.global_action_assist) {
523361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            @Override
524361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public void onPress() {
525361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                Intent intent = new Intent(Intent.ACTION_ASSIST);
526361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
527361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mContext.startActivity(intent);
528361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
529361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
530361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            @Override
531361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public boolean showDuringKeyguard() {
532361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return true;
533361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
534361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
535361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            @Override
536361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public boolean showBeforeProvisioning() {
537361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return true;
538361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
539361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        };
540361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
541361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
542361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private Action getVoiceAssistAction() {
543361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        return new SinglePressAction(R.drawable.ic_voice_search,
544361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                R.string.global_action_voice_assist) {
545361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            @Override
546361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public void onPress() {
547361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                Intent intent = new Intent(Intent.ACTION_VOICE_ASSIST);
548361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
549361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mContext.startActivity(intent);
550361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
551361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
552361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            @Override
553361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public boolean showDuringKeyguard() {
554361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return true;
555361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
556361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
557361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            @Override
558361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public boolean showBeforeProvisioning() {
559361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return true;
560361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
561361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        };
562361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
563361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
564361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private Action getLockdownAction() {
565361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        return new SinglePressAction(R.drawable.ic_lock_lock,
566361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                R.string.global_action_lockdown) {
567361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
568361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            @Override
569361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public void onPress() {
570361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                new LockPatternUtils(mContext).requireCredentialEntry(UserHandle.USER_ALL);
571361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                try {
572361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    WindowManagerGlobal.getWindowManagerService().lockNow(null);
573361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                } catch (RemoteException e) {
574361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    Log.e(TAG, "Error while trying to lock device.", e);
575361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
576361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
577361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
578361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            @Override
579361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public boolean showDuringKeyguard() {
580361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return true;
581361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
582361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
583361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            @Override
584361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public boolean showBeforeProvisioning() {
585361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return false;
586361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
587361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        };
588361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
589361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
590361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private UserInfo getCurrentUser() {
591361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        try {
592361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return ActivityManager.getService().getCurrentUser();
593361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        } catch (RemoteException re) {
594361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return null;
595361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
596361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
597361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
598361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private boolean isCurrentUserOwner() {
599361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        UserInfo currentUser = getCurrentUser();
600361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        return currentUser == null || currentUser.isPrimary();
601361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
602361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
603361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private void addUsersToMenu(ArrayList<Action> items) {
604361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
605361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        if (um.isUserSwitcherEnabled()) {
606361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            List<UserInfo> users = um.getUsers();
607361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            UserInfo currentUser = getCurrentUser();
608361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            for (final UserInfo user : users) {
609361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                if (user.supportsSwitchToByUser()) {
610361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    boolean isCurrentUser = currentUser == null
611361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                            ? user.id == 0 : (currentUser.id == user.id);
612361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    Drawable icon = user.iconPath != null ? Drawable.createFromPath(user.iconPath)
613361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                            : null;
614361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    SinglePressAction switchToUser = new SinglePressAction(
615361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                            R.drawable.ic_menu_cc, icon,
616361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                            (user.name != null ? user.name : "Primary")
617361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                            + (isCurrentUser ? " \u2714" : "")) {
618361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        public void onPress() {
619361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                            try {
620361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                                ActivityManager.getService().switchUser(user.id);
621361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                            } catch (RemoteException re) {
622361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                                Log.e(TAG, "Couldn't switch user " + re);
623361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                            }
624361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        }
625361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
626361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        public boolean showDuringKeyguard() {
627361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                            return true;
628361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        }
629361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
630361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        public boolean showBeforeProvisioning() {
631361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                            return false;
632361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        }
633361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    };
634361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    items.add(switchToUser);
635361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
636361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
637361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
638361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
639361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
640361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private void prepareDialog() {
641361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        refreshSilentMode();
642361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mAirplaneModeOn.updateState(mAirplaneState);
643361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mAdapter.notifyDataSetChanged();
644361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
645361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        if (mShowSilentToggle) {
646361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
647361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mContext.registerReceiver(mRingerModeReceiver, filter);
648361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
649361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
650361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
651361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private void refreshSilentMode() {
652361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        if (!mHasVibrator) {
653361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            final boolean silentModeOn =
654361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
655361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            ((ToggleAction)mSilentModeAction).updateState(
656361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    silentModeOn ? ToggleAction.State.On : ToggleAction.State.Off);
657361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
658361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
659361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
660361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    /** {@inheritDoc} */
661361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    public void onDismiss(DialogInterface dialog) {
662361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mWindowManagerFuncs.onGlobalActionsHidden();
663361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        if (mShowSilentToggle) {
664361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            try {
665361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mContext.unregisterReceiver(mRingerModeReceiver);
666361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } catch (IllegalArgumentException ie) {
667361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                // ignore this
668361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                Log.w(TAG, ie);
669361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
670361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
671361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
672361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
673361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    /** {@inheritDoc} */
674361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    public void onClick(DialogInterface dialog, int which) {
675361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        if (!(mAdapter.getItem(which) instanceof SilentModeTriStateAction)) {
676361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            dialog.dismiss();
677361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
678361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mAdapter.getItem(which).onPress();
679361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
680361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
681361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    /**
682361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * The adapter used for the list within the global actions dialog, taking
683361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * into account whether the keyguard is showing via
684361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * {@link com.android.systemui.globalactions.GlobalActionsDialog#mKeyguardShowing} and whether the device is provisioned
685361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * via {@link com.android.systemui.globalactions.GlobalActionsDialog#mDeviceProvisioned}.
686361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     */
687361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private class MyAdapter extends BaseAdapter {
688361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
689361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public int getCount() {
690361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            int count = 0;
691361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
692361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            for (int i = 0; i < mItems.size(); i++) {
693361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                final Action action = mItems.get(i);
694361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
695361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                if (mKeyguardShowing && !action.showDuringKeyguard()) {
696361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    continue;
697361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
698361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                if (!mDeviceProvisioned && !action.showBeforeProvisioning()) {
699361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    continue;
700361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
701361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                count++;
702361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
703361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return count;
704361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
705361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
706361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
707361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean isEnabled(int position) {
708361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return getItem(position).isEnabled();
709361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
710361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
711361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
712361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean areAllItemsEnabled() {
713361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return false;
714361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
715361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
716361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public Action getItem(int position) {
717361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
718361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            int filteredPos = 0;
719361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            for (int i = 0; i < mItems.size(); i++) {
720361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                final Action action = mItems.get(i);
721361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                if (mKeyguardShowing && !action.showDuringKeyguard()) {
722361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    continue;
723361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
724361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                if (!mDeviceProvisioned && !action.showBeforeProvisioning()) {
725361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    continue;
726361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
727361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                if (filteredPos == position) {
728361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    return action;
729361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
730361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                filteredPos++;
731361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
732361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
733361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            throw new IllegalArgumentException("position " + position
734361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    + " out of range of showable actions"
735361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    + ", filtered count=" + getCount()
736361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    + ", keyguardshowing=" + mKeyguardShowing
737361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    + ", provisioned=" + mDeviceProvisioned);
738361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
739361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
740361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
741361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public long getItemId(int position) {
742361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return position;
743361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
744361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
745361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public View getView(int position, View convertView, ViewGroup parent) {
746361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            Action action = getItem(position);
747361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
748361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
749361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
750361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
751361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    // note: the scheme below made more sense when we were planning on having
752361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    // 8 different things in the global actions dialog.  seems overkill with
753361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    // only 3 items now, but may as well keep this flexible approach so it will
754361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    // be easy should someone decide at the last minute to include something
755361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    // else, such as 'enable wifi', or 'enable bluetooth'
756361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
757361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    /**
758361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * What each item in the global actions dialog must be able to support.
759361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     */
760361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private interface Action {
761361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        /**
762361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         * @return Text that will be announced when dialog is created.  null
763361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         *     for none.
764361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         */
765361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        CharSequence getLabelForAccessibility(Context context);
766361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
767361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        View create(Context context, View convertView, ViewGroup parent, LayoutInflater inflater);
768361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
769361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        void onPress();
770361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
771361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        /**
772361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         * @return whether this action should appear in the dialog when the keygaurd
773361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         *    is showing.
774361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         */
775361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        boolean showDuringKeyguard();
776361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
777361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        /**
778361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         * @return whether this action should appear in the dialog before the
779361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         *   device is provisioned.
780361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         */
781361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        boolean showBeforeProvisioning();
782361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
783361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        boolean isEnabled();
784361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
785361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
786361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    /**
787361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * An action that also supports long press.
788361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     */
789361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private interface LongPressAction extends Action {
790361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        boolean onLongPress();
791361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
792361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
793361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    /**
794361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * A single press action maintains no state, just responds to a press
795361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * and takes an action.
796361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     */
797361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static abstract class SinglePressAction implements Action {
798361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        private final int mIconResId;
799361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        private final Drawable mIcon;
800361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        private final int mMessageResId;
801361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        private final CharSequence mMessage;
802361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
803361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        protected SinglePressAction(int iconResId, int messageResId) {
804361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mIconResId = iconResId;
805361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mMessageResId = messageResId;
806361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mMessage = null;
807361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mIcon = null;
808361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
809361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
810361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        protected SinglePressAction(int iconResId, Drawable icon, CharSequence message) {
811361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mIconResId = iconResId;
812361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mMessageResId = 0;
813361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mMessage = message;
814361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mIcon = icon;
815361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
816361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
817361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean isEnabled() {
818361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return true;
819361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
820361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
821361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public String getStatus() {
822361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return null;
823361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
824361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
825361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        abstract public void onPress();
826361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
827361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public CharSequence getLabelForAccessibility(Context context) {
828361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (mMessage != null) {
829361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return mMessage;
830361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } else {
831361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return context.getString(mMessageResId);
832361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
833361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
834361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
835361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public View create(
836361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
837361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            View v = inflater.inflate(R.layout.global_actions_item, parent, false);
838361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
839361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            ImageView icon = (ImageView) v.findViewById(R.id.icon);
840361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            TextView messageView = (TextView) v.findViewById(R.id.message);
841361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
842361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            TextView statusView = (TextView) v.findViewById(R.id.status);
843361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            final String status = getStatus();
844361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (!TextUtils.isEmpty(status)) {
845361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                statusView.setText(status);
846361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } else {
847361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                statusView.setVisibility(View.GONE);
848361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
849361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (mIcon != null) {
850361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                icon.setImageDrawable(mIcon);
851361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                icon.setScaleType(ScaleType.CENTER_CROP);
852361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } else if (mIconResId != 0) {
853361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                icon.setImageDrawable(context.getDrawable(mIconResId));
854361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
855361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (mMessage != null) {
856361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                messageView.setText(mMessage);
857361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } else {
858361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                messageView.setText(mMessageResId);
859361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
860361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
861361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return v;
862361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
863361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
864361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
865361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    /**
866361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * A toggle action knows whether it is on or off, and displays an icon
867361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * and status message accordingly.
868361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     */
869361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static abstract class ToggleAction implements Action {
870361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
871361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        enum State {
872361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            Off(false),
873361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            TurningOn(true),
874361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            TurningOff(true),
875361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            On(false);
876361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
877361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            private final boolean inTransition;
878361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
879361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            State(boolean intermediate) {
880361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                inTransition = intermediate;
881361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
882361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
883361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            public boolean inTransition() {
884361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return inTransition;
885361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
886361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
887361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
888361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        protected State mState = State.Off;
889361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
890361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        // prefs
891361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        protected int mEnabledIconResId;
892361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        protected int mDisabledIconResid;
893361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        protected int mMessageResId;
894361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        protected int mEnabledStatusMessageResId;
895361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        protected int mDisabledStatusMessageResId;
896361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
897361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        /**
898361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         * @param enabledIconResId The icon for when this action is on.
899361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         * @param disabledIconResid The icon for when this action is off.
900361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         * @param message The general information message, e.g 'Silent Mode'
901361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         * @param enabledStatusMessageResId The on status message, e.g 'sound disabled'
902361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         * @param disabledStatusMessageResId The off status message, e.g. 'sound enabled'
903361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         */
904361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public ToggleAction(int enabledIconResId,
905361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                int disabledIconResid,
906361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                int message,
907361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                int enabledStatusMessageResId,
908361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                int disabledStatusMessageResId) {
909361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mEnabledIconResId = enabledIconResId;
910361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mDisabledIconResid = disabledIconResid;
911361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mMessageResId = message;
912361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mEnabledStatusMessageResId = enabledStatusMessageResId;
913361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mDisabledStatusMessageResId = disabledStatusMessageResId;
914361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
915361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
916361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        /**
917361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         * Override to make changes to resource IDs just before creating the
918361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         * View.
919361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         */
920361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        void willCreate() {
921361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
922361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
923361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
924361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
925361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public CharSequence getLabelForAccessibility(Context context) {
926361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return context.getString(mMessageResId);
927361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
928361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
929361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public View create(Context context, View convertView, ViewGroup parent,
930361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                LayoutInflater inflater) {
931361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            willCreate();
932361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
933361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            View v = inflater.inflate(R
934361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                            .layout.global_actions_item, parent, false);
935361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
936361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            ImageView icon = (ImageView) v.findViewById(R.id.icon);
937361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            TextView messageView = (TextView) v.findViewById(R.id.message);
938361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            TextView statusView = (TextView) v.findViewById(R.id.status);
939361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            final boolean enabled = isEnabled();
940361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
941361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (messageView != null) {
942361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                messageView.setText(mMessageResId);
943361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                messageView.setEnabled(enabled);
944361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
945361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
946361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            boolean on = ((mState == State.On) || (mState == State.TurningOn));
947361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (icon != null) {
948361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                icon.setImageDrawable(context.getDrawable(
949361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        (on ? mEnabledIconResId : mDisabledIconResid)));
950361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                icon.setEnabled(enabled);
951361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
952361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
953361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (statusView != null) {
954361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                statusView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId);
955361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                statusView.setVisibility(View.VISIBLE);
956361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                statusView.setEnabled(enabled);
957361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
958361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            v.setEnabled(enabled);
959361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
960361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return v;
961361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
962361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
963361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public final void onPress() {
964361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (mState.inTransition()) {
965361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                Log.w(TAG, "shouldn't be able to toggle when in transition");
966361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return;
967361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
968361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
969361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            final boolean nowOn = !(mState == State.On);
970361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            onToggle(nowOn);
971361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            changeStateFromPress(nowOn);
972361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
973361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
974361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean isEnabled() {
975361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return !mState.inTransition();
976361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
977361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
978361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        /**
979361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         * Implementations may override this if their state can be in on of the intermediate
980361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         * states until some notification is received (e.g airplane mode is 'turning off' until
981361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         * we know the wireless connections are back online
982361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         * @param buttonOn Whether the button was turned on or off
983361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk         */
984361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        protected void changeStateFromPress(boolean buttonOn) {
985361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mState = buttonOn ? State.On : State.Off;
986361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
987361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
988361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        abstract void onToggle(boolean on);
989361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
990361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public void updateState(State state) {
991361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mState = state;
992361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
993361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
994361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
995361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private class SilentModeToggleAction extends ToggleAction {
996361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public SilentModeToggleAction() {
997361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            super(R.drawable.ic_audio_vol_mute,
998361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    R.drawable.ic_audio_vol,
999361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    R.string.global_action_toggle_silent_mode,
1000361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    R.string.global_action_silent_mode_on_status,
1001361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    R.string.global_action_silent_mode_off_status);
1002361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1003361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1004361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        void onToggle(boolean on) {
1005361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (on) {
1006361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
1007361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } else {
1008361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
1009361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
1010361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1011361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1012361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean showDuringKeyguard() {
1013361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return true;
1014361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1015361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1016361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean showBeforeProvisioning() {
1017361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return false;
1018361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1019361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
1020361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1021361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static class SilentModeTriStateAction implements Action, View.OnClickListener {
1022361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1023361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        private final int[] ITEM_IDS = { R.id.option1, R.id.option2, R.id.option3 };
1024361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1025361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        private final AudioManager mAudioManager;
1026361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        private final Handler mHandler;
1027361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        private final Context mContext;
1028361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1029361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        SilentModeTriStateAction(Context context, AudioManager audioManager, Handler handler) {
1030361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mAudioManager = audioManager;
1031361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mHandler = handler;
1032361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mContext = context;
1033361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1034361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1035361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        private int ringerModeToIndex(int ringerMode) {
1036361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            // They just happen to coincide
1037361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return ringerMode;
1038361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1039361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1040361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        private int indexToRingerMode(int index) {
1041361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            // They just happen to coincide
1042361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return index;
1043361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1044361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1045361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
1046361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public CharSequence getLabelForAccessibility(Context context) {
1047361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return null;
1048361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1049361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1050361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public View create(Context context, View convertView, ViewGroup parent,
1051361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                LayoutInflater inflater) {
1052361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            View v = inflater.inflate(R.layout.global_actions_silent_mode, parent, false);
1053361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1054361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            int selectedIndex = ringerModeToIndex(mAudioManager.getRingerMode());
1055361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            for (int i = 0; i < 3; i++) {
1056361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                View itemView = v.findViewById(ITEM_IDS[i]);
1057361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                itemView.setSelected(selectedIndex == i);
1058361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                // Set up click handler
1059361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                itemView.setTag(i);
1060361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                itemView.setOnClickListener(this);
1061361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
1062361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return v;
1063361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1064361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1065361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public void onPress() {
1066361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1067361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1068361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean showDuringKeyguard() {
1069361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return true;
1070361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1071361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1072361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean showBeforeProvisioning() {
1073361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return false;
1074361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1075361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1076361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean isEnabled() {
1077361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return true;
1078361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1079361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1080361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        void willCreate() {
1081361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1082361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1083361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public void onClick(View v) {
1084361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (!(v.getTag() instanceof Integer)) return;
1085361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1086361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            int index = (Integer) v.getTag();
1087361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mAudioManager.setRingerMode(indexToRingerMode(index));
1088361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mHandler.sendEmptyMessageDelayed(MESSAGE_DISMISS, DIALOG_DISMISS_DELAY);
1089361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1090361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
1091361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1092361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
1093361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public void onReceive(Context context, Intent intent) {
1094361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            String action = intent.getAction();
1095361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
1096361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    || Intent.ACTION_SCREEN_OFF.equals(action)) {
1097361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
1098361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                if (!SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS.equals(reason)) {
1099361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    mHandler.sendEmptyMessage(MESSAGE_DISMISS);
1100361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
1101361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            } else if (TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED.equals(action)) {
1102361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                // Airplane mode can be changed after ECM exits if airplane toggle button
1103361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                // is pressed during ECM mode
1104361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                if (!(intent.getBooleanExtra("PHONE_IN_ECM_STATE", false)) &&
1105361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        mIsWaitingForEcmExit) {
1106361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    mIsWaitingForEcmExit = false;
1107361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    changeAirplaneModeSystemSetting(true);
1108361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
1109361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
1110361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1111361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    };
1112361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1113361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
1114361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
1115361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public void onServiceStateChanged(ServiceState serviceState) {
1116361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (!mHasTelephony) return;
1117361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            final boolean inAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF;
1118361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mAirplaneState = inAirplaneMode ? ToggleAction.State.On : ToggleAction.State.Off;
1119361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mAirplaneModeOn.updateState(mAirplaneState);
1120361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mAdapter.notifyDataSetChanged();
1121361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1122361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    };
1123361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1124361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private BroadcastReceiver mRingerModeReceiver = new BroadcastReceiver() {
1125361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
1126361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public void onReceive(Context context, Intent intent) {
1127361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (intent.getAction().equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
1128361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mHandler.sendEmptyMessage(MESSAGE_REFRESH);
1129361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
1130361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1131361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    };
1132361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1133361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private ContentObserver mAirplaneModeObserver = new ContentObserver(new Handler()) {
1134361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
1135361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public void onChange(boolean selfChange) {
1136361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            onAirplaneModeChanged();
1137361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1138361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    };
1139361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1140361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final int MESSAGE_DISMISS = 0;
1141361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final int MESSAGE_REFRESH = 1;
1142361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final int MESSAGE_SHOW = 2;
1143361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final int DIALOG_DISMISS_DELAY = 300; // ms
1144361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1145361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private Handler mHandler = new Handler() {
1146361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public void handleMessage(Message msg) {
1147361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            switch (msg.what) {
1148361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            case MESSAGE_DISMISS:
1149361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                if (mDialog != null) {
1150361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    mDialog.dismiss();
1151361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    mDialog = null;
1152361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
1153361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                break;
1154361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            case MESSAGE_REFRESH:
1155361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                refreshSilentMode();
1156361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mAdapter.notifyDataSetChanged();
1157361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                break;
1158361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            case MESSAGE_SHOW:
1159361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                handleShow();
1160361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                break;
1161361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
1162361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1163361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    };
1164361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1165361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private void onAirplaneModeChanged() {
1166361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        // Let the service state callbacks handle the state.
1167361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        if (mHasTelephony) return;
1168361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1169361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        boolean airplaneModeOn = Settings.Global.getInt(
1170361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mContext.getContentResolver(),
1171361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                Settings.Global.AIRPLANE_MODE_ON,
1172361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                0) == 1;
1173361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mAirplaneState = airplaneModeOn ? ToggleAction.State.On : ToggleAction.State.Off;
1174361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mAirplaneModeOn.updateState(mAirplaneState);
1175361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
1176361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1177361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    /**
1178361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     * Change the airplane mode system setting
1179361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk     */
1180361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private void changeAirplaneModeSystemSetting(boolean on) {
1181361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        Settings.Global.putInt(
1182361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                mContext.getContentResolver(),
1183361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                Settings.Global.AIRPLANE_MODE_ON,
1184361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                on ? 1 : 0);
1185361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
1186361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
1187361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        intent.putExtra("state", on);
1188361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
1189361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        if (!mHasTelephony) {
1190361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mAirplaneState = on ? ToggleAction.State.On : ToggleAction.State.Off;
1191361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1192361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
1193361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1194361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    private static final class ActionsDialog extends Dialog implements DialogInterface {
1195361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        private final Context mContext;
1196361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        private final AlertController mAlert;
1197361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        private final MyAdapter mAdapter;
1198361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1199361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public ActionsDialog(Context context, AlertParams params) {
1200361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            super(context, getDialogTheme(context));
1201361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mContext = getContext();
1202361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mAlert = AlertController.create(mContext, this, getWindow());
1203361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mAdapter = (MyAdapter) params.mAdapter;
1204361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            params.apply(mAlert);
1205361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1206361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1207361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        private static int getDialogTheme(Context context) {
1208361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            TypedValue outValue = new TypedValue();
1209361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            context.getTheme().resolveAttribute(R.attr.alertDialogTheme,
1210361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    outValue, true);
1211361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return outValue.resourceId;
1212361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1213361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1214361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
1215361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        protected void onStart() {
1216361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            super.setCanceledOnTouchOutside(true);
1217361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            super.onStart();
1218361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1219361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1220361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public ListView getListView() {
1221361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return mAlert.getListView();
1222361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1223361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1224361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
1225361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        protected void onCreate(Bundle savedInstanceState) {
1226361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            super.onCreate(savedInstanceState);
1227361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            mAlert.installContent();
1228361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1229361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1230361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
1231361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
1232361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
1233361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                for (int i = 0; i < mAdapter.getCount(); ++i) {
1234361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    CharSequence label =
1235361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                            mAdapter.getItem(i).getLabelForAccessibility(getContext());
1236361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    if (label != null) {
1237361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                        event.getText().add(label);
1238361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                    }
1239361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                }
1240361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
1241361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return super.dispatchPopulateAccessibilityEvent(event);
1242361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1243361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1244361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
1245361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean onKeyDown(int keyCode, KeyEvent event) {
1246361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (mAlert.onKeyDown(keyCode, event)) {
1247361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return true;
1248361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
1249361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return super.onKeyDown(keyCode, event);
1250361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1251361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk
1252361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        @Override
1253361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        public boolean onKeyUp(int keyCode, KeyEvent event) {
1254361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            if (mAlert.onKeyUp(keyCode, event)) {
1255361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk                return true;
1256361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            }
1257361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk            return super.onKeyUp(keyCode, event);
1258361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk        }
1259361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk    }
1260361915c727fc2ad137bfeed7ff74b3eadde96597Jason Monk}
1261