GlobalActions.java revision 82d6c68b396323789e52c407b18ee4a7eab11a24
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)
13182d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler                    ? R.drawable.ic_lock_silent_mode
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)
2241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                .setInverseBackgroundForced(true)
2251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                .setTitle(R.string.global_actions);
2261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        final AlertDialog dialog = ab.create();
2281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
2298d93c3e46cc975b93a6c56d2813e5600d643b99dDianne Hackborn        if (!mContext.getResources().getBoolean(
2308d93c3e46cc975b93a6c56d2813e5600d643b99dDianne Hackborn                com.android.internal.R.bool.config_sf_slowBlur)) {
2318d93c3e46cc975b93a6c56d2813e5600d643b99dDianne Hackborn            dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
2328d93c3e46cc975b93a6c56d2813e5600d643b99dDianne Hackborn                    WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
2338d93c3e46cc975b93a6c56d2813e5600d643b99dDianne Hackborn        }
2341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        dialog.setOnDismissListener(this);
2361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return dialog;
2381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
2391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private void prepareDialog() {
2411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        final boolean silentModeOn =
2421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
2431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mSilentModeToggle.updateState(
2441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                silentModeOn ? ToggleAction.State.On : ToggleAction.State.Off);
2451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAirplaneModeOn.updateState(mAirplaneState);
2461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAdapter.notifyDataSetChanged();
2471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (mKeyguardShowing) {
2481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
2491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else {
250fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo            mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
2511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
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
3191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            throw new IllegalArgumentException("position " + position + " out of "
3201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    + "range of showable actions, filtered count = "
3211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    + "= " + getCount() + ", keyguardshowing=" + mKeyguardShowing
3221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    + ", provisioned=" + mDeviceProvisioned);
3231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public long getItemId(int position) {
3271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return position;
3281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View getView(int position, View convertView, ViewGroup parent) {
3311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            Action action = getItem(position);
3321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
3331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
3351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // note: the scheme below made more sense when we were planning on having
3371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // 8 different things in the global actions dialog.  seems overkill with
3381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // only 3 items now, but may as well keep this flexible approach so it will
3391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // be easy should someone decide at the last minute to include something
3401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // else, such as 'enable wifi', or 'enable bluetooth'
3411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
3431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * What each item in the global actions dialog must be able to support.
3441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
3451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private interface Action {
3461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        View create(Context context, View convertView, ViewGroup parent, LayoutInflater inflater);
3471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        void onPress();
3491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
3511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @return whether this action should appear in the dialog when the keygaurd
3521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         *    is showing.
3531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
3541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean showDuringKeyguard();
3551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
3571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @return whether this action should appear in the dialog before the
3581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         *   device is provisioned.
3591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
3601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean showBeforeProvisioning();
3611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean isEnabled();
3631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
3641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
3661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * A single press action maintains no state, just responds to a press
3671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * and takes an action.
3681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
3691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static abstract class SinglePressAction implements Action {
3701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        private final int mIconResId;
3711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        private final int mMessageResId;
3721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected SinglePressAction(int iconResId, int messageResId) {
3741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mIconResId = iconResId;
3751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mMessageResId = messageResId;
3761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled() {
3791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return true;
3801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        abstract public void onPress();
3831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View create(
3851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
3861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            View v = (convertView != null) ?
3871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    convertView :
3881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    inflater.inflate(R.layout.global_actions_item, parent, false);
3891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            ImageView icon = (ImageView) v.findViewById(R.id.icon);
3911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TextView messageView = (TextView) v.findViewById(R.id.message);
3921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            v.findViewById(R.id.status).setVisibility(View.GONE);
3941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            icon.setImageDrawable(context.getResources().getDrawable(mIconResId));
3961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            messageView.setText(mMessageResId);
3971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return v;
3991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
4011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
4031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * A toggle action knows whether it is on or off, and displays an icon
4041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * and status message accordingly.
4051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
4061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static abstract class ToggleAction implements Action {
4071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        enum State {
4091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            Off(false),
4101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TurningOn(true),
4111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TurningOff(true),
4121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            On(false);
4131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            private final boolean inTransition;
4151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            State(boolean intermediate) {
4171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                inTransition = intermediate;
4181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
4191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean inTransition() {
4211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return inTransition;
4221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
4231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected State mState = State.Off;
4261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // prefs
42882d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mEnabledIconResId;
42982d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mDisabledIconResid;
43082d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mMessageResId;
43182d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mEnabledStatusMessageResId;
43282d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mDisabledStatusMessageResId;
4331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
4351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param enabledIconResId The icon for when this action is on.
4361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param disabledIconResid The icon for when this action is off.
4371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param essage The general information message, e.g 'Silent Mode'
4381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param enabledStatusMessageResId The on status message, e.g 'sound disabled'
4391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param disabledStatusMessageResId The off status message, e.g. 'sound enabled'
4401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
4411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public ToggleAction(int enabledIconResId,
4421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int disabledIconResid,
4431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int essage,
4441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int enabledStatusMessageResId,
4451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int disabledStatusMessageResId) {
4461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mEnabledIconResId = enabledIconResId;
4471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDisabledIconResid = disabledIconResid;
4481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mMessageResId = essage;
4491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mEnabledStatusMessageResId = enabledStatusMessageResId;
4501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDisabledStatusMessageResId = disabledStatusMessageResId;
4511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
45382d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        /**
45482d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         * Override to make changes to resource IDs just before creating the
45582d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         * View.
45682d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         */
45782d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        void willCreate() {
45882d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
45982d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        }
46082d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
4611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View create(Context context, View convertView, ViewGroup parent,
4621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                LayoutInflater inflater) {
46382d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler            willCreate();
46482d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
4651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            View v = (convertView != null) ?
4661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    convertView :
4671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    inflater.inflate(R
4681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                            .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            TextView statusView = (TextView) v.findViewById(R.id.status);
4731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            messageView.setText(mMessageResId);
4751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            boolean on = ((mState == State.On) || (mState == State.TurningOn));
4771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            icon.setImageDrawable(context.getResources().getDrawable(
4781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    (on ? mEnabledIconResId : mDisabledIconResid)));
4791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            statusView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId);
4801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            statusView.setVisibility(View.VISIBLE);
4811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            final boolean enabled = isEnabled();
4831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            messageView.setEnabled(enabled);
4841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            statusView.setEnabled(enabled);
4851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            icon.setEnabled(enabled);
4861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            v.setEnabled(enabled);
4871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return v;
4891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public final void onPress() {
4921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (mState.inTransition()) {
4931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                Log.w(TAG, "shouldn't be able to toggle when in transition");
4941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return;
4951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
4961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            final boolean nowOn = !(mState == State.On);
4981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            onToggle(nowOn);
4991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            changeStateFromPress(nowOn);
5001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled() {
5031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return !mState.inTransition();
5041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
5071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * Implementations may override this if their state can be in on of the intermediate
5081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * states until some notification is received (e.g airplane mode is 'turning off' until
5091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * we know the wireless connections are back online
5101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param buttonOn Whether the button was turned on or off
5111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
5121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected void changeStateFromPress(boolean buttonOn) {
5131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mState = buttonOn ? State.On : State.Off;
5141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        abstract void onToggle(boolean on);
5171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void updateState(State state) {
5191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mState = state;
5201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
5221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
5241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void onReceive(Context context, Intent intent) {
5251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            String action = intent.getAction();
52678866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
52778866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato                    || Intent.ACTION_SCREEN_OFF.equals(action)) {
5281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                String reason = intent.getStringExtra(PhoneWindowManager.SYSTEM_DIALOG_REASON_KEY);
52978866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato                if (!PhoneWindowManager.SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS.equals(reason)) {
5301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mHandler.sendEmptyMessage(MESSAGE_DISMISS);
5311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
532fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo            } else if (TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED.equals(action)) {
533fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // Airplane mode can be changed after ECM exits if airplane toggle button
534fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // is pressed during ECM mode
535fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                if (!(intent.getBooleanExtra("PHONE_IN_ECM_STATE", false)) &&
536fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                        mIsWaitingForEcmExit) {
537fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mIsWaitingForEcmExit = false;
538fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    changeAirplaneModeSystemSetting(true);
539fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                }
5401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
5411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
5431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
5451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
5461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void onServiceStateChanged(ServiceState serviceState) {
5471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            final boolean inAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF;
5481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAirplaneState = inAirplaneMode ? ToggleAction.State.On : ToggleAction.State.Off;
5491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAirplaneModeOn.updateState(mAirplaneState);
5501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAdapter.notifyDataSetChanged();
5511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
5531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static final int MESSAGE_DISMISS = 0;
5551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private Handler mHandler = new Handler() {
5561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void handleMessage(Message msg) {
5571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (msg.what == MESSAGE_DISMISS) {
5581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mDialog != null) {
5591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mDialog.dismiss();
5601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
5611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
5621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
564fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo
565fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    /**
566fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo     * Change the airplane mode system setting
567fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo     */
568fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    private void changeAirplaneModeSystemSetting(boolean on) {
569fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        Settings.System.putInt(
570fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                mContext.getContentResolver(),
571fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                Settings.System.AIRPLANE_MODE_ON,
572fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                on ? 1 : 0);
573fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
574818ba11cd680de336fb9278b64a21dc2efb7517eDianne Hackborn        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
575fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        intent.putExtra("state", on);
576fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        mContext.sendBroadcast(intent);
577fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    }
5781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project}
579