GlobalActions.java revision c1a9b03a35b833e639e35fe3298ed8e71b7657e9
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
19fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guoimport android.app.Activity;
201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.app.AlertDialog;
211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.app.StatusBarManager;
221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.BroadcastReceiver;
231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Context;
241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.DialogInterface;
251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Intent;
261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.IntentFilter;
271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.media.AudioManager;
281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.Handler;
291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.Message;
30fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guoimport android.os.SystemProperties;
311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.provider.Settings;
321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.telephony.PhoneStateListener;
331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.telephony.ServiceState;
341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.telephony.TelephonyManager;
351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.util.Log;
361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.LayoutInflater;
371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.View;
381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.ViewGroup;
391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.WindowManager;
401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.BaseAdapter;
411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.ImageView;
421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.TextView;
431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport com.android.internal.R;
44b7e787fd409a6135eecdd5e32bbe9c60872a4f6fDianne Hackbornimport com.android.internal.app.ShutdownThread;
45fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guoimport com.android.internal.telephony.TelephonyIntents;
46fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guoimport com.android.internal.telephony.TelephonyProperties;
471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport com.google.android.collect.Lists;
481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport java.util.ArrayList;
501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/**
521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Helper to show the global actions dialog.  Each item is an {@link Action} that
531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * may show depending on whether the keyguard is showing, and whether the device
541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * is provisioned.
551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */
561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectclass GlobalActions implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener  {
571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static final String TAG = "GlobalActions";
591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private StatusBarManager mStatusBar;
611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final Context mContext;
631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final AudioManager mAudioManager;
641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ArrayList<Action> mItems;
661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private AlertDialog mDialog;
671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ToggleAction mSilentModeToggle;
691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ToggleAction mAirplaneModeOn;
701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private MyAdapter mAdapter;
721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mKeyguardShowing = false;
741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mDeviceProvisioned = false;
751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ToggleAction.State mAirplaneState = ToggleAction.State.Off;
76fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    private boolean mIsWaitingForEcmExit = false;
771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @param context everything needs a context :(
801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public GlobalActions(Context context) {
821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mContext = context;
831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // receive broadcasts
861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        IntentFilter filter = new IntentFilter();
871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
8878866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato        filter.addAction(Intent.ACTION_SCREEN_OFF);
89fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        context.registerReceiver(mBroadcastReceiver, filter);
911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // get notified of phone state changes
931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        TelephonyManager telephonyManager =
941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Show the global actions dialog (creating if necessary)
1001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @param keyguardShowing True if keyguard is showing
1011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) {
1031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mKeyguardShowing = keyguardShowing;
1041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mDeviceProvisioned = isDeviceProvisioned;
1051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (mDialog == null) {
1061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mStatusBar = (StatusBarManager)mContext.getSystemService(Context.STATUS_BAR_SERVICE);
1071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDialog = createDialog();
1081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
1091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        prepareDialog();
1101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mStatusBar.disable(StatusBarManager.DISABLE_EXPAND);
1121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mDialog.show();
1131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Create the global actions dialog.
1171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @return A new dialog.
1181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private AlertDialog createDialog() {
1201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mSilentModeToggle = new ToggleAction(
1211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.drawable.ic_lock_silent_mode,
1221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.drawable.ic_lock_silent_mode_off,
1231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_action_toggle_silent_mode,
1241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_action_silent_mode_on_status,
1251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_action_silent_mode_off_status) {
1261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
12782d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler            void willCreate() {
12882d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler                // XXX: FIXME: switch to ic_lock_vibrate_mode when available
12982d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler                mEnabledIconResId = (Settings.System.getInt(mContext.getContentResolver(),
13082d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler                        Settings.System.VIBRATE_IN_SILENT, 1) == 1)
131055ea248a40897dcf9bc09241135f4003e69a562Daniel Sandler                    ? R.drawable.ic_lock_silent_mode_vibrate
13282d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler                    : R.drawable.ic_lock_silent_mode;
13382d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler            }
13482d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
1351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            void onToggle(boolean on) {
13682d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler                if (on) {
13782d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler                    mAudioManager.setRingerMode((Settings.System.getInt(mContext.getContentResolver(),
13882d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler                        Settings.System.VIBRATE_IN_SILENT, 1) == 1)
13982d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler                        ? AudioManager.RINGER_MODE_VIBRATE
14082d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler                        : AudioManager.RINGER_MODE_SILENT);
14182d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler                } else {
14282d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler                    mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
14382d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler                }
1441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
1451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean showDuringKeyguard() {
1471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return true;
1481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
1491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean showBeforeProvisioning() {
1511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return false;
1521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
1531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        };
1541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAirplaneModeOn = new ToggleAction(
1561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.drawable.ic_lock_airplane_mode,
1571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.drawable.ic_lock_airplane_mode_off,
1581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_actions_toggle_airplane_mode,
1591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_actions_airplane_mode_on_status,
1601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_actions_airplane_mode_off_status) {
1611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            void onToggle(boolean on) {
163fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                if (Boolean.parseBoolean(
164fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                        SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
165fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mIsWaitingForEcmExit = true;
166fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    // Launch ECM exit dialog
167fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    Intent ecmDialogIntent =
168fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                            new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null);
169fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    ecmDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
170fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mContext.startActivity(ecmDialogIntent);
171fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                } else {
172fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    changeAirplaneModeSystemSetting(on);
173fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                }
1741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
1751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            @Override
1771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            protected void changeStateFromPress(boolean buttonOn) {
178fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // In ECM mode airplane state cannot be changed
179fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                if (!(Boolean.parseBoolean(
180fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                        SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)))) {
181fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mState = buttonOn ? State.TurningOn : State.TurningOff;
182fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mAirplaneState = mState;
183fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                }
1841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
1851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean showDuringKeyguard() {
1871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return true;
1881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
1891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean showBeforeProvisioning() {
1911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return false;
1921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
1931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        };
1941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mItems = Lists.newArrayList(
1961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // silent mode
1971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                mSilentModeToggle,
1981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // next: airplane mode
1991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                mAirplaneModeOn,
2001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                // last: power off
2011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                new SinglePressAction(
2021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                        com.android.internal.R.drawable.ic_lock_power_off,
2031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                        R.string.global_action_power_off) {
2041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    public void onPress() {
2061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                        // shutdown by making sure radio and power are handled accordingly.
207b7e787fd409a6135eecdd5e32bbe9c60872a4f6fDianne Hackborn                        ShutdownThread.shutdown(mContext, true);
2081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    }
2091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    public boolean showDuringKeyguard() {
2111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                        return true;
2121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    }
2131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    public boolean showBeforeProvisioning() {
2151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                        return true;
2161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    }
2171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                });
2181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAdapter = new MyAdapter();
2201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        final AlertDialog.Builder ab = new AlertDialog.Builder(mContext);
2221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        ab.setAdapter(mAdapter, this)
224e79223ed415ca437aa5954f8bfdaf11309f6338aAnders Hammar                .setInverseBackgroundForced(true);
2251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        final AlertDialog dialog = ab.create();
2271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
2288d93c3e46cc975b93a6c56d2813e5600d643b99dDianne Hackborn        if (!mContext.getResources().getBoolean(
2298d93c3e46cc975b93a6c56d2813e5600d643b99dDianne Hackborn                com.android.internal.R.bool.config_sf_slowBlur)) {
2308d93c3e46cc975b93a6c56d2813e5600d643b99dDianne Hackborn            dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
2318d93c3e46cc975b93a6c56d2813e5600d643b99dDianne Hackborn                    WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
2328d93c3e46cc975b93a6c56d2813e5600d643b99dDianne Hackborn        }
2331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        dialog.setOnDismissListener(this);
2351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return dialog;
2371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
2381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private void prepareDialog() {
2401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        final boolean silentModeOn =
2411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
2421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mSilentModeToggle.updateState(
2431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                silentModeOn ? ToggleAction.State.On : ToggleAction.State.Off);
2441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAirplaneModeOn.updateState(mAirplaneState);
2451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAdapter.notifyDataSetChanged();
2461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (mKeyguardShowing) {
2471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
2481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else {
249fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo            mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
2501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
251e79223ed415ca437aa5954f8bfdaf11309f6338aAnders Hammar        mDialog.setTitle(R.string.global_actions);
2521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
2531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /** {@inheritDoc} */
2561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void onDismiss(DialogInterface dialog) {
2571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mStatusBar.disable(StatusBarManager.DISABLE_NONE);
2581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
2591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /** {@inheritDoc} */
2611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void onClick(DialogInterface dialog, int which) {
2621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        dialog.dismiss();
2631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAdapter.getItem(which).onPress();
2641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
2651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
2681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * The adapter used for the list within the global actions dialog, taking
2691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * into account whether the keyguard is showing via
2701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * {@link GlobalActions#mKeyguardShowing} and whether the device is provisioned
2711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * via {@link GlobalActions#mDeviceProvisioned}.
2721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
2731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private class MyAdapter extends BaseAdapter {
2741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public int getCount() {
2761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            int count = 0;
2771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            for (int i = 0; i < mItems.size(); i++) {
2791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                final Action action = mItems.get(i);
2801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mKeyguardShowing && !action.showDuringKeyguard()) {
2821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
2831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
2841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (!mDeviceProvisioned && !action.showBeforeProvisioning()) {
2851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
2861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
2871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                count++;
2881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
2891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return count;
2901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
2911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
2931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled(int position) {
2941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return getItem(position).isEnabled();
2951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
2961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
2981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean areAllItemsEnabled() {
2991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return false;
3001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public Action getItem(int position) {
3031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            int filteredPos = 0;
3051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            for (int i = 0; i < mItems.size(); i++) {
3061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                final Action action = mItems.get(i);
3071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mKeyguardShowing && !action.showDuringKeyguard()) {
3081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
3091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
3101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (!mDeviceProvisioned && !action.showBeforeProvisioning()) {
3111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
3121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
3131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (filteredPos == position) {
3141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    return action;
3151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
3161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                filteredPos++;
3171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
3181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
319c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer            throw new IllegalArgumentException("position " + position
320c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer                    + " out of range of showable actions"
321c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer                    + ", filtered count=" + getCount()
322c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer                    + ", keyguardshowing=" + mKeyguardShowing
3231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    + ", provisioned=" + mDeviceProvisioned);
3241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public long getItemId(int position) {
3281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return position;
3291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View getView(int position, View convertView, ViewGroup parent) {
3321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            Action action = getItem(position);
3331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
3341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
3361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // note: the scheme below made more sense when we were planning on having
3381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // 8 different things in the global actions dialog.  seems overkill with
3391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // only 3 items now, but may as well keep this flexible approach so it will
3401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // be easy should someone decide at the last minute to include something
3411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // else, such as 'enable wifi', or 'enable bluetooth'
3421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
3441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * What each item in the global actions dialog must be able to support.
3451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
3461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private interface Action {
3471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        View create(Context context, View convertView, ViewGroup parent, LayoutInflater inflater);
3481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        void onPress();
3501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
3521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @return whether this action should appear in the dialog when the keygaurd
3531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         *    is showing.
3541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
3551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean showDuringKeyguard();
3561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
3581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @return whether this action should appear in the dialog before the
3591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         *   device is provisioned.
3601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
3611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean showBeforeProvisioning();
3621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean isEnabled();
3641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
3651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
3671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * A single press action maintains no state, just responds to a press
3681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * and takes an action.
3691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
3701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static abstract class SinglePressAction implements Action {
3711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        private final int mIconResId;
3721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        private final int mMessageResId;
3731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected SinglePressAction(int iconResId, int messageResId) {
3751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mIconResId = iconResId;
3761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mMessageResId = messageResId;
3771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled() {
3801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return true;
3811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        abstract public void onPress();
3841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View create(
3861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
3871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            View v = (convertView != null) ?
3881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    convertView :
3891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    inflater.inflate(R.layout.global_actions_item, parent, false);
3901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            ImageView icon = (ImageView) v.findViewById(R.id.icon);
3921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TextView messageView = (TextView) v.findViewById(R.id.message);
3931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            v.findViewById(R.id.status).setVisibility(View.GONE);
3951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            icon.setImageDrawable(context.getResources().getDrawable(mIconResId));
3971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            messageView.setText(mMessageResId);
3981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return v;
4001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
4021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
4041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * A toggle action knows whether it is on or off, and displays an icon
4051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * and status message accordingly.
4061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
4071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static abstract class ToggleAction implements Action {
4081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        enum State {
4101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            Off(false),
4111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TurningOn(true),
4121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TurningOff(true),
4131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            On(false);
4141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            private final boolean inTransition;
4161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            State(boolean intermediate) {
4181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                inTransition = intermediate;
4191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
4201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean inTransition() {
4221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return inTransition;
4231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
4241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected State mState = State.Off;
4271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // prefs
42982d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mEnabledIconResId;
43082d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mDisabledIconResid;
43182d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mMessageResId;
43282d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mEnabledStatusMessageResId;
43382d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mDisabledStatusMessageResId;
4341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
4361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param enabledIconResId The icon for when this action is on.
4371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param disabledIconResid The icon for when this action is off.
4381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param essage The general information message, e.g 'Silent Mode'
4391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param enabledStatusMessageResId The on status message, e.g 'sound disabled'
4401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param disabledStatusMessageResId The off status message, e.g. 'sound enabled'
4411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
4421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public ToggleAction(int enabledIconResId,
4431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int disabledIconResid,
4441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int essage,
4451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int enabledStatusMessageResId,
4461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int disabledStatusMessageResId) {
4471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mEnabledIconResId = enabledIconResId;
4481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDisabledIconResid = disabledIconResid;
4491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mMessageResId = essage;
4501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mEnabledStatusMessageResId = enabledStatusMessageResId;
4511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDisabledStatusMessageResId = disabledStatusMessageResId;
4521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
45482d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        /**
45582d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         * Override to make changes to resource IDs just before creating the
45682d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         * View.
45782d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         */
45882d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        void willCreate() {
45982d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
46082d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        }
46182d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
4621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View create(Context context, View convertView, ViewGroup parent,
4631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                LayoutInflater inflater) {
46482d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler            willCreate();
46582d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
4661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            View v = (convertView != null) ?
4671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    convertView :
4681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    inflater.inflate(R
4691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                            .layout.global_actions_item, parent, false);
4701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            ImageView icon = (ImageView) v.findViewById(R.id.icon);
4721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TextView messageView = (TextView) v.findViewById(R.id.message);
4731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TextView statusView = (TextView) v.findViewById(R.id.status);
4741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            messageView.setText(mMessageResId);
4761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            boolean on = ((mState == State.On) || (mState == State.TurningOn));
4781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            icon.setImageDrawable(context.getResources().getDrawable(
4791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    (on ? mEnabledIconResId : mDisabledIconResid)));
4801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            statusView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId);
4811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            statusView.setVisibility(View.VISIBLE);
4821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            final boolean enabled = isEnabled();
4841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            messageView.setEnabled(enabled);
4851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            statusView.setEnabled(enabled);
4861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            icon.setEnabled(enabled);
4871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            v.setEnabled(enabled);
4881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return v;
4901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public final void onPress() {
4931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (mState.inTransition()) {
4941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                Log.w(TAG, "shouldn't be able to toggle when in transition");
4951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return;
4961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
4971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            final boolean nowOn = !(mState == State.On);
4991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            onToggle(nowOn);
5001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            changeStateFromPress(nowOn);
5011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled() {
5041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return !mState.inTransition();
5051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
5081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * Implementations may override this if their state can be in on of the intermediate
5091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * states until some notification is received (e.g airplane mode is 'turning off' until
5101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * we know the wireless connections are back online
5111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param buttonOn Whether the button was turned on or off
5121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
5131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected void changeStateFromPress(boolean buttonOn) {
5141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mState = buttonOn ? State.On : State.Off;
5151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        abstract void onToggle(boolean on);
5181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void updateState(State state) {
5201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mState = state;
5211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
5251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void onReceive(Context context, Intent intent) {
5261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            String action = intent.getAction();
52778866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
52878866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato                    || Intent.ACTION_SCREEN_OFF.equals(action)) {
5291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                String reason = intent.getStringExtra(PhoneWindowManager.SYSTEM_DIALOG_REASON_KEY);
53078866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato                if (!PhoneWindowManager.SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS.equals(reason)) {
5311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mHandler.sendEmptyMessage(MESSAGE_DISMISS);
5321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
533fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo            } else if (TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED.equals(action)) {
534fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // Airplane mode can be changed after ECM exits if airplane toggle button
535fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // is pressed during ECM mode
536fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                if (!(intent.getBooleanExtra("PHONE_IN_ECM_STATE", false)) &&
537fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                        mIsWaitingForEcmExit) {
538fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mIsWaitingForEcmExit = false;
539fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    changeAirplaneModeSystemSetting(true);
540fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                }
5411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
5421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
5441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
5461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
5471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void onServiceStateChanged(ServiceState serviceState) {
5481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            final boolean inAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF;
5491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAirplaneState = inAirplaneMode ? ToggleAction.State.On : ToggleAction.State.Off;
5501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAirplaneModeOn.updateState(mAirplaneState);
5511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAdapter.notifyDataSetChanged();
5521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
5541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static final int MESSAGE_DISMISS = 0;
5561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private Handler mHandler = new Handler() {
5571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void handleMessage(Message msg) {
5581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (msg.what == MESSAGE_DISMISS) {
5591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mDialog != null) {
5601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mDialog.dismiss();
5611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
5621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
5631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
565fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo
566fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    /**
567fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo     * Change the airplane mode system setting
568fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo     */
569fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    private void changeAirplaneModeSystemSetting(boolean on) {
570fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        Settings.System.putInt(
571fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                mContext.getContentResolver(),
572fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                Settings.System.AIRPLANE_MODE_ON,
573fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                on ? 1 : 0);
574fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
575818ba11cd680de336fb9278b64a21dc2efb7517eDianne Hackborn        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
576fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        intent.putExtra("state", on);
577fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        mContext.sendBroadcast(intent);
578fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    }
5791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project}
580