GlobalActions.java revision 912133a4966e0eed9a72b208e2aa650dc538b328
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
171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectpackage com.android.internal.policy.impl;
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;
24742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
25742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport android.app.ActivityManagerNative;
261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.app.AlertDialog;
277befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.app.Dialog;
281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.BroadcastReceiver;
291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Context;
301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.DialogInterface;
311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Intent;
321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.IntentFilter;
33742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport android.content.pm.UserInfo;
347ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasaniimport android.database.ContentObserver;
35b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasaniimport android.graphics.drawable.Drawable;
361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.media.AudioManager;
377ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasaniimport android.net.ConnectivityManager;
387befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.os.Bundle;
391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.Handler;
401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.Message;
41742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport android.os.RemoteException;
42542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlockimport android.os.ServiceManager;
437befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.os.SystemClock;
44fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guoimport android.os.SystemProperties;
455ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackbornimport android.os.UserHandle;
46258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasaniimport android.os.UserManager;
47135936072b24b090fb63940aea41b408d855a4f3Amith Yamasaniimport android.os.Vibrator;
481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.provider.Settings;
49542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlockimport android.service.dreams.DreamService;
50542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlockimport android.service.dreams.IDreamManager;
511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.telephony.PhoneStateListener;
521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.telephony.ServiceState;
531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.telephony.TelephonyManager;
541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.util.Log;
557befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.util.TypedValue;
567befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.view.InputDevice;
577befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.view.KeyEvent;
581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.LayoutInflater;
597befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.view.MotionEvent;
601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.View;
617befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.view.ViewConfiguration;
621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.ViewGroup;
631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.WindowManager;
647304c343821309dd15f769b18f1de2fa43751573Jeff Brownimport android.view.WindowManagerPolicy.WindowManagerFuncs;
6519caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackbornimport android.widget.AdapterView;
661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.BaseAdapter;
671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.ImageView;
68b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasaniimport android.widget.ImageView.ScaleType;
697befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganovimport android.widget.ListView;
701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.TextView;
711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport java.util.ArrayList;
73742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport java.util.List;
741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/**
761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Helper to show the global actions dialog.  Each item is an {@link Action} that
771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * may show depending on whether the keyguard is showing, and whether the device
781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * is provisioned.
791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */
801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectclass GlobalActions implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener  {
811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static final String TAG = "GlobalActions";
831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
846243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private static final boolean SHOW_SILENT_TOGGLE = true;
852ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani
861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final Context mContext;
877304c343821309dd15f769b18f1de2fa43751573Jeff Brown    private final WindowManagerFuncs mWindowManagerFuncs;
881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final AudioManager mAudioManager;
89542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock    private final IDreamManager mDreamManager;
901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ArrayList<Action> mItems;
927befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov    private GlobalActionsDialog mDialog;
931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
947ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private Action mSilentModeAction;
951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ToggleAction mAirplaneModeOn;
961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private MyAdapter mAdapter;
981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mKeyguardShowing = false;
1001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mDeviceProvisioned = false;
1011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ToggleAction.State mAirplaneState = ToggleAction.State.Off;
102fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    private boolean mIsWaitingForEcmExit = false;
1037ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private boolean mHasTelephony;
1047ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private boolean mHasVibrator;
1051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @param context everything needs a context :(
1081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1097304c343821309dd15f769b18f1de2fa43751573Jeff Brown    public GlobalActions(Context context, WindowManagerFuncs windowManagerFuncs) {
1101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mContext = context;
1117304c343821309dd15f769b18f1de2fa43751573Jeff Brown        mWindowManagerFuncs = windowManagerFuncs;
1121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
113542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock        mDreamManager = IDreamManager.Stub.asInterface(
114542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock                ServiceManager.getService(DreamService.DREAM_SERVICE));
1151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // receive broadcasts
1171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        IntentFilter filter = new IntentFilter();
1181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
11978866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato        filter.addAction(Intent.ACTION_SCREEN_OFF);
120fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
1211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        context.registerReceiver(mBroadcastReceiver, filter);
1221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // get notified of phone state changes
1241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        TelephonyManager telephonyManager =
1251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
1261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
1277ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        ConnectivityManager cm = (ConnectivityManager)
1287ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                context.getSystemService(Context.CONNECTIVITY_SERVICE);
1297ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        mHasTelephony = cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
1307ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        mContext.getContentResolver().registerContentObserver(
131c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate                Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
1327ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                mAirplaneModeObserver);
1337ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
1347ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        mHasVibrator = vibrator != null && vibrator.hasVibrator();
1351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Show the global actions dialog (creating if necessary)
1391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @param keyguardShowing True if keyguard is showing
1401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) {
1421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mKeyguardShowing = keyguardShowing;
1431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mDeviceProvisioned = isDeviceProvisioned;
144742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        if (mDialog != null) {
145742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mDialog.dismiss();
1462efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            mDialog = null;
1472efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            // Show delayed, so that the dismiss of the previous dialog completes
1482efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            mHandler.sendEmptyMessage(MESSAGE_SHOW);
1492efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani        } else {
1502efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            handleShow();
1511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
1522efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani    }
1532efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani
154542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock    private void awakenIfNecessary() {
155542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock        if (mDreamManager != null) {
156542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock            try {
157542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock                if (mDreamManager.isDreaming()) {
158542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock                    mDreamManager.awaken();
159542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock                }
160542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock            } catch (RemoteException e) {
161542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock                // we tried
162542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock            }
163542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock        }
164542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock    }
165542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock
1662efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani    private void handleShow() {
167542a51cc791613319386f53f51ea3676e6c9208eJohn Spurlock        awakenIfNecessary();
168742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        mDialog = createDialog();
1691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        prepareDialog();
1701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1715fe7e2a3043d6a8ca933c77ccf95c791b57b221aDianne Hackborn        WindowManager.LayoutParams attrs = mDialog.getWindow().getAttributes();
1725fe7e2a3043d6a8ca933c77ccf95c791b57b221aDianne Hackborn        attrs.setTitle("GlobalActions");
1735fe7e2a3043d6a8ca933c77ccf95c791b57b221aDianne Hackborn        mDialog.getWindow().setAttributes(attrs);
1741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mDialog.show();
175ec3f05e707044505642cbdb180aff5edf9b926aaDaniel Sandler        mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);
1761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1777ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
1781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Create the global actions dialog.
1801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @return A new dialog.
1811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1827befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov    private GlobalActionsDialog createDialog() {
1837ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        // Simple toggle style if there's no vibrator, otherwise use a tri-state
1847ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        if (!mHasVibrator) {
1857ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            mSilentModeAction = new SilentModeToggleAction();
1867ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        } else {
1877ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            mSilentModeAction = new SilentModeTriStateAction(mContext, mAudioManager, mHandler);
1887ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
1891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAirplaneModeOn = new ToggleAction(
1901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.drawable.ic_lock_airplane_mode,
1911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.drawable.ic_lock_airplane_mode_off,
1921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_actions_toggle_airplane_mode,
1931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_actions_airplane_mode_on_status,
1941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_actions_airplane_mode_off_status) {
1951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            void onToggle(boolean on) {
1977ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                if (mHasTelephony && Boolean.parseBoolean(
198fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                        SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
199fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mIsWaitingForEcmExit = true;
200fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    // Launch ECM exit dialog
201fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    Intent ecmDialogIntent =
202fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                            new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null);
203fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    ecmDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
204fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mContext.startActivity(ecmDialogIntent);
205fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                } else {
206fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    changeAirplaneModeSystemSetting(on);
207fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                }
2081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
2091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            @Override
2111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            protected void changeStateFromPress(boolean buttonOn) {
2127ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                if (!mHasTelephony) return;
2137ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
214fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // In ECM mode airplane state cannot be changed
215fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                if (!(Boolean.parseBoolean(
216fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                        SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)))) {
217fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mState = buttonOn ? State.TurningOn : State.TurningOff;
218fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mAirplaneState = mState;
219fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                }
2201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
2211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean showDuringKeyguard() {
2231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return true;
2241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
2251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean showBeforeProvisioning() {
2271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return false;
2281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
2291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        };
2307ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        onAirplaneModeChanged();
2311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2322ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani        mItems = new ArrayList<Action>();
2332ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani
2346243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        // first: power off
2352ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani        mItems.add(
2362ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani            new SinglePressAction(
2372ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                    com.android.internal.R.drawable.ic_lock_power_off,
2382ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                    R.string.global_action_power_off) {
2392ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani
2402ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                public void onPress() {
2412ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                    // shutdown by making sure radio and power are handled accordingly.
2429a538ee7bde42ad36f43edc48594282d98e191a4Jeff Brown                    mWindowManagerFuncs.shutdown(true);
2432ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                }
2442ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani
24519caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn                public boolean onLongPress() {
2469a538ee7bde42ad36f43edc48594282d98e191a4Jeff Brown                    mWindowManagerFuncs.rebootSafeMode(true);
24719caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn                    return true;
24819caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn                }
24919caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn
2502ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                public boolean showDuringKeyguard() {
2512ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                    return true;
2522ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                }
2532ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani
2542ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                public boolean showBeforeProvisioning() {
2552ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                    return true;
2562ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                }
2572ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani            });
2581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2596243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        // next: airplane mode
2606243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        mItems.add(mAirplaneModeOn);
2616243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
2625773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn        // next: bug report, if enabled
2635773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn        if (Settings.Secure.getInt(mContext.getContentResolver(),
2645773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                Settings.Secure.BUGREPORT_IN_POWER_MENU, 0) != 0) {
2655773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn            mItems.add(
266d4ac8d7b3de27a9f0e4c6af2496ca71d794e42d1Dianne Hackborn                new SinglePressAction(com.android.internal.R.drawable.stat_sys_adb,
267d4ac8d7b3de27a9f0e4c6af2496ca71d794e42d1Dianne Hackborn                        R.string.global_action_bug_report) {
2685773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn
2695773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                    public void onPress() {
2705773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
2715773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                        builder.setTitle(com.android.internal.R.string.bugreport_title);
2725773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                        builder.setMessage(com.android.internal.R.string.bugreport_message);
2735773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                        builder.setNegativeButton(com.android.internal.R.string.cancel, null);
2745773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                        builder.setPositiveButton(com.android.internal.R.string.report,
2755773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                                new DialogInterface.OnClickListener() {
2765773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                                    @Override
2775773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                                    public void onClick(DialogInterface dialog, int which) {
2785773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                                        // Add a little delay before executing, to give the
2795773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                                        // dialog a chance to go away before it takes a
2805773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                                        // screenshot.
2815773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                                        mHandler.postDelayed(new Runnable() {
2825773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                                            @Override public void run() {
283d4ac8d7b3de27a9f0e4c6af2496ca71d794e42d1Dianne Hackborn                                                try {
284d4ac8d7b3de27a9f0e4c6af2496ca71d794e42d1Dianne Hackborn                                                    ActivityManagerNative.getDefault()
285d4ac8d7b3de27a9f0e4c6af2496ca71d794e42d1Dianne Hackborn                                                            .requestBugReport();
286d4ac8d7b3de27a9f0e4c6af2496ca71d794e42d1Dianne Hackborn                                                } catch (RemoteException e) {
287d4ac8d7b3de27a9f0e4c6af2496ca71d794e42d1Dianne Hackborn                                                }
2885773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                                            }
2895773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                                        }, 500);
2905773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                                    }
2915773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                                });
2925773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                        AlertDialog dialog = builder.create();
293bef0f617a09e8c3b1567217bba65006c7364baedDianne Hackborn                        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
2945773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                        dialog.show();
2955773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                    }
2965773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn
2975773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                    public boolean onLongPress() {
2985773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                        return false;
2995773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                    }
3005773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn
3015773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                    public boolean showDuringKeyguard() {
3025773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                        return true;
3035773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                    }
3045773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn
3055773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                    public boolean showBeforeProvisioning() {
3065773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                        return false;
3075773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                    }
3085773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn                });
3095773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn        }
3105773bfdb7cd3852d9fedd497e3c22c49c83d0d75Dianne Hackborn
3116243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        // last: silent mode
3126243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        if (SHOW_SILENT_TOGGLE) {
3136243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mItems.add(mSilentModeAction);
3146243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
3156243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
316bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        // one more thing: optionally add a list of users to switch to
317912133a4966e0eed9a72b208e2aa650dc538b328Amith Yamasani        if (SystemProperties.getBoolean("fw.power_user_switcher", false)) {
318bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani            addUsersToMenu(mItems);
319bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        }
320bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani
321bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        mAdapter = new MyAdapter();
322bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani
323bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        AlertParams params = new AlertParams(mContext);
324bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        params.mAdapter = mAdapter;
325bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        params.mOnClickListener = this;
326bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        params.mForceInverseBackground = true;
327bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani
328bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        GlobalActionsDialog dialog = new GlobalActionsDialog(mContext, params);
329bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
330bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani
331bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        dialog.getListView().setItemsCanFocus(true);
332bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        dialog.getListView().setLongClickable(true);
333bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        dialog.getListView().setOnItemLongClickListener(
334bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani                new AdapterView.OnItemLongClickListener() {
335bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani                    @Override
336bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani                    public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
337bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani                            long id) {
338bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani                        return mAdapter.getItem(position).onLongPress();
339bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani                    }
340bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        });
341bef0f617a09e8c3b1567217bba65006c7364baedDianne Hackborn        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
342bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani
343bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        dialog.setOnDismissListener(this);
344bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani
345bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani        return dialog;
346bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani    }
347bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani
348bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani    private void addUsersToMenu(ArrayList<Action> items) {
349258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani        List<UserInfo> users = ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
350258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasani                .getUsers();
351742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        if (users.size() > 1) {
35252f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani            UserInfo currentUser;
35352f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani            try {
35452f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani                currentUser = ActivityManagerNative.getDefault().getCurrentUser();
35552f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani            } catch (RemoteException re) {
35652f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani                currentUser = null;
35752f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani            }
358742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            for (final UserInfo user : users) {
35952f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani                boolean isCurrentUser = currentUser == null
36052f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani                        ? user.id == 0 : (currentUser.id == user.id);
361b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani                Drawable icon = user.iconPath != null ? Drawable.createFromPath(user.iconPath)
362b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani                        : null;
363742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                SinglePressAction switchToUser = new SinglePressAction(
364b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani                        com.android.internal.R.drawable.ic_menu_cc, icon,
36552f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani                        (user.name != null ? user.name : "Primary")
36652f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani                        + (isCurrentUser ? " \u2714" : "")) {
367742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                    public void onPress() {
368742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                        try {
369742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                            ActivityManagerNative.getDefault().switchUser(user.id);
370742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                        } catch (RemoteException re) {
371742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                            Log.e(TAG, "Couldn't switch user " + re);
372742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                        }
373742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                    }
374742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
375742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                    public boolean showDuringKeyguard() {
376742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                        return true;
377742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                    }
378742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
379742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                    public boolean showBeforeProvisioning() {
380742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                        return false;
381742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                    }
382742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                };
383bc4ba82335c091cebaaee8b20987a61fb54c1727Amith Yamasani                items.add(switchToUser);
384742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            }
385742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
3861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
3871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private void prepareDialog() {
3897ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        refreshSilentMode();
3901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAirplaneModeOn.updateState(mAirplaneState);
3911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAdapter.notifyDataSetChanged();
392bef0f617a09e8c3b1567217bba65006c7364baedDianne Hackborn        mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
3936243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        if (SHOW_SILENT_TOGGLE) {
3946243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
3956243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mContext.registerReceiver(mRingerModeReceiver, filter);
3966243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
3971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
3981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3997ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private void refreshSilentMode() {
4007ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        if (!mHasVibrator) {
4017ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            final boolean silentModeOn =
4027ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
4037ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            ((ToggleAction)mSilentModeAction).updateState(
4047ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    silentModeOn ? ToggleAction.State.On : ToggleAction.State.Off);
4057ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
4067ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    }
4077ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
4081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /** {@inheritDoc} */
4091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void onDismiss(DialogInterface dialog) {
4106243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        if (SHOW_SILENT_TOGGLE) {
4116243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mContext.unregisterReceiver(mRingerModeReceiver);
4126243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
4131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
4141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /** {@inheritDoc} */
4161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void onClick(DialogInterface dialog, int which) {
4177ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        if (!(mAdapter.getItem(which) instanceof SilentModeTriStateAction)) {
4186243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            dialog.dismiss();
4196243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
4201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAdapter.getItem(which).onPress();
4211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
4221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
4241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * The adapter used for the list within the global actions dialog, taking
4251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * into account whether the keyguard is showing via
4261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * {@link GlobalActions#mKeyguardShowing} and whether the device is provisioned
4271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * via {@link GlobalActions#mDeviceProvisioned}.
4281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
4291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private class MyAdapter extends BaseAdapter {
4301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public int getCount() {
4321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            int count = 0;
4331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            for (int i = 0; i < mItems.size(); i++) {
4351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                final Action action = mItems.get(i);
4361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mKeyguardShowing && !action.showDuringKeyguard()) {
4381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
4391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
4401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (!mDeviceProvisioned && !action.showBeforeProvisioning()) {
4411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
4421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
4431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                count++;
4441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
4451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return count;
4461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
4491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled(int position) {
4501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return getItem(position).isEnabled();
4511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
4541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean areAllItemsEnabled() {
4551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return false;
4561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public Action getItem(int position) {
4591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            int filteredPos = 0;
4611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            for (int i = 0; i < mItems.size(); i++) {
4621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                final Action action = mItems.get(i);
4631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mKeyguardShowing && !action.showDuringKeyguard()) {
4641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
4651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
4661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (!mDeviceProvisioned && !action.showBeforeProvisioning()) {
4671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
4681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
4691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (filteredPos == position) {
4701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    return action;
4711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
4721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                filteredPos++;
4731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
4741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
475c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer            throw new IllegalArgumentException("position " + position
476c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer                    + " out of range of showable actions"
477c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer                    + ", filtered count=" + getCount()
478c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer                    + ", keyguardshowing=" + mKeyguardShowing
4791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    + ", provisioned=" + mDeviceProvisioned);
4801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public long getItemId(int position) {
4841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return position;
4851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View getView(int position, View convertView, ViewGroup parent) {
4881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            Action action = getItem(position);
4891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
4901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
4921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // note: the scheme below made more sense when we were planning on having
4941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // 8 different things in the global actions dialog.  seems overkill with
4951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // only 3 items now, but may as well keep this flexible approach so it will
4961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // be easy should someone decide at the last minute to include something
4971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // else, such as 'enable wifi', or 'enable bluetooth'
4981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
5001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * What each item in the global actions dialog must be able to support.
5011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
5021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private interface Action {
5031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        View create(Context context, View convertView, ViewGroup parent, LayoutInflater inflater);
5041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        void onPress();
5061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
50719caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        public boolean onLongPress();
50819caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn
5091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
5101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @return whether this action should appear in the dialog when the keygaurd
5111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         *    is showing.
5121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
5131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean showDuringKeyguard();
5141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
5161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @return whether this action should appear in the dialog before the
5171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         *   device is provisioned.
5181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
5191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean showBeforeProvisioning();
5201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean isEnabled();
5221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
5251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * A single press action maintains no state, just responds to a press
5261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * and takes an action.
5271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
5281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static abstract class SinglePressAction implements Action {
5291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        private final int mIconResId;
530b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani        private final Drawable mIcon;
5311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        private final int mMessageResId;
532742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        private final CharSequence mMessage;
5331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected SinglePressAction(int iconResId, int messageResId) {
5351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mIconResId = iconResId;
5361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mMessageResId = messageResId;
537742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mMessage = null;
538b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            mIcon = null;
539b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani        }
540b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani
541b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani        protected SinglePressAction(int iconResId, Drawable icon, CharSequence message) {
542b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            mIconResId = iconResId;
543b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            mMessageResId = 0;
544b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            mMessage = message;
545b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            mIcon = icon;
5461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
548742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        protected SinglePressAction(int iconResId, CharSequence message) {
549742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mIconResId = iconResId;
550742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mMessageResId = 0;
551742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mMessage = message;
552b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            mIcon = null;
553742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
554b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani
5551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled() {
5561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return true;
5571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        abstract public void onPress();
5601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
56119caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        public boolean onLongPress() {
56219caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn            return false;
56319caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        }
56419caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn
5651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View create(
5661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
5676243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            View v = inflater.inflate(R.layout.global_actions_item, parent, false);
5681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            ImageView icon = (ImageView) v.findViewById(R.id.icon);
5701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TextView messageView = (TextView) v.findViewById(R.id.message);
5711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            v.findViewById(R.id.status).setVisibility(View.GONE);
573b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            if (mIcon != null) {
574b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani                icon.setImageDrawable(mIcon);
575b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani                icon.setScaleType(ScaleType.CENTER_CROP);
576b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            } else if (mIconResId != 0) {
577b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani                icon.setImageDrawable(context.getResources().getDrawable(mIconResId));
578b8151ecd6ef4faa5c16d0a4c3abb45ec84d1f97aAmith Yamasani            }
579742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            if (mMessage != null) {
580742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                messageView.setText(mMessage);
581742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            } else {
582742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                messageView.setText(mMessageResId);
583742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            }
5841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return v;
5861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
5901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * A toggle action knows whether it is on or off, and displays an icon
5911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * and status message accordingly.
5921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
5931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static abstract class ToggleAction implements Action {
5941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        enum State {
5961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            Off(false),
5971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TurningOn(true),
5981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TurningOff(true),
5991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            On(false);
6001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            private final boolean inTransition;
6021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            State(boolean intermediate) {
6041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                inTransition = intermediate;
6051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
6061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean inTransition() {
6081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return inTransition;
6091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
6101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected State mState = State.Off;
6131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // prefs
61582d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mEnabledIconResId;
61682d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mDisabledIconResid;
61782d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mMessageResId;
61882d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mEnabledStatusMessageResId;
61982d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mDisabledStatusMessageResId;
6201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
6221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param enabledIconResId The icon for when this action is on.
6231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param disabledIconResid The icon for when this action is off.
6241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param essage The general information message, e.g 'Silent Mode'
6251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param enabledStatusMessageResId The on status message, e.g 'sound disabled'
6261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param disabledStatusMessageResId The off status message, e.g. 'sound enabled'
6271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
6281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public ToggleAction(int enabledIconResId,
6291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int disabledIconResid,
6307ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                int message,
6311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int enabledStatusMessageResId,
6321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int disabledStatusMessageResId) {
6331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mEnabledIconResId = enabledIconResId;
6341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDisabledIconResid = disabledIconResid;
6357ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            mMessageResId = message;
6361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mEnabledStatusMessageResId = enabledStatusMessageResId;
6371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDisabledStatusMessageResId = disabledStatusMessageResId;
6381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
64082d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        /**
64182d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         * Override to make changes to resource IDs just before creating the
64282d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         * View.
64382d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         */
64482d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        void willCreate() {
64582d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
64682d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        }
64782d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
6481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View create(Context context, View convertView, ViewGroup parent,
6491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                LayoutInflater inflater) {
65082d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler            willCreate();
65182d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
6526243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            View v = inflater.inflate(R
6531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                            .layout.global_actions_item, parent, false);
6541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            ImageView icon = (ImageView) v.findViewById(R.id.icon);
6561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TextView messageView = (TextView) v.findViewById(R.id.message);
6571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TextView statusView = (TextView) v.findViewById(R.id.status);
6586243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            final boolean enabled = isEnabled();
6591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6606243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (messageView != null) {
6616243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                messageView.setText(mMessageResId);
6626243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                messageView.setEnabled(enabled);
6636243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
6641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            boolean on = ((mState == State.On) || (mState == State.TurningOn));
6666243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (icon != null) {
6676243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                icon.setImageDrawable(context.getResources().getDrawable(
6686243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                        (on ? mEnabledIconResId : mDisabledIconResid)));
6696243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                icon.setEnabled(enabled);
6706243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
6711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6726243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (statusView != null) {
6736243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                statusView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId);
6746243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                statusView.setVisibility(View.VISIBLE);
6756243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                statusView.setEnabled(enabled);
6766243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
6771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            v.setEnabled(enabled);
6781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return v;
6801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public final void onPress() {
6831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (mState.inTransition()) {
6841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                Log.w(TAG, "shouldn't be able to toggle when in transition");
6851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return;
6861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
6871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            final boolean nowOn = !(mState == State.On);
6891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            onToggle(nowOn);
6901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            changeStateFromPress(nowOn);
6911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
69319caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        public boolean onLongPress() {
69419caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn            return false;
69519caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        }
69619caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn
6971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled() {
6981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return !mState.inTransition();
6991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
7001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
7021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * Implementations may override this if their state can be in on of the intermediate
7031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * states until some notification is received (e.g airplane mode is 'turning off' until
7041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * we know the wireless connections are back online
7051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param buttonOn Whether the button was turned on or off
7061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
7071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected void changeStateFromPress(boolean buttonOn) {
7081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mState = buttonOn ? State.On : State.Off;
7091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
7101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        abstract void onToggle(boolean on);
7121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void updateState(State state) {
7141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mState = state;
7151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
7161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
7171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7187ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private class SilentModeToggleAction extends ToggleAction {
7197ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        public SilentModeToggleAction() {
7207ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            super(R.drawable.ic_audio_vol_mute,
7217ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    R.drawable.ic_audio_vol,
7227ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    R.string.global_action_toggle_silent_mode,
7237ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    R.string.global_action_silent_mode_on_status,
7247ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    R.string.global_action_silent_mode_off_status);
7257ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
7267ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
7277ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        void onToggle(boolean on) {
7287ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            if (on) {
7297ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
7307ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            } else {
7317ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
7327ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            }
7337ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
7347ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
7357ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        public boolean showDuringKeyguard() {
7367ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            return true;
7377ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
7387ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
7397ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        public boolean showBeforeProvisioning() {
7407ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            return false;
7417ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
7427ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    }
7437ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
7447ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private static class SilentModeTriStateAction implements Action, View.OnClickListener {
7456243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
7466243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private final int[] ITEM_IDS = { R.id.option1, R.id.option2, R.id.option3 };
7476243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
7486243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private final AudioManager mAudioManager;
7496243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private final Handler mHandler;
750135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        private final Context mContext;
7516243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
7527ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        SilentModeTriStateAction(Context context, AudioManager audioManager, Handler handler) {
7536243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mAudioManager = audioManager;
7546243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mHandler = handler;
755135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            mContext = context;
7566243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
7576243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
7586243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private int ringerModeToIndex(int ringerMode) {
7596243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            // They just happen to coincide
7606243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return ringerMode;
7616243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
7626243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
7636243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private int indexToRingerMode(int index) {
7646243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            // They just happen to coincide
7656243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return index;
7666243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
7676243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
7686243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public View create(Context context, View convertView, ViewGroup parent,
7696243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                LayoutInflater inflater) {
7706243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            View v = inflater.inflate(R.layout.global_actions_silent_mode, parent, false);
7716243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
7726243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            int selectedIndex = ringerModeToIndex(mAudioManager.getRingerMode());
7736243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            for (int i = 0; i < 3; i++) {
7746243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                View itemView = v.findViewById(ITEM_IDS[i]);
7756243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                itemView.setSelected(selectedIndex == i);
7766243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                // Set up click handler
7776243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                itemView.setTag(i);
7786243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                itemView.setOnClickListener(this);
7796243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
7806243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return v;
7816243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
7826243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
7836243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public void onPress() {
7846243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
7856243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
78619caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        public boolean onLongPress() {
78719caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn            return false;
78819caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        }
78919caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn
7906243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public boolean showDuringKeyguard() {
7916243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return true;
7926243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
7936243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
7946243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public boolean showBeforeProvisioning() {
7956243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return false;
7966243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
7976243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
7986243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public boolean isEnabled() {
7996243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return true;
8006243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
8016243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
8026243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        void willCreate() {
8036243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
8046243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
8056243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public void onClick(View v) {
8066243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (!(v.getTag() instanceof Integer)) return;
8076243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
8086243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            int index = (Integer) v.getTag();
8096243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mAudioManager.setRingerMode(indexToRingerMode(index));
8106243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mHandler.sendEmptyMessageDelayed(MESSAGE_DISMISS, DIALOG_DISMISS_DELAY);
8116243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
8126243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    }
8136243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
8141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
8151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void onReceive(Context context, Intent intent) {
8161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            String action = intent.getAction();
81778866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
81878866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato                    || Intent.ACTION_SCREEN_OFF.equals(action)) {
8191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                String reason = intent.getStringExtra(PhoneWindowManager.SYSTEM_DIALOG_REASON_KEY);
82078866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato                if (!PhoneWindowManager.SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS.equals(reason)) {
8211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mHandler.sendEmptyMessage(MESSAGE_DISMISS);
8221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
823fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo            } else if (TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED.equals(action)) {
824fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // Airplane mode can be changed after ECM exits if airplane toggle button
825fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // is pressed during ECM mode
826fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                if (!(intent.getBooleanExtra("PHONE_IN_ECM_STATE", false)) &&
827fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                        mIsWaitingForEcmExit) {
828fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mIsWaitingForEcmExit = false;
829fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    changeAirplaneModeSystemSetting(true);
830fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                }
8311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
8321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
8331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
8341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
8361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
8371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void onServiceStateChanged(ServiceState serviceState) {
8387ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            if (!mHasTelephony) return;
8391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            final boolean inAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF;
8401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAirplaneState = inAirplaneMode ? ToggleAction.State.On : ToggleAction.State.Off;
8411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAirplaneModeOn.updateState(mAirplaneState);
8421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAdapter.notifyDataSetChanged();
8431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
8441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
8451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
8466243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private BroadcastReceiver mRingerModeReceiver = new BroadcastReceiver() {
8476243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        @Override
8486243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public void onReceive(Context context, Intent intent) {
8496243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (intent.getAction().equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
8506243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                mHandler.sendEmptyMessage(MESSAGE_REFRESH);
8516243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
8526243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
8536243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    };
8546243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
8557ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private ContentObserver mAirplaneModeObserver = new ContentObserver(new Handler()) {
8567ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        @Override
8577ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        public void onChange(boolean selfChange) {
8587ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            onAirplaneModeChanged();
8597ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
8607ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    };
8617ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
8621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static final int MESSAGE_DISMISS = 0;
8636243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private static final int MESSAGE_REFRESH = 1;
8642efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani    private static final int MESSAGE_SHOW = 2;
8656243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private static final int DIALOG_DISMISS_DELAY = 300; // ms
8666243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
8671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private Handler mHandler = new Handler() {
8681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void handleMessage(Message msg) {
8692efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            switch (msg.what) {
8702efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            case MESSAGE_DISMISS:
8711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mDialog != null) {
8721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mDialog.dismiss();
8731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
8742efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani                break;
8752efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            case MESSAGE_REFRESH:
8767ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                refreshSilentMode();
8776243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                mAdapter.notifyDataSetChanged();
8782efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani                break;
8792efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            case MESSAGE_SHOW:
8802efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani                handleShow();
8812efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani                break;
8821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
8831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
8841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
885fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo
8867ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private void onAirplaneModeChanged() {
8877ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        // Let the service state callbacks handle the state.
8887ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        if (mHasTelephony) return;
8897ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
890c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate        boolean airplaneModeOn = Settings.Global.getInt(
8917ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                mContext.getContentResolver(),
892c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate                Settings.Global.AIRPLANE_MODE_ON,
8937ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                0) == 1;
8947ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        mAirplaneState = airplaneModeOn ? ToggleAction.State.On : ToggleAction.State.Off;
8957ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        mAirplaneModeOn.updateState(mAirplaneState);
8967ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    }
8977ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
898fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    /**
899fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo     * Change the airplane mode system setting
900fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo     */
901fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    private void changeAirplaneModeSystemSetting(boolean on) {
902c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate        Settings.Global.putInt(
903fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                mContext.getContentResolver(),
904c09cdce1b05075da808ae080b9905a14a3e1e627Christopher Tate                Settings.Global.AIRPLANE_MODE_ON,
905fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                on ? 1 : 0);
906fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
907818ba11cd680de336fb9278b64a21dc2efb7517eDianne Hackborn        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
908fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        intent.putExtra("state", on);
9095ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
9107ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        if (!mHasTelephony) {
9117ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            mAirplaneState = on ? ToggleAction.State.On : ToggleAction.State.Off;
9127ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
913fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    }
9147befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
9157befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov    private static final class GlobalActionsDialog extends Dialog implements DialogInterface {
9167befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        private final Context mContext;
9177befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        private final int mWindowTouchSlop;
9187befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        private final AlertController mAlert;
9197befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
9207befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        private EnableAccessibilityController mEnableAccessibilityController;
9217befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
9227befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        private boolean mIntercepted;
9237befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        private boolean mCancelOnUp;
9247befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
9257befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        public GlobalActionsDialog(Context context, AlertParams params) {
9267befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            super(context, getDialogTheme(context));
9277befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            mContext = context;
9287befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            mAlert = new AlertController(mContext, this, getWindow());
9297befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            mWindowTouchSlop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
9307befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            params.apply(mAlert);
9317befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
9327befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
9337befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        private static int getDialogTheme(Context context) {
9347befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            TypedValue outValue = new TypedValue();
9357befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            context.getTheme().resolveAttribute(com.android.internal.R.attr.alertDialogTheme,
9367befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    outValue, true);
9377befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            return outValue.resourceId;
9387befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
9397befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
9407befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        @Override
9417befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        protected void onStart() {
9427befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            // If global accessibility gesture can be performed, we will take care
9437befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            // of dismissing the dialog on touch outside. This is because the dialog
9447befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            // is dismissed on the first down while the global gesture is a long press
9457befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            // with two fingers anywhere on the screen.
9467befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            if (EnableAccessibilityController.canEnableAccessibilityViaGesture(mContext)) {
9477befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                mEnableAccessibilityController = new EnableAccessibilityController(mContext);
9487befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                super.setCanceledOnTouchOutside(false);
9497befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            } else {
9507befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                mEnableAccessibilityController = null;
9517befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                super.setCanceledOnTouchOutside(true);
9527befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            }
9537befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            super.onStart();
9547befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
9557befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
9567befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        @Override
9577befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        protected void onStop() {
9587befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            if (mEnableAccessibilityController != null) {
9597befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                mEnableAccessibilityController.onDestroy();
9607befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            }
9617befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            super.onStop();
9627befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
9637befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
9647befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        @Override
9657befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        public boolean dispatchTouchEvent(MotionEvent event) {
9667befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            if (mEnableAccessibilityController != null) {
9677befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                final int action = event.getActionMasked();
9687befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                if (action == MotionEvent.ACTION_DOWN) {
9697befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    View decor = getWindow().getDecorView();
9707befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    final int eventX = (int) event.getX();
9717befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    final int eventY = (int) event.getY();
9727befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    if (eventX < -mWindowTouchSlop
9737befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            || eventY < -mWindowTouchSlop
9747befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            || eventX >= decor.getWidth() + mWindowTouchSlop
9757befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            || eventY >= decor.getHeight() + mWindowTouchSlop) {
9767befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        mCancelOnUp = true;
9777befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    }
9787befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                }
9797befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                try {
9807befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    if (!mIntercepted) {
9817befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        mIntercepted = mEnableAccessibilityController.onInterceptTouchEvent(event);
9827befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        if (mIntercepted) {
9837befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            final long now = SystemClock.uptimeMillis();
9847befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            event = MotionEvent.obtain(now, now,
9857befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                                    MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
9867befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
9877befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            mCancelOnUp = true;
9887befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        }
9897befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    } else {
9907befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        return mEnableAccessibilityController.onTouchEvent(event);
9917befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    }
9927befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                } finally {
9937befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    if (action == MotionEvent.ACTION_UP) {
9947befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        if (mCancelOnUp) {
9957befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                            cancel();
9967befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        }
9977befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        mCancelOnUp = false;
9987befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                        mIntercepted = false;
9997befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                    }
10007befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                }
10017befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            }
10027befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            return super.dispatchTouchEvent(event);
10037befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
10047befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
10057befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        public ListView getListView() {
10067befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            return mAlert.getListView();
10077befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
10087befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
10097befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        @Override
10107befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        protected void onCreate(Bundle savedInstanceState) {
10117befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            super.onCreate(savedInstanceState);
10127befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            mAlert.installContent();
10137befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
10147befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
10157befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        @Override
10167befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        public boolean onKeyDown(int keyCode, KeyEvent event) {
10177befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            if (mAlert.onKeyDown(keyCode, event)) {
10187befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                return true;
10197befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            }
10207befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            return super.onKeyDown(keyCode, event);
10217befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
10227befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov
10237befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        @Override
10247befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        public boolean onKeyUp(int keyCode, KeyEvent event) {
10257befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            if (mAlert.onKeyUp(keyCode, event)) {
10267befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov                return true;
10277befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            }
10287befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov            return super.onKeyUp(keyCode, event);
10297befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov        }
10307befb7deb2ac15134b3bb190520cba19165d16ddSvetoslav Ganov    }
10311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project}
1032