11f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/*
21f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
31f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
41f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
51f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * you may not use this file except in compliance with the License.
61f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * You may obtain a copy of the License at
71f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
81f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
91f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project *
101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * See the License for the specific language governing permissions and
141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * limitations under the License.
151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */
161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
17b10e33ff804a831c71be9303146cea892b9aeb5dJorim Jaggipackage com.android.server.policy;
181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
197befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport com.android.internal.app.AlertController;
207befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport com.android.internal.app.AlertController.AlertParams;
21742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport com.android.internal.telephony.TelephonyIntents;
22742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport com.android.internal.telephony.TelephonyProperties;
23742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport com.android.internal.R;
24d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roosimport com.android.internal.widget.LockPatternUtils;
25742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
2698a881418a33dd4331ba864727d26c9fb0e2175fGuang Zhuimport android.app.ActivityManager;
27742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport android.app.ActivityManagerNative;
281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.app.AlertDialog;
297befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.app.Dialog;
301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.BroadcastReceiver;
311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Context;
321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.DialogInterface;
331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Intent;
341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.IntentFilter;
35742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport android.content.pm.UserInfo;
367ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasaniimport android.database.ContentObserver;
37b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasaniimport android.graphics.drawable.Drawable;
381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.media.AudioManager;
397ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasaniimport android.net.ConnectivityManager;
40887aa0024f2fe62f24555a6000f862df169f2d44John Spurlockimport android.os.Build;
417befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.os.Bundle;
421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.Handler;
431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.Message;
44742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport android.os.RemoteException;
45542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlockimport android.os.ServiceManager;
467befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.os.SystemClock;
47fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guoimport android.os.SystemProperties;
485ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackbornimport android.os.UserHandle;
49258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasaniimport android.os.UserManager;
50135936072b24b090fb63940aea41b408d855a4f3Amith Yamasaniimport android.os.Vibrator;
511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.provider.Settings;
52542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlockimport android.service.dreams.DreamService;
53542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlockimport android.service.dreams.IDreamManager;
541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.telephony.PhoneStateListener;
551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.telephony.ServiceState;
561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.telephony.TelephonyManager;
57887aa0024f2fe62f24555a6000f862df169f2d44John Spurlockimport android.text.TextUtils;
583b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Kohimport android.util.ArraySet;
591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.util.Log;
607befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.util.TypedValue;
617befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.view.InputDevice;
627befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.view.KeyEvent;
631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.LayoutInflater;
647befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.view.MotionEvent;
651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.View;
667befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.view.ViewConfiguration;
671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.ViewGroup;
681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.WindowManager;
69d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roosimport android.view.WindowManagerGlobal;
707304c343821309dd15f769b18f1de2fa43751573Jeff Brownimport android.view.WindowManagerPolicy.WindowManagerFuncs;
7130443b14d123535038e0e64bfa315214ac2d2e11Jason Monkimport android.view.accessibility.AccessibilityEvent;
7219caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackbornimport android.widget.AdapterView;
731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.BaseAdapter;
741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.ImageView;
75b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasaniimport android.widget.ImageView.ScaleType;
767befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.widget.ListView;
771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.TextView;
781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport java.util.ArrayList;
80742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport java.util.List;
811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/**
831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Helper to show the global actions dialog.  Each item is an {@link Action} that
841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * may show depending on whether the keyguard is showing, and whether the device
851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * is provisioned.
861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */
871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectclass GlobalActions implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener  {
881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static final String TAG = "GlobalActions";
901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
916243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private static final boolean SHOW_SILENT_TOGGLE = true;
922ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani
933b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh    /* Valid settings for global actions keys.
943b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh     * see config.xml config_globalActionList */
953b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh    private static final String GLOBAL_ACTION_KEY_POWER = "power";
963b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh    private static final String GLOBAL_ACTION_KEY_AIRPLANE = "airplane";
973b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh    private static final String GLOBAL_ACTION_KEY_BUGREPORT = "bugreport";
983b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh    private static final String GLOBAL_ACTION_KEY_SILENT = "silent";
993b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh    private static final String GLOBAL_ACTION_KEY_USERS = "users";
1003b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh    private static final String GLOBAL_ACTION_KEY_SETTINGS = "settings";
101d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos    private static final String GLOBAL_ACTION_KEY_LOCKDOWN = "lockdown";
102cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee    private static final String GLOBAL_ACTION_KEY_VOICEASSIST = "voiceassist";
1038326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee    private static final String GLOBAL_ACTION_KEY_ASSIST = "assist";
1043b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh
1051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final Context mContext;
1067304c343821309dd15f769b18f1de2fa43751573Jeff Brown    private final WindowManagerFuncs mWindowManagerFuncs;
1071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final AudioManager mAudioManager;
108542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock    private final IDreamManager mDreamManager;
1091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ArrayList<Action> mItems;
1117befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov    private GlobalActionsDialog mDialog;
1121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1137ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private Action mSilentModeAction;
1141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ToggleAction mAirplaneModeOn;
1151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private MyAdapter mAdapter;
1171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mKeyguardShowing = false;
1191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mDeviceProvisioned = false;
1201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ToggleAction.State mAirplaneState = ToggleAction.State.Off;
121fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    private boolean mIsWaitingForEcmExit = false;
1227ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private boolean mHasTelephony;
1237ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private boolean mHasVibrator;
12483a017b6b7c099d1a0293e5839be6477325aef06Eric Laurent    private final boolean mShowSilentToggle;
1251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @param context everything needs a context :(
1281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1297304c343821309dd15f769b18f1de2fa43751573Jeff Brown    public GlobalActions(Context context, WindowManagerFuncs windowManagerFuncs) {
1301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mContext = context;
1317304c343821309dd15f769b18f1de2fa43751573Jeff Brown        mWindowManagerFuncs = windowManagerFuncs;
1321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
133542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock        mDreamManager = IDreamManager.Stub.asInterface(
134542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock                ServiceManager.getService(DreamService.DREAM_SERVICE));
1351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // receive broadcasts
1371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        IntentFilter filter = new IntentFilter();
1381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
13978866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato        filter.addAction(Intent.ACTION_SCREEN_OFF);
140fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
1411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        context.registerReceiver(mBroadcastReceiver, filter);
1421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
143c3b7e6fd44593c3974e989d8ccf2097b4471b2b7nagarw        ConnectivityManager cm = (ConnectivityManager)
144c3b7e6fd44593c3974e989d8ccf2097b4471b2b7nagarw                context.getSystemService(Context.CONNECTIVITY_SERVICE);
145c3b7e6fd44593c3974e989d8ccf2097b4471b2b7nagarw        mHasTelephony = cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
146c3b7e6fd44593c3974e989d8ccf2097b4471b2b7nagarw
1471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // get notified of phone state changes
1481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        TelephonyManager telephonyManager =
1491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
1501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
1517ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        mContext.getContentResolver().registerContentObserver(
152c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate                Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
1537ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                mAirplaneModeObserver);
1547ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
1557ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        mHasVibrator = vibrator != null && vibrator.hasVibrator();
15683a017b6b7c099d1a0293e5839be6477325aef06Eric Laurent
15783a017b6b7c099d1a0293e5839be6477325aef06Eric Laurent        mShowSilentToggle = SHOW_SILENT_TOGGLE && !mContext.getResources().getBoolean(
15883a017b6b7c099d1a0293e5839be6477325aef06Eric Laurent                com.android.internal.R.bool.config_useFixedVolume);
1591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Show the global actions dialog (creating if necessary)
1631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @param keyguardShowing True if keyguard is showing
1641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) {
1661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mKeyguardShowing = keyguardShowing;
1671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mDeviceProvisioned = isDeviceProvisioned;
168742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        if (mDialog != null) {
169742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mDialog.dismiss();
1702efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            mDialog = null;
1712efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            // Show delayed, so that the dismiss of the previous dialog completes
1722efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            mHandler.sendEmptyMessage(MESSAGE_SHOW);
1732efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani        } else {
1742efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            handleShow();
1751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
1762efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani    }
1772efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani
178542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock    private void awakenIfNecessary() {
179542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock        if (mDreamManager != null) {
180542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock            try {
181542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock                if (mDreamManager.isDreaming()) {
182542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock                    mDreamManager.awaken();
183542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock                }
184542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock            } catch (RemoteException e) {
185542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock                // we tried
186542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock            }
187542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock        }
188542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock    }
189542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock
1902efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani    private void handleShow() {
191542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock        awakenIfNecessary();
192742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        mDialog = createDialog();
1931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        prepareDialog();
1941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1951c46c2d7848cb59a50341f7ff0867311d8b96b15Justin Koh        // If we only have 1 item and it's a simple press action, just do this action.
1961c46c2d7848cb59a50341f7ff0867311d8b96b15Justin Koh        if (mAdapter.getCount() == 1
197822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock                && mAdapter.getItem(0) instanceof SinglePressAction
198822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock                && !(mAdapter.getItem(0) instanceof LongPressAction)) {
1991c46c2d7848cb59a50341f7ff0867311d8b96b15Justin Koh            ((SinglePressAction) mAdapter.getItem(0)).onPress();
2001c46c2d7848cb59a50341f7ff0867311d8b96b15Justin Koh        } else {
2011c46c2d7848cb59a50341f7ff0867311d8b96b15Justin Koh            WindowManager.LayoutParams attrs = mDialog.getWindow().getAttributes();
2021c46c2d7848cb59a50341f7ff0867311d8b96b15Justin Koh            attrs.setTitle("GlobalActions");
2031c46c2d7848cb59a50341f7ff0867311d8b96b15Justin Koh            mDialog.getWindow().setAttributes(attrs);
2041c46c2d7848cb59a50341f7ff0867311d8b96b15Justin Koh            mDialog.show();
2051c46c2d7848cb59a50341f7ff0867311d8b96b15Justin Koh            mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);
2061c46c2d7848cb59a50341f7ff0867311d8b96b15Justin Koh        }
2071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
2087ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
2091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
2101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Create the global actions dialog.
2111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @return A new dialog.
2121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
2137befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov    private GlobalActionsDialog createDialog() {
2147ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        // Simple toggle style if there's no vibrator, otherwise use a tri-state
2157ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        if (!mHasVibrator) {
2167ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            mSilentModeAction = new SilentModeToggleAction();
2177ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        } else {
2187ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            mSilentModeAction = new SilentModeTriStateAction(mContext, mAudioManager, mHandler);
2197ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
2201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAirplaneModeOn = new ToggleAction(
2211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.drawable.ic_lock_airplane_mode,
2221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.drawable.ic_lock_airplane_mode_off,
2231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_actions_toggle_airplane_mode,
2241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_actions_airplane_mode_on_status,
2251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_actions_airplane_mode_off_status) {
2261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            void onToggle(boolean on) {
2287ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                if (mHasTelephony && Boolean.parseBoolean(
229fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                        SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
230fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mIsWaitingForEcmExit = true;
231fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    // Launch ECM exit dialog
232fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    Intent ecmDialogIntent =
233fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                            new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null);
234fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    ecmDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
235fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mContext.startActivity(ecmDialogIntent);
236fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                } else {
237fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    changeAirplaneModeSystemSetting(on);
238fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                }
2391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
2401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            @Override
2421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            protected void changeStateFromPress(boolean buttonOn) {
2437ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                if (!mHasTelephony) return;
2447ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
245fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // In ECM mode airplane state cannot be changed
246fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                if (!(Boolean.parseBoolean(
247fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                        SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)))) {
248fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mState = buttonOn ? State.TurningOn : State.TurningOff;
249fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mAirplaneState = mState;
250fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                }
2511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
2521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean showDuringKeyguard() {
2541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return true;
2551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
2561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean showBeforeProvisioning() {
2581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return false;
2591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
2601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        };
2617ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        onAirplaneModeChanged();
2621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2632ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani        mItems = new ArrayList<Action>();
2643b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh        String[] defaultActions = mContext.getResources().getStringArray(
2653b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                com.android.internal.R.array.config_globalActionsList);
2663b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh
2673b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh        ArraySet<String> addedKeys = new ArraySet<String>();
2683b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh        for (int i = 0; i < defaultActions.length; i++) {
2693b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            String actionKey = defaultActions[i];
2703b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            if (addedKeys.contains(actionKey)) {
2713b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                // If we already have added this, don't add it again.
2723b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                continue;
2733b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            }
2743b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            if (GLOBAL_ACTION_KEY_POWER.equals(actionKey)) {
275822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock                mItems.add(new PowerAction());
2763b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            } else if (GLOBAL_ACTION_KEY_AIRPLANE.equals(actionKey)) {
2773b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                mItems.add(mAirplaneModeOn);
27868539a664b6fc886ed467433cedd2fae291694deJohn Spurlock            } else if (GLOBAL_ACTION_KEY_BUGREPORT.equals(actionKey)) {
27968539a664b6fc886ed467433cedd2fae291694deJohn Spurlock                if (Settings.Global.getInt(mContext.getContentResolver(),
28068539a664b6fc886ed467433cedd2fae291694deJohn Spurlock                        Settings.Global.BUGREPORT_IN_POWER_MENU, 0) != 0 && isCurrentUserOwner()) {
28168539a664b6fc886ed467433cedd2fae291694deJohn Spurlock                    mItems.add(getBugReportAction());
28268539a664b6fc886ed467433cedd2fae291694deJohn Spurlock                }
28368539a664b6fc886ed467433cedd2fae291694deJohn Spurlock            } else if (GLOBAL_ACTION_KEY_SILENT.equals(actionKey)) {
28468539a664b6fc886ed467433cedd2fae291694deJohn Spurlock                if (mShowSilentToggle) {
28568539a664b6fc886ed467433cedd2fae291694deJohn Spurlock                    mItems.add(mSilentModeAction);
28668539a664b6fc886ed467433cedd2fae291694deJohn Spurlock                }
28768539a664b6fc886ed467433cedd2fae291694deJohn Spurlock            } else if (GLOBAL_ACTION_KEY_USERS.equals(actionKey)) {
28868539a664b6fc886ed467433cedd2fae291694deJohn Spurlock                if (SystemProperties.getBoolean("fw.power_user_switcher", false)) {
28968539a664b6fc886ed467433cedd2fae291694deJohn Spurlock                    addUsersToMenu(mItems);
29068539a664b6fc886ed467433cedd2fae291694deJohn Spurlock                }
2913b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            } else if (GLOBAL_ACTION_KEY_SETTINGS.equals(actionKey)) {
2923b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                mItems.add(getSettingsAction());
2934ebcdfdd4294cc52a68fb150bc7a34f005290ea3Adrian Roos            } else if (GLOBAL_ACTION_KEY_LOCKDOWN.equals(actionKey)) {
294d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos                mItems.add(getLockdownAction());
295cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee            } else if (GLOBAL_ACTION_KEY_VOICEASSIST.equals(actionKey)) {
296cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee                mItems.add(getVoiceAssistAction());
2978326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee            } else if (GLOBAL_ACTION_KEY_ASSIST.equals(actionKey)) {
2988326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee                mItems.add(getAssistAction());
2993b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            } else {
3003b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                Log.e(TAG, "Invalid global action key " + actionKey);
3013b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            }
3023b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            // Add here so we don't add more than one.
3033b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            addedKeys.add(actionKey);
304bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        }
305bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani
306bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        mAdapter = new MyAdapter();
307bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani
308bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        AlertParams params = new AlertParams(mContext);
309bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        params.mAdapter = mAdapter;
310bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        params.mOnClickListener = this;
311bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        params.mForceInverseBackground = true;
312bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani
313bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        GlobalActionsDialog dialog = new GlobalActionsDialog(mContext, params);
314bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
315bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani
316bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        dialog.getListView().setItemsCanFocus(true);
317bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        dialog.getListView().setLongClickable(true);
318bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        dialog.getListView().setOnItemLongClickListener(
319bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani                new AdapterView.OnItemLongClickListener() {
320bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani                    @Override
321bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani                    public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
322bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani                            long id) {
323822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock                        final Action action = mAdapter.getItem(position);
324822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock                        if (action instanceof LongPressAction) {
325822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock                            return ((LongPressAction) action).onLongPress();
326822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock                        }
327822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock                        return false;
328bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani                    }
329bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        });
330bef0f617a09e8c3b1567217bba65006c7364baedDianne Hackborn        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
331bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani
332bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        dialog.setOnDismissListener(this);
333bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani
334bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        return dialog;
335bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani    }
336bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani
337822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock    private final class PowerAction extends SinglePressAction implements LongPressAction {
338822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock        private PowerAction() {
339822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock            super(com.android.internal.R.drawable.ic_lock_power_off,
340822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock                R.string.global_action_power_off);
341822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock        }
3423b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh
343822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock        @Override
344822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock        public boolean onLongPress() {
345bff46bac807ae8a9ebdc22c449a8d4f78711b4d2Benjamin Franz            UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
346bff46bac807ae8a9ebdc22c449a8d4f78711b4d2Benjamin Franz            if (!um.hasUserRestriction(UserManager.DISALLOW_SAFE_BOOT)) {
347bff46bac807ae8a9ebdc22c449a8d4f78711b4d2Benjamin Franz                mWindowManagerFuncs.rebootSafeMode(true);
348bff46bac807ae8a9ebdc22c449a8d4f78711b4d2Benjamin Franz                return true;
349bff46bac807ae8a9ebdc22c449a8d4f78711b4d2Benjamin Franz            }
350bff46bac807ae8a9ebdc22c449a8d4f78711b4d2Benjamin Franz            return false;
351822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock        }
3523b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh
353822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock        @Override
354822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock        public boolean showDuringKeyguard() {
355822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock            return true;
356822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock        }
3573b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh
358822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock        @Override
359822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock        public boolean showBeforeProvisioning() {
360822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock            return true;
361822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock        }
3623b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh
363822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock        @Override
364822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock        public void onPress() {
365822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock            // shutdown by making sure radio and power are handled accordingly.
366822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock            mWindowManagerFuncs.shutdown(false /* confirm */);
367822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock        }
3683b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh    }
3693b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh
3703b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh    private Action getBugReportAction() {
371887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock        return new SinglePressAction(com.android.internal.R.drawable.ic_lock_bugreport,
372887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock                R.string.bugreport_title) {
3733b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh
3743b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            public void onPress() {
3753b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
3763b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                builder.setTitle(com.android.internal.R.string.bugreport_title);
3773b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                builder.setMessage(com.android.internal.R.string.bugreport_message);
3783b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                builder.setNegativeButton(com.android.internal.R.string.cancel, null);
3793b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                builder.setPositiveButton(com.android.internal.R.string.report,
3803b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                        new DialogInterface.OnClickListener() {
3813b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                            @Override
3823b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                            public void onClick(DialogInterface dialog, int which) {
38398a881418a33dd4331ba864727d26c9fb0e2175fGuang Zhu                                // don't actually trigger the bugreport if we are running stability
38498a881418a33dd4331ba864727d26c9fb0e2175fGuang Zhu                                // tests via monkey
38598a881418a33dd4331ba864727d26c9fb0e2175fGuang Zhu                                if (ActivityManager.isUserAMonkey()) {
38698a881418a33dd4331ba864727d26c9fb0e2175fGuang Zhu                                    return;
38798a881418a33dd4331ba864727d26c9fb0e2175fGuang Zhu                                }
3883b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                                // Add a little delay before executing, to give the
3893b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                                // dialog a chance to go away before it takes a
3903b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                                // screenshot.
3913b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                                mHandler.postDelayed(new Runnable() {
3923b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                                    @Override public void run() {
3933b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                                        try {
3943b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                                            ActivityManagerNative.getDefault()
3953b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                                                    .requestBugReport();
3963b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                                        } catch (RemoteException e) {
3973b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                                        }
3983b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                                    }
3993b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                                }, 500);
4003b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                            }
4013b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                        });
4023b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                AlertDialog dialog = builder.create();
4033b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
4043b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                dialog.show();
4053b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            }
4063b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh
4073b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            public boolean showDuringKeyguard() {
4083b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                return true;
4093b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            }
4103b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh
4113b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            public boolean showBeforeProvisioning() {
4123b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                return false;
4133b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            }
414887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock
415887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock            @Override
416887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock            public String getStatus() {
417887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock                return mContext.getString(
418887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock                        com.android.internal.R.string.bugreport_status,
419887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock                        Build.VERSION.RELEASE,
420887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock                        Build.ID);
421887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock            }
4223b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh        };
4233b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh    }
4243b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh
4253b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh    private Action getSettingsAction() {
4263b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh        return new SinglePressAction(com.android.internal.R.drawable.ic_settings,
4273b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                R.string.global_action_settings) {
4283b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh
4293b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            @Override
4303b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            public void onPress() {
4313b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                Intent intent = new Intent(Settings.ACTION_SETTINGS);
432636f3eac6d3ae69e7cc1dd159fe7cdbb043ce2dfWei Liu                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
4333b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                mContext.startActivity(intent);
4348326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee            }
4358326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee
4368326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee            @Override
4378326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee            public boolean showDuringKeyguard() {
4388326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee                return true;
4398326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee            }
4408326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee
4418326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee            @Override
4428326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee            public boolean showBeforeProvisioning() {
4438326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee                return true;
4448326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee            }
4458326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee        };
4468326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee    }
4478326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee
4488326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee    private Action getAssistAction() {
4498326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee        return new SinglePressAction(com.android.internal.R.drawable.ic_action_assist_focused,
4508326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee                R.string.global_action_assist) {
4518326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee            @Override
4528326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee            public void onPress() {
4538326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee                Intent intent = new Intent(Intent.ACTION_ASSIST);
4548326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
4558326554788c78f47d7b5f266a074fd2d24fb7fd0Bryce Lee                mContext.startActivity(intent);
4563b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            }
4573b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh
4583b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            @Override
4593b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            public boolean showDuringKeyguard() {
4603b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh                return true;
4613b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            }
4623b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh
4633b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            @Override
4643b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            public boolean showBeforeProvisioning() {
4651c46c2d7848cb59a50341f7ff0867311d8b96b15Justin Koh                return true;
4663b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh            }
4673b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh        };
4683b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh    }
4693b9a3cc02ecb025f8b1f322015c7d1fb46222f9eJustin Koh
470cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee    private Action getVoiceAssistAction() {
471cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee        return new SinglePressAction(com.android.internal.R.drawable.ic_voice_search,
472cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee                R.string.global_action_voice_assist) {
473cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee            @Override
474cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee            public void onPress() {
475cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee                Intent intent = new Intent(Intent.ACTION_VOICE_ASSIST);
476cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
477cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee                mContext.startActivity(intent);
478cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee            }
479cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee
480cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee            @Override
481cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee            public boolean showDuringKeyguard() {
482cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee                return true;
483cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee            }
484cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee
485cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee            @Override
486cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee            public boolean showBeforeProvisioning() {
487cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee                return true;
488cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee            }
489cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee        };
490cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee    }
491cc8b467c590170dd52e817dc1fd48ace83e6599eBryce Lee
492d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos    private Action getLockdownAction() {
493d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos        return new SinglePressAction(com.android.internal.R.drawable.ic_lock_lock,
494d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos                R.string.global_action_lockdown) {
495d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos
496d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos            @Override
497d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos            public void onPress() {
498d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos                new LockPatternUtils(mContext).requireCredentialEntry(UserHandle.USER_ALL);
499d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos                try {
500d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos                    WindowManagerGlobal.getWindowManagerService().lockNow(null);
501d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos                } catch (RemoteException e) {
502d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos                    Log.e(TAG, "Error while trying to lock device.", e);
503d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos                }
504d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos            }
505d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos
506d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos            @Override
507d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos            public boolean showDuringKeyguard() {
508d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos                return true;
509d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos            }
510d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos
511d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos            @Override
512d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos            public boolean showBeforeProvisioning() {
513d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos                return false;
514d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos            }
515d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos        };
516d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos    }
517d4d6136eb38e6380d4f1a0a0152f0d5707945562Adrian Roos
5183df2172215e2e0c5cd0c01eeb0d57191623b460eAmith Yamasani    private UserInfo getCurrentUser() {
5193df2172215e2e0c5cd0c01eeb0d57191623b460eAmith Yamasani        try {
5203df2172215e2e0c5cd0c01eeb0d57191623b460eAmith Yamasani            return ActivityManagerNative.getDefault().getCurrentUser();
5213df2172215e2e0c5cd0c01eeb0d57191623b460eAmith Yamasani        } catch (RemoteException re) {
5223df2172215e2e0c5cd0c01eeb0d57191623b460eAmith Yamasani            return null;
5233df2172215e2e0c5cd0c01eeb0d57191623b460eAmith Yamasani        }
5243df2172215e2e0c5cd0c01eeb0d57191623b460eAmith Yamasani    }
5253df2172215e2e0c5cd0c01eeb0d57191623b460eAmith Yamasani
5263df2172215e2e0c5cd0c01eeb0d57191623b460eAmith Yamasani    private boolean isCurrentUserOwner() {
5273df2172215e2e0c5cd0c01eeb0d57191623b460eAmith Yamasani        UserInfo currentUser = getCurrentUser();
5283df2172215e2e0c5cd0c01eeb0d57191623b460eAmith Yamasani        return currentUser == null || currentUser.isPrimary();
5293df2172215e2e0c5cd0c01eeb0d57191623b460eAmith Yamasani    }
5303df2172215e2e0c5cd0c01eeb0d57191623b460eAmith Yamasani
531bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani    private void addUsersToMenu(ArrayList<Action> items) {
5321a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy        UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
5331a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy        if (um.isUserSwitcherEnabled()) {
5341a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy            List<UserInfo> users = um.getUsers();
5353df2172215e2e0c5cd0c01eeb0d57191623b460eAmith Yamasani            UserInfo currentUser = getCurrentUser();
536742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            for (final UserInfo user : users) {
5371a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                if (user.supportsSwitchTo()) {
5381a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                    boolean isCurrentUser = currentUser == null
5391a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                            ? user.id == 0 : (currentUser.id == user.id);
5401a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                    Drawable icon = user.iconPath != null ? Drawable.createFromPath(user.iconPath)
5411a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                            : null;
5421a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                    SinglePressAction switchToUser = new SinglePressAction(
5431a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                            com.android.internal.R.drawable.ic_menu_cc, icon,
5441a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                            (user.name != null ? user.name : "Primary")
5451a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                            + (isCurrentUser ? " \u2714" : "")) {
5461a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                        public void onPress() {
5471a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                            try {
5481a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                                ActivityManagerNative.getDefault().switchUser(user.id);
5491a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                            } catch (RemoteException re) {
5501a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                                Log.e(TAG, "Couldn't switch user " + re);
5511a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                            }
552742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                        }
553742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
5541a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                        public boolean showDuringKeyguard() {
5551a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                            return true;
5561a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                        }
557742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
5581a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                        public boolean showBeforeProvisioning() {
5591a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                            return false;
5601a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                        }
5611a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                    };
5621a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                    items.add(switchToUser);
5631a447535cef7e3739d5f763dfe13e568568b9789Kenny Guy                }
564742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            }
565742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
5661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private void prepareDialog() {
5697ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        refreshSilentMode();
5701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAirplaneModeOn.updateState(mAirplaneState);
5711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAdapter.notifyDataSetChanged();
572bef0f617a09e8c3b1567217bba65006c7364baedDianne Hackborn        mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
57383a017b6b7c099d1a0293e5839be6477325aef06Eric Laurent        if (mShowSilentToggle) {
5746243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
5756243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mContext.registerReceiver(mRingerModeReceiver, filter);
5766243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
5771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5797ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private void refreshSilentMode() {
5807ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        if (!mHasVibrator) {
5817ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            final boolean silentModeOn =
5827ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
5837ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            ((ToggleAction)mSilentModeAction).updateState(
5847ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    silentModeOn ? ToggleAction.State.On : ToggleAction.State.Off);
5857ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
5867ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    }
5877ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
5881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /** {@inheritDoc} */
5891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void onDismiss(DialogInterface dialog) {
59083a017b6b7c099d1a0293e5839be6477325aef06Eric Laurent        if (mShowSilentToggle) {
5917d4adea7b4c5c27c53de9592a14193ea296873a1Masanori Ogino            try {
5927d4adea7b4c5c27c53de9592a14193ea296873a1Masanori Ogino                mContext.unregisterReceiver(mRingerModeReceiver);
5937d4adea7b4c5c27c53de9592a14193ea296873a1Masanori Ogino            } catch (IllegalArgumentException ie) {
5947d4adea7b4c5c27c53de9592a14193ea296873a1Masanori Ogino                // ignore this
5957d4adea7b4c5c27c53de9592a14193ea296873a1Masanori Ogino                Log.w(TAG, ie);
5967d4adea7b4c5c27c53de9592a14193ea296873a1Masanori Ogino            }
5976243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
5981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /** {@inheritDoc} */
6011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void onClick(DialogInterface dialog, int which) {
6027ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        if (!(mAdapter.getItem(which) instanceof SilentModeTriStateAction)) {
6036243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            dialog.dismiss();
6046243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
6051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAdapter.getItem(which).onPress();
6061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
6071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
6091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * The adapter used for the list within the global actions dialog, taking
6101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * into account whether the keyguard is showing via
6111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * {@link GlobalActions#mKeyguardShowing} and whether the device is provisioned
6121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * via {@link GlobalActions#mDeviceProvisioned}.
6131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
6141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private class MyAdapter extends BaseAdapter {
6151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public int getCount() {
6171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            int count = 0;
6181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            for (int i = 0; i < mItems.size(); i++) {
6201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                final Action action = mItems.get(i);
6211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mKeyguardShowing && !action.showDuringKeyguard()) {
6231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
6241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
6251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (!mDeviceProvisioned && !action.showBeforeProvisioning()) {
6261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
6271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
6281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                count++;
6291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
6301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return count;
6311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
6341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled(int position) {
6351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return getItem(position).isEnabled();
6361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
6391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean areAllItemsEnabled() {
6401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return false;
6411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public Action getItem(int position) {
6441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            int filteredPos = 0;
6461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            for (int i = 0; i < mItems.size(); i++) {
6471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                final Action action = mItems.get(i);
6481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mKeyguardShowing && !action.showDuringKeyguard()) {
6491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
6501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
6511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (!mDeviceProvisioned && !action.showBeforeProvisioning()) {
6521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
6531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
6541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (filteredPos == position) {
6551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    return action;
6561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
6571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                filteredPos++;
6581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
6591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
660c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer            throw new IllegalArgumentException("position " + position
661c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer                    + " out of range of showable actions"
662c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer                    + ", filtered count=" + getCount()
663c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer                    + ", keyguardshowing=" + mKeyguardShowing
6641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    + ", provisioned=" + mDeviceProvisioned);
6651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public long getItemId(int position) {
6691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return position;
6701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View getView(int position, View convertView, ViewGroup parent) {
6731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            Action action = getItem(position);
6741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
6751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
6771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // note: the scheme below made more sense when we were planning on having
6791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // 8 different things in the global actions dialog.  seems overkill with
6801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // only 3 items now, but may as well keep this flexible approach so it will
6811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // be easy should someone decide at the last minute to include something
6821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // else, such as 'enable wifi', or 'enable bluetooth'
6831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
6851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * What each item in the global actions dialog must be able to support.
6861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
6871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private interface Action {
68830443b14d123535038e0e64bfa315214ac2d2e11Jason Monk        /**
68930443b14d123535038e0e64bfa315214ac2d2e11Jason Monk         * @return Text that will be announced when dialog is created.  null
69030443b14d123535038e0e64bfa315214ac2d2e11Jason Monk         *     for none.
69130443b14d123535038e0e64bfa315214ac2d2e11Jason Monk         */
69230443b14d123535038e0e64bfa315214ac2d2e11Jason Monk        CharSequence getLabelForAccessibility(Context context);
69330443b14d123535038e0e64bfa315214ac2d2e11Jason Monk
6941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        View create(Context context, View convertView, ViewGroup parent, LayoutInflater inflater);
6951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        void onPress();
6971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
6991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @return whether this action should appear in the dialog when the keygaurd
7001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         *    is showing.
7011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
7021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean showDuringKeyguard();
7031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
7051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @return whether this action should appear in the dialog before the
7061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         *   device is provisioned.
7071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
7081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean showBeforeProvisioning();
7091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean isEnabled();
7111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
7121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
714822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock     * An action that also supports long press.
715822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock     */
716822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock    private interface LongPressAction extends Action {
717822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock        boolean onLongPress();
718822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock    }
719822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock
720822e5cc4823a09727833eb984e3982dcd98e4d99John Spurlock    /**
7211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * A single press action maintains no state, just responds to a press
7221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * and takes an action.
7231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
7241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static abstract class SinglePressAction implements Action {
7251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        private final int mIconResId;
726b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani        private final Drawable mIcon;
7271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        private final int mMessageResId;
728742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        private final CharSequence mMessage;
7291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected SinglePressAction(int iconResId, int messageResId) {
7311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mIconResId = iconResId;
7321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mMessageResId = messageResId;
733742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mMessage = null;
734b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            mIcon = null;
735b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani        }
736b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani
737b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani        protected SinglePressAction(int iconResId, Drawable icon, CharSequence message) {
738b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            mIconResId = iconResId;
739b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            mMessageResId = 0;
740b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            mMessage = message;
741b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            mIcon = icon;
7421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
7431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
744742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        protected SinglePressAction(int iconResId, CharSequence message) {
745742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mIconResId = iconResId;
746742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mMessageResId = 0;
747742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mMessage = message;
748b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            mIcon = null;
749742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
750b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani
7511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled() {
7521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return true;
7531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
7541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
755887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock        public String getStatus() {
756887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock            return null;
757887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock        }
758887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock
7591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        abstract public void onPress();
7601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
76130443b14d123535038e0e64bfa315214ac2d2e11Jason Monk        public CharSequence getLabelForAccessibility(Context context) {
76230443b14d123535038e0e64bfa315214ac2d2e11Jason Monk            if (mMessage != null) {
76330443b14d123535038e0e64bfa315214ac2d2e11Jason Monk                return mMessage;
76430443b14d123535038e0e64bfa315214ac2d2e11Jason Monk            } else {
76530443b14d123535038e0e64bfa315214ac2d2e11Jason Monk                return context.getString(mMessageResId);
76630443b14d123535038e0e64bfa315214ac2d2e11Jason Monk            }
76730443b14d123535038e0e64bfa315214ac2d2e11Jason Monk        }
76830443b14d123535038e0e64bfa315214ac2d2e11Jason Monk
7691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View create(
7701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
7716243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            View v = inflater.inflate(R.layout.global_actions_item, parent, false);
7721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            ImageView icon = (ImageView) v.findViewById(R.id.icon);
7741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TextView messageView = (TextView) v.findViewById(R.id.message);
7751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
776887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock            TextView statusView = (TextView) v.findViewById(R.id.status);
777887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock            final String status = getStatus();
778887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock            if (!TextUtils.isEmpty(status)) {
779887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock                statusView.setText(status);
780887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock            } else {
781887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock                statusView.setVisibility(View.GONE);
782887aa0024f2fe62f24555a6000f862df169f2d44John Spurlock            }
783b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            if (mIcon != null) {
784b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani                icon.setImageDrawable(mIcon);
785b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani                icon.setScaleType(ScaleType.CENTER_CROP);
786b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            } else if (mIconResId != 0) {
7878eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette                icon.setImageDrawable(context.getDrawable(mIconResId));
788b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            }
789742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            if (mMessage != null) {
790742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                messageView.setText(mMessage);
791742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            } else {
792742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                messageView.setText(mMessageResId);
793742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            }
7941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return v;
7961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
7971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
7981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
8001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * A toggle action knows whether it is on or off, and displays an icon
8011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * and status message accordingly.
8021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
8031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static abstract class ToggleAction implements Action {
8041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        enum State {
8061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            Off(false),
8071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TurningOn(true),
8081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TurningOff(true),
8091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            On(false);
8101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            private final boolean inTransition;
8121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            State(boolean intermediate) {
8141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                inTransition = intermediate;
8151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
8161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean inTransition() {
8181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return inTransition;
8191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
8201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
8211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected State mState = State.Off;
8231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // prefs
82582d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mEnabledIconResId;
82682d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mDisabledIconResid;
82782d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mMessageResId;
82882d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mEnabledStatusMessageResId;
82982d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mDisabledStatusMessageResId;
8301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
8321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param enabledIconResId The icon for when this action is on.
8331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param disabledIconResid The icon for when this action is off.
8341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param essage The general information message, e.g 'Silent Mode'
8351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param enabledStatusMessageResId The on status message, e.g 'sound disabled'
8361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param disabledStatusMessageResId The off status message, e.g. 'sound enabled'
8371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
8381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public ToggleAction(int enabledIconResId,
8391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int disabledIconResid,
8407ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                int message,
8411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int enabledStatusMessageResId,
8421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int disabledStatusMessageResId) {
8431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mEnabledIconResId = enabledIconResId;
8441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDisabledIconResid = disabledIconResid;
8457ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            mMessageResId = message;
8461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mEnabledStatusMessageResId = enabledStatusMessageResId;
8471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDisabledStatusMessageResId = disabledStatusMessageResId;
8481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
8491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
85082d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        /**
85182d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         * Override to make changes to resource IDs just before creating the
85282d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         * View.
85382d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         */
85482d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        void willCreate() {
85582d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
85682d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        }
85782d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
85830443b14d123535038e0e64bfa315214ac2d2e11Jason Monk        @Override
85930443b14d123535038e0e64bfa315214ac2d2e11Jason Monk        public CharSequence getLabelForAccessibility(Context context) {
86030443b14d123535038e0e64bfa315214ac2d2e11Jason Monk            return context.getString(mMessageResId);
86130443b14d123535038e0e64bfa315214ac2d2e11Jason Monk        }
86230443b14d123535038e0e64bfa315214ac2d2e11Jason Monk
8631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View create(Context context, View convertView, ViewGroup parent,
8641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                LayoutInflater inflater) {
86582d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler            willCreate();
86682d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
8676243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            View v = inflater.inflate(R
8681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                            .layout.global_actions_item, parent, false);
8691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            ImageView icon = (ImageView) v.findViewById(R.id.icon);
8711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TextView messageView = (TextView) v.findViewById(R.id.message);
8721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TextView statusView = (TextView) v.findViewById(R.id.status);
8736243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            final boolean enabled = isEnabled();
8741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8756243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (messageView != null) {
8766243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                messageView.setText(mMessageResId);
8776243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                messageView.setEnabled(enabled);
8786243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
8791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            boolean on = ((mState == State.On) || (mState == State.TurningOn));
8816243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (icon != null) {
8828eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette                icon.setImageDrawable(context.getDrawable(
8836243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                        (on ? mEnabledIconResId : mDisabledIconResid)));
8846243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                icon.setEnabled(enabled);
8856243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
8861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8876243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (statusView != null) {
8886243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                statusView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId);
8896243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                statusView.setVisibility(View.VISIBLE);
8906243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                statusView.setEnabled(enabled);
8916243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
8921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            v.setEnabled(enabled);
8931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return v;
8951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
8961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public final void onPress() {
8981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (mState.inTransition()) {
8991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                Log.w(TAG, "shouldn't be able to toggle when in transition");
9001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return;
9011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
9021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            final boolean nowOn = !(mState == State.On);
9041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            onToggle(nowOn);
9051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            changeStateFromPress(nowOn);
9061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
9071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled() {
9091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return !mState.inTransition();
9101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
9111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
9131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * Implementations may override this if their state can be in on of the intermediate
9141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * states until some notification is received (e.g airplane mode is 'turning off' until
9151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * we know the wireless connections are back online
9161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param buttonOn Whether the button was turned on or off
9171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
9181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected void changeStateFromPress(boolean buttonOn) {
9191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mState = buttonOn ? State.On : State.Off;
9201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
9211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        abstract void onToggle(boolean on);
9231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void updateState(State state) {
9251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mState = state;
9261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
9271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
9281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
9297ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private class SilentModeToggleAction extends ToggleAction {
9307ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        public SilentModeToggleAction() {
9317ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            super(R.drawable.ic_audio_vol_mute,
9327ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    R.drawable.ic_audio_vol,
9337ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    R.string.global_action_toggle_silent_mode,
9347ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    R.string.global_action_silent_mode_on_status,
9357ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    R.string.global_action_silent_mode_off_status);
9367ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
9377ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
9387ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        void onToggle(boolean on) {
9397ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            if (on) {
9407ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
9417ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            } else {
9427ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
9437ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            }
9447ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
9457ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
9467ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        public boolean showDuringKeyguard() {
9477ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            return true;
9487ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
9497ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
9507ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        public boolean showBeforeProvisioning() {
9517ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            return false;
9527ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
9537ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    }
9547ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
9557ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private static class SilentModeTriStateAction implements Action, View.OnClickListener {
9566243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
9576243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private final int[] ITEM_IDS = { R.id.option1, R.id.option2, R.id.option3 };
9586243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
9596243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private final AudioManager mAudioManager;
9606243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private final Handler mHandler;
961135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        private final Context mContext;
9626243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
9637ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        SilentModeTriStateAction(Context context, AudioManager audioManager, Handler handler) {
9646243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mAudioManager = audioManager;
9656243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mHandler = handler;
966135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            mContext = context;
9676243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
9686243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
9696243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private int ringerModeToIndex(int ringerMode) {
9706243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            // They just happen to coincide
9716243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return ringerMode;
9726243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
9736243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
9746243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private int indexToRingerMode(int index) {
9756243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            // They just happen to coincide
9766243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return index;
9776243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
9786243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
97930443b14d123535038e0e64bfa315214ac2d2e11Jason Monk        @Override
98030443b14d123535038e0e64bfa315214ac2d2e11Jason Monk        public CharSequence getLabelForAccessibility(Context context) {
98130443b14d123535038e0e64bfa315214ac2d2e11Jason Monk            return null;
98230443b14d123535038e0e64bfa315214ac2d2e11Jason Monk        }
98330443b14d123535038e0e64bfa315214ac2d2e11Jason Monk
9846243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public View create(Context context, View convertView, ViewGroup parent,
9856243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                LayoutInflater inflater) {
9866243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            View v = inflater.inflate(R.layout.global_actions_silent_mode, parent, false);
9876243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
9886243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            int selectedIndex = ringerModeToIndex(mAudioManager.getRingerMode());
9896243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            for (int i = 0; i < 3; i++) {
9906243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                View itemView = v.findViewById(ITEM_IDS[i]);
9916243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                itemView.setSelected(selectedIndex == i);
9926243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                // Set up click handler
9936243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                itemView.setTag(i);
9946243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                itemView.setOnClickListener(this);
9956243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
9966243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return v;
9976243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
9986243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
9996243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public void onPress() {
10006243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
10016243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
10026243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public boolean showDuringKeyguard() {
10036243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return true;
10046243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
10056243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
10066243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public boolean showBeforeProvisioning() {
10076243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return false;
10086243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
10096243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
10106243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public boolean isEnabled() {
10116243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return true;
10126243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
10136243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
10146243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        void willCreate() {
10156243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
10166243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
10176243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public void onClick(View v) {
10186243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (!(v.getTag() instanceof Integer)) return;
10196243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
10206243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            int index = (Integer) v.getTag();
10216243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mAudioManager.setRingerMode(indexToRingerMode(index));
10226243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mHandler.sendEmptyMessageDelayed(MESSAGE_DISMISS, DIALOG_DISMISS_DELAY);
10236243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
10246243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    }
10256243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
10261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
10271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void onReceive(Context context, Intent intent) {
10281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            String action = intent.getAction();
102978866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
103078866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato                    || Intent.ACTION_SCREEN_OFF.equals(action)) {
10311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                String reason = intent.getStringExtra(PhoneWindowManager.SYSTEM_DIALOG_REASON_KEY);
103278866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato                if (!PhoneWindowManager.SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS.equals(reason)) {
10331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mHandler.sendEmptyMessage(MESSAGE_DISMISS);
10341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
1035fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo            } else if (TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED.equals(action)) {
1036fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // Airplane mode can be changed after ECM exits if airplane toggle button
1037fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // is pressed during ECM mode
1038fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                if (!(intent.getBooleanExtra("PHONE_IN_ECM_STATE", false)) &&
1039fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                        mIsWaitingForEcmExit) {
1040fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mIsWaitingForEcmExit = false;
1041fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    changeAirplaneModeSystemSetting(true);
1042fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                }
10431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
10441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
10451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
10461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
10471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
10481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
10491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void onServiceStateChanged(ServiceState serviceState) {
10507ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            if (!mHasTelephony) return;
10511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            final boolean inAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF;
10521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAirplaneState = inAirplaneMode ? ToggleAction.State.On : ToggleAction.State.Off;
10531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAirplaneModeOn.updateState(mAirplaneState);
10541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAdapter.notifyDataSetChanged();
10551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
10561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
10571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
10586243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private BroadcastReceiver mRingerModeReceiver = new BroadcastReceiver() {
10596243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        @Override
10606243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public void onReceive(Context context, Intent intent) {
10616243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (intent.getAction().equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
10626243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                mHandler.sendEmptyMessage(MESSAGE_REFRESH);
10636243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
10646243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
10656243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    };
10666243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
10677ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private ContentObserver mAirplaneModeObserver = new ContentObserver(new Handler()) {
10687ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        @Override
10697ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        public void onChange(boolean selfChange) {
10707ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            onAirplaneModeChanged();
10717ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
10727ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    };
10737ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
10741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static final int MESSAGE_DISMISS = 0;
10756243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private static final int MESSAGE_REFRESH = 1;
10762efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani    private static final int MESSAGE_SHOW = 2;
10776243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private static final int DIALOG_DISMISS_DELAY = 300; // ms
10786243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
10791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private Handler mHandler = new Handler() {
10801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void handleMessage(Message msg) {
10812efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            switch (msg.what) {
10822efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            case MESSAGE_DISMISS:
10831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mDialog != null) {
10841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mDialog.dismiss();
1085ae15594549427e18825071edc60fc63f144ba585Henrik Baard                    mDialog = null;
10861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
10872efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani                break;
10882efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            case MESSAGE_REFRESH:
10897ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                refreshSilentMode();
10906243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                mAdapter.notifyDataSetChanged();
10912efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani                break;
10922efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            case MESSAGE_SHOW:
10932efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani                handleShow();
10942efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani                break;
10951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
10961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
10971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
1098fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo
10997ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private void onAirplaneModeChanged() {
11007ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        // Let the service state callbacks handle the state.
11017ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        if (mHasTelephony) return;
11027ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
1103c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate        boolean airplaneModeOn = Settings.Global.getInt(
11047ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                mContext.getContentResolver(),
1105c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate                Settings.Global.AIRPLANE_MODE_ON,
11067ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                0) == 1;
11077ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        mAirplaneState = airplaneModeOn ? ToggleAction.State.On : ToggleAction.State.Off;
11087ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        mAirplaneModeOn.updateState(mAirplaneState);
11097ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    }
11107ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
1111fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    /**
1112fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo     * Change the airplane mode system setting
1113fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo     */
1114fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    private void changeAirplaneModeSystemSetting(boolean on) {
1115c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate        Settings.Global.putInt(
1116fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                mContext.getContentResolver(),
1117c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate                Settings.Global.AIRPLANE_MODE_ON,
1118fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                on ? 1 : 0);
1119fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
1120818ba11cd680de336fb9278b64a21dc2efb7517eDianne Hackborn        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
1121fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        intent.putExtra("state", on);
11225ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
11237ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        if (!mHasTelephony) {
11247ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            mAirplaneState = on ? ToggleAction.State.On : ToggleAction.State.Off;
11257ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
1126fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    }
11277befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
11287befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov    private static final class GlobalActionsDialog extends Dialog implements DialogInterface {
11297befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        private final Context mContext;
11307befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        private final int mWindowTouchSlop;
11317befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        private final AlertController mAlert;
113230443b14d123535038e0e64bfa315214ac2d2e11Jason Monk        private final MyAdapter mAdapter;
11337befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
11347befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        private EnableAccessibilityController mEnableAccessibilityController;
11357befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
11367befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        private boolean mIntercepted;
11377befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        private boolean mCancelOnUp;
11387befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
11397befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        public GlobalActionsDialog(Context context, AlertParams params) {
11407befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            super(context, getDialogTheme(context));
1141e54d245b993e1347cb32c23a6bdc907a45fab324Alan Viverette            mContext = getContext();
11427befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            mAlert = new AlertController(mContext, this, getWindow());
114330443b14d123535038e0e64bfa315214ac2d2e11Jason Monk            mAdapter = (MyAdapter) params.mAdapter;
11447befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            mWindowTouchSlop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
11457befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            params.apply(mAlert);
11467befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
11477befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
11487befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        private static int getDialogTheme(Context context) {
11497befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            TypedValue outValue = new TypedValue();
11507befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            context.getTheme().resolveAttribute(com.android.internal.R.attr.alertDialogTheme,
11517befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    outValue, true);
11527befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            return outValue.resourceId;
11537befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
11547befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
11557befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        @Override
11567befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        protected void onStart() {
11577befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            // If global accessibility gesture can be performed, we will take care
11587befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            // of dismissing the dialog on touch outside. This is because the dialog
11597befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            // is dismissed on the first down while the global gesture is a long press
11607befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            // with two fingers anywhere on the screen.
11617befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            if (EnableAccessibilityController.canEnableAccessibilityViaGesture(mContext)) {
1162dc6d1a9cc3a23c26c786a732e729fdd418b57d29Svetoslav                mEnableAccessibilityController = new EnableAccessibilityController(mContext,
1163dc6d1a9cc3a23c26c786a732e729fdd418b57d29Svetoslav                        new Runnable() {
1164dc6d1a9cc3a23c26c786a732e729fdd418b57d29Svetoslav                    @Override
1165dc6d1a9cc3a23c26c786a732e729fdd418b57d29Svetoslav                    public void run() {
1166dc6d1a9cc3a23c26c786a732e729fdd418b57d29Svetoslav                        dismiss();
1167dc6d1a9cc3a23c26c786a732e729fdd418b57d29Svetoslav                    }
1168dc6d1a9cc3a23c26c786a732e729fdd418b57d29Svetoslav                });
11697befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                super.setCanceledOnTouchOutside(false);
11707befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            } else {
11717befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                mEnableAccessibilityController = null;
11727befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                super.setCanceledOnTouchOutside(true);
11737befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            }
11741c46c2d7848cb59a50341f7ff0867311d8b96b15Justin Koh
11757befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            super.onStart();
11767befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
11777befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
11787befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        @Override
11797befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        protected void onStop() {
11807befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            if (mEnableAccessibilityController != null) {
11817befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                mEnableAccessibilityController.onDestroy();
11827befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            }
11837befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            super.onStop();
11847befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
11857befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
11867befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        @Override
11877befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        public boolean dispatchTouchEvent(MotionEvent event) {
11887befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            if (mEnableAccessibilityController != null) {
11897befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                final int action = event.getActionMasked();
11907befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                if (action == MotionEvent.ACTION_DOWN) {
11917befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    View decor = getWindow().getDecorView();
11927befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    final int eventX = (int) event.getX();
11937befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    final int eventY = (int) event.getY();
11947befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    if (eventX < -mWindowTouchSlop
11957befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            || eventY < -mWindowTouchSlop
11967befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            || eventX >= decor.getWidth() + mWindowTouchSlop
11977befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            || eventY >= decor.getHeight() + mWindowTouchSlop) {
11987befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        mCancelOnUp = true;
11997befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    }
12007befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                }
12017befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                try {
12027befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    if (!mIntercepted) {
12037befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        mIntercepted = mEnableAccessibilityController.onInterceptTouchEvent(event);
12047befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        if (mIntercepted) {
12057befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            final long now = SystemClock.uptimeMillis();
12067befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            event = MotionEvent.obtain(now, now,
12077befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                                    MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
12087befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
12097befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            mCancelOnUp = true;
12107befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        }
12117befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    } else {
12127befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        return mEnableAccessibilityController.onTouchEvent(event);
12137befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    }
12147befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                } finally {
12157befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    if (action == MotionEvent.ACTION_UP) {
12167befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        if (mCancelOnUp) {
12177befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            cancel();
12187befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        }
12197befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        mCancelOnUp = false;
12207befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        mIntercepted = false;
12217befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    }
12227befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                }
12237befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            }
12247befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            return super.dispatchTouchEvent(event);
12257befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
12267befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
12277befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        public ListView getListView() {
12287befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            return mAlert.getListView();
12297befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
12307befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
12317befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        @Override
12327befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        protected void onCreate(Bundle savedInstanceState) {
12337befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            super.onCreate(savedInstanceState);
12347befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            mAlert.installContent();
12357befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
12367befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
12377befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        @Override
123830443b14d123535038e0e64bfa315214ac2d2e11Jason Monk        public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
123930443b14d123535038e0e64bfa315214ac2d2e11Jason Monk            if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
124030443b14d123535038e0e64bfa315214ac2d2e11Jason Monk                for (int i = 0; i < mAdapter.getCount(); ++i) {
124130443b14d123535038e0e64bfa315214ac2d2e11Jason Monk                    CharSequence label =
124230443b14d123535038e0e64bfa315214ac2d2e11Jason Monk                            mAdapter.getItem(i).getLabelForAccessibility(getContext());
124330443b14d123535038e0e64bfa315214ac2d2e11Jason Monk                    if (label != null) {
124430443b14d123535038e0e64bfa315214ac2d2e11Jason Monk                        event.getText().add(label);
124530443b14d123535038e0e64bfa315214ac2d2e11Jason Monk                    }
124630443b14d123535038e0e64bfa315214ac2d2e11Jason Monk                }
124730443b14d123535038e0e64bfa315214ac2d2e11Jason Monk            }
124830443b14d123535038e0e64bfa315214ac2d2e11Jason Monk            return super.dispatchPopulateAccessibilityEvent(event);
124930443b14d123535038e0e64bfa315214ac2d2e11Jason Monk        }
125030443b14d123535038e0e64bfa315214ac2d2e11Jason Monk
125130443b14d123535038e0e64bfa315214ac2d2e11Jason Monk        @Override
12527befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        public boolean onKeyDown(int keyCode, KeyEvent event) {
12537befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            if (mAlert.onKeyDown(keyCode, event)) {
12547befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                return true;
12557befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            }
12567befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            return super.onKeyDown(keyCode, event);
12577befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
12587befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
12597befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        @Override
12607befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        public boolean onKeyUp(int keyCode, KeyEvent event) {
12617befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            if (mAlert.onKeyUp(keyCode, event)) {
12627befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                return true;
12637befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            }
12647befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            return super.onKeyUp(keyCode, event);
12657befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
12667befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov    }
12671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project}
1268