GlobalActions.java revision 7ee994d728acf2b3b3297a67001f2d21c9094109
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
19742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport com.android.internal.telephony.TelephonyIntents;
20742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport com.android.internal.telephony.TelephonyProperties;
21742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport com.android.internal.R;
22742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
23742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport android.app.ActivityManagerNative;
241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.app.AlertDialog;
251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.BroadcastReceiver;
261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Context;
271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.DialogInterface;
281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Intent;
291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.IntentFilter;
30742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport android.content.pm.UserInfo;
317ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasaniimport android.database.ContentObserver;
321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.media.AudioManager;
337ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasaniimport android.net.ConnectivityManager;
341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.Handler;
35135936072b24b090fb63940aea41b408d855a4f3Amith Yamasaniimport android.os.IBinder;
361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.Message;
37742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport android.os.RemoteException;
38135936072b24b090fb63940aea41b408d855a4f3Amith Yamasaniimport android.os.ServiceManager;
39fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guoimport android.os.SystemProperties;
40135936072b24b090fb63940aea41b408d855a4f3Amith Yamasaniimport android.os.Vibrator;
411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.provider.Settings;
421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.telephony.PhoneStateListener;
431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.telephony.ServiceState;
441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.telephony.TelephonyManager;
451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.util.Log;
46135936072b24b090fb63940aea41b408d855a4f3Amith Yamasaniimport android.view.IWindowManager;
471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.LayoutInflater;
481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.View;
491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.ViewGroup;
501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.WindowManager;
517304c343821309dd15f769b18f1de2fa43751573Jeff Brownimport android.view.WindowManagerPolicy.WindowManagerFuncs;
5219caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackbornimport android.widget.AdapterView;
531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.BaseAdapter;
541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.ImageView;
551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.TextView;
561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport java.util.ArrayList;
58742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasaniimport java.util.List;
591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/**
611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Helper to show the global actions dialog.  Each item is an {@link Action} that
621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * may show depending on whether the keyguard is showing, and whether the device
631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * is provisioned.
641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */
651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectclass GlobalActions implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener  {
661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static final String TAG = "GlobalActions";
681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
696243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private static final boolean SHOW_SILENT_TOGGLE = true;
702ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani
711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final Context mContext;
727304c343821309dd15f769b18f1de2fa43751573Jeff Brown    private final WindowManagerFuncs mWindowManagerFuncs;
731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final AudioManager mAudioManager;
741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ArrayList<Action> mItems;
761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private AlertDialog mDialog;
771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
787ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private Action mSilentModeAction;
791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ToggleAction mAirplaneModeOn;
801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private MyAdapter mAdapter;
821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mKeyguardShowing = false;
841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mDeviceProvisioned = false;
851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ToggleAction.State mAirplaneState = ToggleAction.State.Off;
86fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    private boolean mIsWaitingForEcmExit = false;
877ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private boolean mHasTelephony;
887ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private boolean mHasVibrator;
891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
90135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani    private IWindowManager mIWindowManager;
91135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani
921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @param context everything needs a context :(
941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
957304c343821309dd15f769b18f1de2fa43751573Jeff Brown    public GlobalActions(Context context, WindowManagerFuncs windowManagerFuncs) {
961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mContext = context;
977304c343821309dd15f769b18f1de2fa43751573Jeff Brown        mWindowManagerFuncs = windowManagerFuncs;
981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // receive broadcasts
1011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        IntentFilter filter = new IntentFilter();
1021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
10378866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato        filter.addAction(Intent.ACTION_SCREEN_OFF);
104fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
1051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        context.registerReceiver(mBroadcastReceiver, filter);
1061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // get notified of phone state changes
1081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        TelephonyManager telephonyManager =
1091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
1101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
1117ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        ConnectivityManager cm = (ConnectivityManager)
1127ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                context.getSystemService(Context.CONNECTIVITY_SERVICE);
1137ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        mHasTelephony = cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
1147ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        mContext.getContentResolver().registerContentObserver(
1157ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                Settings.System.getUriFor(Settings.System.AIRPLANE_MODE_ON), true,
1167ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                mAirplaneModeObserver);
1177ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
1187ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        mHasVibrator = vibrator != null && vibrator.hasVibrator();
1191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Show the global actions dialog (creating if necessary)
1231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @param keyguardShowing True if keyguard is showing
1241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) {
1261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mKeyguardShowing = keyguardShowing;
1271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mDeviceProvisioned = isDeviceProvisioned;
128742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        if (mDialog != null) {
129742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mDialog.dismiss();
1302efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            mDialog = null;
1312efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            // Show delayed, so that the dismiss of the previous dialog completes
1322efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            mHandler.sendEmptyMessage(MESSAGE_SHOW);
1332efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani        } else {
1342efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            handleShow();
1351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
1362efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani    }
1372efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani
1382efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani    private void handleShow() {
139742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        mDialog = createDialog();
1401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        prepareDialog();
1411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mDialog.show();
143ec3f05e707044505642cbdb180aff5edf9b926aaDaniel Sandler        mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);
1441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1457ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
1461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Create the global actions dialog.
1481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @return A new dialog.
1491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private AlertDialog createDialog() {
1517ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        // Simple toggle style if there's no vibrator, otherwise use a tri-state
1527ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        if (!mHasVibrator) {
1537ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            mSilentModeAction = new SilentModeToggleAction();
1547ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        } else {
1557ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            mSilentModeAction = new SilentModeTriStateAction(mContext, mAudioManager, mHandler);
1567ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
1571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAirplaneModeOn = new ToggleAction(
1581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.drawable.ic_lock_airplane_mode,
1591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.drawable.ic_lock_airplane_mode_off,
1601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_actions_toggle_airplane_mode,
1611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_actions_airplane_mode_on_status,
1621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_actions_airplane_mode_off_status) {
1631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            void onToggle(boolean on) {
1657ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                if (mHasTelephony && Boolean.parseBoolean(
166fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                        SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
167fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mIsWaitingForEcmExit = true;
168fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    // Launch ECM exit dialog
169fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    Intent ecmDialogIntent =
170fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                            new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null);
171fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    ecmDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
172fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mContext.startActivity(ecmDialogIntent);
173fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                } else {
174fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    changeAirplaneModeSystemSetting(on);
175fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                }
1761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
1771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            @Override
1791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            protected void changeStateFromPress(boolean buttonOn) {
1807ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                if (!mHasTelephony) return;
1817ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
182fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // In ECM mode airplane state cannot be changed
183fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                if (!(Boolean.parseBoolean(
184fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                        SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)))) {
185fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mState = buttonOn ? State.TurningOn : State.TurningOff;
186fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mAirplaneState = mState;
187fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                }
1881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
1891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean showDuringKeyguard() {
1911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return true;
1921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
1931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean showBeforeProvisioning() {
1951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return false;
1961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
1971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        };
1987ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        onAirplaneModeChanged();
1991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2002ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani        mItems = new ArrayList<Action>();
2012ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani
2026243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        // first: power off
2032ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani        mItems.add(
2042ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani            new SinglePressAction(
2052ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                    com.android.internal.R.drawable.ic_lock_power_off,
2062ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                    R.string.global_action_power_off) {
2072ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani
2082ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                public void onPress() {
2092ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                    // shutdown by making sure radio and power are handled accordingly.
2107304c343821309dd15f769b18f1de2fa43751573Jeff Brown                    mWindowManagerFuncs.shutdown();
2112ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                }
2122ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani
21319caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn                public boolean onLongPress() {
2147304c343821309dd15f769b18f1de2fa43751573Jeff Brown                    mWindowManagerFuncs.rebootSafeMode();
21519caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn                    return true;
21619caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn                }
21719caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn
2182ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                public boolean showDuringKeyguard() {
2192ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                    return true;
2202ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                }
2212ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani
2222ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                public boolean showBeforeProvisioning() {
2232ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                    return true;
2242ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                }
2252ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani            });
2261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2276243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        // next: airplane mode
2286243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        mItems.add(mAirplaneModeOn);
2296243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
2306243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        // last: silent mode
2316243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        if (SHOW_SILENT_TOGGLE) {
2326243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mItems.add(mSilentModeAction);
2336243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
2346243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
235742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        List<UserInfo> users = mContext.getPackageManager().getUsers();
236742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        if (users.size() > 1) {
23752f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani            UserInfo currentUser;
23852f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani            try {
23952f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani                currentUser = ActivityManagerNative.getDefault().getCurrentUser();
24052f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani            } catch (RemoteException re) {
24152f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani                currentUser = null;
24252f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani            }
243742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            for (final UserInfo user : users) {
24452f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani                boolean isCurrentUser = currentUser == null
24552f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani                        ? user.id == 0 : (currentUser.id == user.id);
246742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                SinglePressAction switchToUser = new SinglePressAction(
247742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                        com.android.internal.R.drawable.ic_menu_cc,
24852f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani                        (user.name != null ? user.name : "Primary")
24952f1d752f90579c9b57e3350393a029cf72138d0Amith Yamasani                        + (isCurrentUser ? " \u2714" : "")) {
250742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                    public void onPress() {
251742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                        try {
252742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                            ActivityManagerNative.getDefault().switchUser(user.id);
253135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                            getWindowManager().lockNow();
254742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                        } catch (RemoteException re) {
255742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                            Log.e(TAG, "Couldn't switch user " + re);
256742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                        }
257742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                    }
258742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
259742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                    public boolean showDuringKeyguard() {
260742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                        return true;
261742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                    }
262742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani
263742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                    public boolean showBeforeProvisioning() {
264742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                        return false;
265742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                    }
266742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                };
267742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                mItems.add(switchToUser);
268742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            }
269742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
2707ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
2711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAdapter = new MyAdapter();
2721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        final AlertDialog.Builder ab = new AlertDialog.Builder(mContext);
2741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        ab.setAdapter(mAdapter, this)
2766243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                .setInverseBackgroundForced(true);
2771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        final AlertDialog dialog = ab.create();
279e48a160e57a6426be81bfa18dd35324a36f6a74dAmith Yamasani        dialog.getListView().setItemsCanFocus(true);
28019caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        dialog.getListView().setLongClickable(true);
28119caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        dialog.getListView().setOnItemLongClickListener(
28219caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn                new AdapterView.OnItemLongClickListener() {
28319caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn                    @Override
28419caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn                    public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
28519caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn                            long id) {
28619caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn                        return mAdapter.getItem(position).onLongPress();
28719caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn                    }
28819caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        });
2891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
2901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        dialog.setOnDismissListener(this);
2921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return dialog;
2941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
2951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private void prepareDialog() {
2977ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        refreshSilentMode();
2981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAirplaneModeOn.updateState(mAirplaneState);
2991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAdapter.notifyDataSetChanged();
3001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (mKeyguardShowing) {
3011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
3021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else {
303fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo            mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
3041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3056243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        if (SHOW_SILENT_TOGGLE) {
3066243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
3076243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mContext.registerReceiver(mRingerModeReceiver, filter);
3086243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
3091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
3101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3117ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private void refreshSilentMode() {
3127ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        if (!mHasVibrator) {
3137ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            final boolean silentModeOn =
3147ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
3157ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            ((ToggleAction)mSilentModeAction).updateState(
3167ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    silentModeOn ? ToggleAction.State.On : ToggleAction.State.Off);
3177ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
3187ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    }
3197ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
3201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /** {@inheritDoc} */
3211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void onDismiss(DialogInterface dialog) {
3226243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        if (SHOW_SILENT_TOGGLE) {
3236243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mContext.unregisterReceiver(mRingerModeReceiver);
3246243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
3251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
3261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /** {@inheritDoc} */
3281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void onClick(DialogInterface dialog, int which) {
3297ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        if (!(mAdapter.getItem(which) instanceof SilentModeTriStateAction)) {
3306243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            dialog.dismiss();
3316243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
3321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAdapter.getItem(which).onPress();
3331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
3341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
3361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * The adapter used for the list within the global actions dialog, taking
3371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * into account whether the keyguard is showing via
3381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * {@link GlobalActions#mKeyguardShowing} and whether the device is provisioned
3391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * via {@link GlobalActions#mDeviceProvisioned}.
3401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
3411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private class MyAdapter extends BaseAdapter {
3421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public int getCount() {
3441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            int count = 0;
3451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            for (int i = 0; i < mItems.size(); i++) {
3471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                final Action action = mItems.get(i);
3481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mKeyguardShowing && !action.showDuringKeyguard()) {
3501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
3511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
3521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (!mDeviceProvisioned && !action.showBeforeProvisioning()) {
3531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
3541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
3551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                count++;
3561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
3571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return count;
3581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
3611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled(int position) {
3621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return getItem(position).isEnabled();
3631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
3661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean areAllItemsEnabled() {
3671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return false;
3681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public Action getItem(int position) {
3711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            int filteredPos = 0;
3731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            for (int i = 0; i < mItems.size(); i++) {
3741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                final Action action = mItems.get(i);
3751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mKeyguardShowing && !action.showDuringKeyguard()) {
3761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
3771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
3781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (!mDeviceProvisioned && !action.showBeforeProvisioning()) {
3791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
3801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
3811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (filteredPos == position) {
3821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    return action;
3831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
3841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                filteredPos++;
3851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
3861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
387c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer            throw new IllegalArgumentException("position " + position
388c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer                    + " out of range of showable actions"
389c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer                    + ", filtered count=" + getCount()
390c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer                    + ", keyguardshowing=" + mKeyguardShowing
3911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    + ", provisioned=" + mDeviceProvisioned);
3921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public long getItemId(int position) {
3961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return position;
3971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View getView(int position, View convertView, ViewGroup parent) {
4001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            Action action = getItem(position);
4011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
4021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
4041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // note: the scheme below made more sense when we were planning on having
4061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // 8 different things in the global actions dialog.  seems overkill with
4071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // only 3 items now, but may as well keep this flexible approach so it will
4081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // be easy should someone decide at the last minute to include something
4091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // else, such as 'enable wifi', or 'enable bluetooth'
4101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
4121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * What each item in the global actions dialog must be able to support.
4131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
4141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private interface Action {
4151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        View create(Context context, View convertView, ViewGroup parent, LayoutInflater inflater);
4161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        void onPress();
4181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
41919caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        public boolean onLongPress();
42019caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn
4211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
4221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @return whether this action should appear in the dialog when the keygaurd
4231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         *    is showing.
4241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
4251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean showDuringKeyguard();
4261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
4281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @return whether this action should appear in the dialog before the
4291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         *   device is provisioned.
4301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
4311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean showBeforeProvisioning();
4321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean isEnabled();
4341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
4351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
4371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * A single press action maintains no state, just responds to a press
4381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * and takes an action.
4391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
4401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static abstract class SinglePressAction implements Action {
4411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        private final int mIconResId;
4421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        private final int mMessageResId;
443742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        private final CharSequence mMessage;
4441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected SinglePressAction(int iconResId, int messageResId) {
4461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mIconResId = iconResId;
4471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mMessageResId = messageResId;
448742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mMessage = null;
4491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
451742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        protected SinglePressAction(int iconResId, CharSequence message) {
452742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mIconResId = iconResId;
453742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mMessageResId = 0;
454742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            mMessage = message;
455742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani        }
4561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled() {
4571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return true;
4581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        abstract public void onPress();
4611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
46219caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        public boolean onLongPress() {
46319caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn            return false;
46419caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        }
46519caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn
4661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View create(
4671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
4686243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            View v = inflater.inflate(R.layout.global_actions_item, parent, false);
4691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            ImageView icon = (ImageView) v.findViewById(R.id.icon);
4711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TextView messageView = (TextView) v.findViewById(R.id.message);
4721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            v.findViewById(R.id.status).setVisibility(View.GONE);
4741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            icon.setImageDrawable(context.getResources().getDrawable(mIconResId));
476742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            if (mMessage != null) {
477742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                messageView.setText(mMessage);
478742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            } else {
479742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani                messageView.setText(mMessageResId);
480742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani            }
4811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return v;
4831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
4851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
4871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * A toggle action knows whether it is on or off, and displays an icon
4881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * and status message accordingly.
4891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
4901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static abstract class ToggleAction implements Action {
4911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        enum State {
4931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            Off(false),
4941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TurningOn(true),
4951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TurningOff(true),
4961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            On(false);
4971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            private final boolean inTransition;
4991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            State(boolean intermediate) {
5011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                inTransition = intermediate;
5021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
5031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean inTransition() {
5051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return inTransition;
5061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
5071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected State mState = State.Off;
5101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // prefs
51282d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mEnabledIconResId;
51382d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mDisabledIconResid;
51482d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mMessageResId;
51582d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mEnabledStatusMessageResId;
51682d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mDisabledStatusMessageResId;
5171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
5191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param enabledIconResId The icon for when this action is on.
5201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param disabledIconResid The icon for when this action is off.
5211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param essage The general information message, e.g 'Silent Mode'
5221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param enabledStatusMessageResId The on status message, e.g 'sound disabled'
5231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param disabledStatusMessageResId The off status message, e.g. 'sound enabled'
5241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
5251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public ToggleAction(int enabledIconResId,
5261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int disabledIconResid,
5277ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                int message,
5281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int enabledStatusMessageResId,
5291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int disabledStatusMessageResId) {
5301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mEnabledIconResId = enabledIconResId;
5311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDisabledIconResid = disabledIconResid;
5327ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            mMessageResId = message;
5331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mEnabledStatusMessageResId = enabledStatusMessageResId;
5341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDisabledStatusMessageResId = disabledStatusMessageResId;
5351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
53782d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        /**
53882d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         * Override to make changes to resource IDs just before creating the
53982d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         * View.
54082d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         */
54182d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        void willCreate() {
54282d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
54382d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        }
54482d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
5451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View create(Context context, View convertView, ViewGroup parent,
5461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                LayoutInflater inflater) {
54782d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler            willCreate();
54882d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
5496243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            View v = inflater.inflate(R
5501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                            .layout.global_actions_item, parent, false);
5511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            ImageView icon = (ImageView) v.findViewById(R.id.icon);
5531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TextView messageView = (TextView) v.findViewById(R.id.message);
5541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TextView statusView = (TextView) v.findViewById(R.id.status);
5556243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            final boolean enabled = isEnabled();
5561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5576243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (messageView != null) {
5586243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                messageView.setText(mMessageResId);
5596243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                messageView.setEnabled(enabled);
5606243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
5611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            boolean on = ((mState == State.On) || (mState == State.TurningOn));
5636243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (icon != null) {
5646243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                icon.setImageDrawable(context.getResources().getDrawable(
5656243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                        (on ? mEnabledIconResId : mDisabledIconResid)));
5666243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                icon.setEnabled(enabled);
5676243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
5681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5696243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (statusView != null) {
5706243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                statusView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId);
5716243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                statusView.setVisibility(View.VISIBLE);
5726243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                statusView.setEnabled(enabled);
5736243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
5741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            v.setEnabled(enabled);
5751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return v;
5771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public final void onPress() {
5801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (mState.inTransition()) {
5811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                Log.w(TAG, "shouldn't be able to toggle when in transition");
5821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return;
5831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
5841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            final boolean nowOn = !(mState == State.On);
5861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            onToggle(nowOn);
5871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            changeStateFromPress(nowOn);
5881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
59019caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        public boolean onLongPress() {
59119caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn            return false;
59219caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        }
59319caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn
5941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled() {
5951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return !mState.inTransition();
5961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
5991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * Implementations may override this if their state can be in on of the intermediate
6001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * states until some notification is received (e.g airplane mode is 'turning off' until
6011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * we know the wireless connections are back online
6021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param buttonOn Whether the button was turned on or off
6031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
6041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected void changeStateFromPress(boolean buttonOn) {
6051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mState = buttonOn ? State.On : State.Off;
6061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        abstract void onToggle(boolean on);
6091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void updateState(State state) {
6111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mState = state;
6121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
6141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
6157ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private class SilentModeToggleAction extends ToggleAction {
6167ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        public SilentModeToggleAction() {
6177ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            super(R.drawable.ic_audio_vol_mute,
6187ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    R.drawable.ic_audio_vol,
6197ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    R.string.global_action_toggle_silent_mode,
6207ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    R.string.global_action_silent_mode_on_status,
6217ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                    R.string.global_action_silent_mode_off_status);
6227ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
6237ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
6247ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        void onToggle(boolean on) {
6257ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            if (on) {
6267ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
6277ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            } else {
6287ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
6297ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            }
6307ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
6317ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
6327ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        public boolean showDuringKeyguard() {
6337ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            return true;
6347ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
6357ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
6367ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        public boolean showBeforeProvisioning() {
6377ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            return false;
6387ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
6397ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    }
6407ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
6417ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private static class SilentModeTriStateAction implements Action, View.OnClickListener {
6426243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
6436243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private final int[] ITEM_IDS = { R.id.option1, R.id.option2, R.id.option3 };
6446243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
6456243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private final AudioManager mAudioManager;
6466243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private final Handler mHandler;
647135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        private final Context mContext;
6486243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
6497ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        SilentModeTriStateAction(Context context, AudioManager audioManager, Handler handler) {
6506243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mAudioManager = audioManager;
6516243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mHandler = handler;
652135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            mContext = context;
6536243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
6546243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
6556243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private int ringerModeToIndex(int ringerMode) {
6566243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            // They just happen to coincide
6576243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return ringerMode;
6586243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
6596243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
6606243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private int indexToRingerMode(int index) {
6616243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            // They just happen to coincide
6626243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return index;
6636243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
6646243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
6656243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public View create(Context context, View convertView, ViewGroup parent,
6666243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                LayoutInflater inflater) {
6676243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            View v = inflater.inflate(R.layout.global_actions_silent_mode, parent, false);
6686243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
6696243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            int selectedIndex = ringerModeToIndex(mAudioManager.getRingerMode());
6706243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            for (int i = 0; i < 3; i++) {
6716243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                View itemView = v.findViewById(ITEM_IDS[i]);
6726243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                itemView.setSelected(selectedIndex == i);
6736243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                // Set up click handler
6746243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                itemView.setTag(i);
6756243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                itemView.setOnClickListener(this);
6766243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
6776243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return v;
6786243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
6796243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
6806243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public void onPress() {
6816243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
6826243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
68319caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        public boolean onLongPress() {
68419caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn            return false;
68519caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn        }
68619caadc08f09cc9f6665fbbb0d61e02861ce8562Dianne Hackborn
6876243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public boolean showDuringKeyguard() {
6886243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return true;
6896243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
6906243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
6916243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public boolean showBeforeProvisioning() {
6926243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return false;
6936243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
6946243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
6956243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public boolean isEnabled() {
6966243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return true;
6976243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
6986243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
6996243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        void willCreate() {
7006243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
7016243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
7026243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public void onClick(View v) {
7036243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (!(v.getTag() instanceof Integer)) return;
7046243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
7056243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            int index = (Integer) v.getTag();
7066243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mAudioManager.setRingerMode(indexToRingerMode(index));
7076243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mHandler.sendEmptyMessageDelayed(MESSAGE_DISMISS, DIALOG_DISMISS_DELAY);
7086243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
7096243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    }
7106243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
7111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
7121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void onReceive(Context context, Intent intent) {
7131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            String action = intent.getAction();
71478866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
71578866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato                    || Intent.ACTION_SCREEN_OFF.equals(action)) {
7161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                String reason = intent.getStringExtra(PhoneWindowManager.SYSTEM_DIALOG_REASON_KEY);
71778866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato                if (!PhoneWindowManager.SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS.equals(reason)) {
7181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mHandler.sendEmptyMessage(MESSAGE_DISMISS);
7191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
720fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo            } else if (TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED.equals(action)) {
721fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // Airplane mode can be changed after ECM exits if airplane toggle button
722fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // is pressed during ECM mode
723fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                if (!(intent.getBooleanExtra("PHONE_IN_ECM_STATE", false)) &&
724fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                        mIsWaitingForEcmExit) {
725fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mIsWaitingForEcmExit = false;
726fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    changeAirplaneModeSystemSetting(true);
727fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                }
7281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
7291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
7301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
7311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
7331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
7341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void onServiceStateChanged(ServiceState serviceState) {
7357ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            if (!mHasTelephony) return;
7361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            final boolean inAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF;
7371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAirplaneState = inAirplaneMode ? ToggleAction.State.On : ToggleAction.State.Off;
7381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAirplaneModeOn.updateState(mAirplaneState);
7391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAdapter.notifyDataSetChanged();
7401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
7411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
7421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
7436243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private BroadcastReceiver mRingerModeReceiver = new BroadcastReceiver() {
7446243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        @Override
7456243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public void onReceive(Context context, Intent intent) {
7466243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (intent.getAction().equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
7476243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                mHandler.sendEmptyMessage(MESSAGE_REFRESH);
7486243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
7496243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
7506243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    };
7516243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
7527ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private ContentObserver mAirplaneModeObserver = new ContentObserver(new Handler()) {
7537ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        @Override
7547ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        public void onChange(boolean selfChange) {
7557ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            onAirplaneModeChanged();
7567ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
7577ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    };
7587ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
7591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static final int MESSAGE_DISMISS = 0;
7606243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private static final int MESSAGE_REFRESH = 1;
7612efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani    private static final int MESSAGE_SHOW = 2;
7626243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private static final int DIALOG_DISMISS_DELAY = 300; // ms
7636243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
7641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private Handler mHandler = new Handler() {
7651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void handleMessage(Message msg) {
7662efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            switch (msg.what) {
7672efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            case MESSAGE_DISMISS:
7681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mDialog != null) {
7691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mDialog.dismiss();
7701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
7712efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani                break;
7722efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            case MESSAGE_REFRESH:
7737ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                refreshSilentMode();
7746243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                mAdapter.notifyDataSetChanged();
7752efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani                break;
7762efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani            case MESSAGE_SHOW:
7772efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani                handleShow();
7782efb6a94ca528beb96e26bd3ad2f4b995fb75b49Amith Yamasani                break;
7791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
7801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
7811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
782fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo
7837ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    private void onAirplaneModeChanged() {
7847ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        // Let the service state callbacks handle the state.
7857ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        if (mHasTelephony) return;
7867ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
7877ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        boolean airplaneModeOn = Settings.System.getInt(
7887ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                mContext.getContentResolver(),
7897ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                Settings.System.AIRPLANE_MODE_ON,
7907ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani                0) == 1;
7917ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        mAirplaneState = airplaneModeOn ? ToggleAction.State.On : ToggleAction.State.Off;
7927ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        mAirplaneModeOn.updateState(mAirplaneState);
7937ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani    }
7947ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani
795fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    /**
796fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo     * Change the airplane mode system setting
797fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo     */
798fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    private void changeAirplaneModeSystemSetting(boolean on) {
799fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        Settings.System.putInt(
800fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                mContext.getContentResolver(),
801fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                Settings.System.AIRPLANE_MODE_ON,
802fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                on ? 1 : 0);
803fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
804818ba11cd680de336fb9278b64a21dc2efb7517eDianne Hackborn        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
805fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        intent.putExtra("state", on);
806fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        mContext.sendBroadcast(intent);
8077ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        if (!mHasTelephony) {
8087ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani            mAirplaneState = on ? ToggleAction.State.On : ToggleAction.State.Off;
8097ee994d728acf2b3b3297a67001f2d21c9094109Amith Yamasani        }
810fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    }
811135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani
812135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani    private IWindowManager getWindowManager() {
813135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        if (mIWindowManager == null) {
814135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            IBinder b = ServiceManager.getService(Context.WINDOW_SERVICE);
815135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            mIWindowManager = IWindowManager.Stub.asInterface(b);
816135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        }
817135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        return mIWindowManager;
818135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani    }
8191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project}
820