GlobalActions.java revision 6243edd818b84adfbe712d5d233d6414b33653ac
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.content.BroadcastReceiver;
221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Context;
231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.DialogInterface;
241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.Intent;
251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.content.IntentFilter;
261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.media.AudioManager;
271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.Handler;
281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.os.Message;
29fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guoimport android.os.SystemProperties;
301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.provider.Settings;
311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.telephony.PhoneStateListener;
321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.telephony.ServiceState;
331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.telephony.TelephonyManager;
341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.util.Log;
351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.LayoutInflater;
361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.View;
371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.ViewGroup;
381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.view.WindowManager;
391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.BaseAdapter;
401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.ImageView;
411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport android.widget.TextView;
421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport com.android.internal.R;
43b7e787fd409a6135eecdd5e32bbe9c60872a4f6fDianne Hackbornimport com.android.internal.app.ShutdownThread;
44fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guoimport com.android.internal.telephony.TelephonyIntents;
45fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guoimport com.android.internal.telephony.TelephonyProperties;
461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport com.google.android.collect.Lists;
471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectimport java.util.ArrayList;
491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project/**
511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * Helper to show the global actions dialog.  Each item is an {@link Action} that
521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * may show depending on whether the keyguard is showing, and whether the device
531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project * is provisioned.
541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project */
551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Projectclass GlobalActions implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener  {
561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static final String TAG = "GlobalActions";
581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
596243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private static final boolean SHOW_SILENT_TOGGLE = true;
602ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani
611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final Context mContext;
621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private final AudioManager mAudioManager;
631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ArrayList<Action> mItems;
651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private AlertDialog mDialog;
661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
676243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private SilentModeAction mSilentModeAction;
681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ToggleAction mAirplaneModeOn;
691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private MyAdapter mAdapter;
711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mKeyguardShowing = false;
731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private boolean mDeviceProvisioned = false;
741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private ToggleAction.State mAirplaneState = ToggleAction.State.Off;
75fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    private boolean mIsWaitingForEcmExit = false;
761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @param context everything needs a context :(
791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public GlobalActions(Context context) {
811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mContext = context;
821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // receive broadcasts
851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        IntentFilter filter = new IntentFilter();
861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
8778866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato        filter.addAction(Intent.ACTION_SCREEN_OFF);
88fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        context.registerReceiver(mBroadcastReceiver, filter);
901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // get notified of phone state changes
921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        TelephonyManager telephonyManager =
931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Show the global actions dialog (creating if necessary)
991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @param keyguardShowing True if keyguard is showing
1001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) {
1021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mKeyguardShowing = keyguardShowing;
1031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mDeviceProvisioned = isDeviceProvisioned;
1041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (mDialog == null) {
1051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDialog = createDialog();
1061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
1071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        prepareDialog();
1081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mDialog.show();
110ec3f05e707044505642cbdb180aff5edf9b926aaDaniel Sandler        mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);
1111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
1121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
1141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * Create the global actions dialog.
1151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * @return A new dialog.
1161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
1171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private AlertDialog createDialog() {
1186243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        mSilentModeAction = new SilentModeAction(mAudioManager, mHandler);
1191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAirplaneModeOn = new ToggleAction(
1211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.drawable.ic_lock_airplane_mode,
1221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.drawable.ic_lock_airplane_mode_off,
1231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_actions_toggle_airplane_mode,
1241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_actions_airplane_mode_on_status,
1251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                R.string.global_actions_airplane_mode_off_status) {
1261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            void onToggle(boolean on) {
128fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                if (Boolean.parseBoolean(
129fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                        SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
130fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mIsWaitingForEcmExit = true;
131fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    // Launch ECM exit dialog
132fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    Intent ecmDialogIntent =
133fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                            new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null);
134fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    ecmDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
135fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mContext.startActivity(ecmDialogIntent);
136fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                } else {
137fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    changeAirplaneModeSystemSetting(on);
138fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                }
1391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
1401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            @Override
1421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            protected void changeStateFromPress(boolean buttonOn) {
143fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // In ECM mode airplane state cannot be changed
144fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                if (!(Boolean.parseBoolean(
145fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                        SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)))) {
146fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mState = buttonOn ? State.TurningOn : State.TurningOff;
147fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mAirplaneState = mState;
148fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                }
1491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
1501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean showDuringKeyguard() {
1521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return true;
1531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
1541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean showBeforeProvisioning() {
1561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return false;
1571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
1581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        };
1591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1602ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani        mItems = new ArrayList<Action>();
1612ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani
1626243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        // first: power off
1632ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani        mItems.add(
1642ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani            new SinglePressAction(
1652ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                    com.android.internal.R.drawable.ic_lock_power_off,
1662ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                    R.string.global_action_power_off) {
1672ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani
1682ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                public void onPress() {
1692ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                    // shutdown by making sure radio and power are handled accordingly.
1702ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                    ShutdownThread.shutdown(mContext, true);
1712ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                }
1722ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani
1732ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                public boolean showDuringKeyguard() {
1742ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                    return true;
1752ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                }
1762ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani
1772ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                public boolean showBeforeProvisioning() {
1782ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                    return true;
1792ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani                }
1802ef6f1bb5603c2e221191117695725237f49a5d5Amith Yamasani            });
1811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1826243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        // next: airplane mode
1836243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        mItems.add(mAirplaneModeOn);
1846243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
1856243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        // last: silent mode
1866243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        if (SHOW_SILENT_TOGGLE) {
1876243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mItems.add(mSilentModeAction);
1886243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
1896243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
1901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAdapter = new MyAdapter();
1911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        final AlertDialog.Builder ab = new AlertDialog.Builder(mContext);
1931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        ab.setAdapter(mAdapter, this)
1956243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                .setInverseBackgroundForced(true);
1961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
1971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        final AlertDialog dialog = ab.create();
1981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
1991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        dialog.setOnDismissListener(this);
2011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        return dialog;
2031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
2041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private void prepareDialog() {
2061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        final boolean silentModeOn =
2071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
2081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAirplaneModeOn.updateState(mAirplaneState);
2091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAdapter.notifyDataSetChanged();
2101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        if (mKeyguardShowing) {
2111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
2121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        } else {
213fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo            mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
2141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
2156243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        if (SHOW_SILENT_TOGGLE) {
2166243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
2176243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mContext.registerReceiver(mRingerModeReceiver, filter);
2186243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
2191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
2201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /** {@inheritDoc} */
2231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void onDismiss(DialogInterface dialog) {
2246243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        if (SHOW_SILENT_TOGGLE) {
2256243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mContext.unregisterReceiver(mRingerModeReceiver);
2266243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
2271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
2281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /** {@inheritDoc} */
2301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    public void onClick(DialogInterface dialog, int which) {
2316243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        if (!(mAdapter.getItem(which) instanceof SilentModeAction)) {
2326243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            dialog.dismiss();
2336243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
2341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        mAdapter.getItem(which).onPress();
2351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
2361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
2381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * The adapter used for the list within the global actions dialog, taking
2391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * into account whether the keyguard is showing via
2401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * {@link GlobalActions#mKeyguardShowing} and whether the device is provisioned
2411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * via {@link GlobalActions#mDeviceProvisioned}.
2421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
2431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private class MyAdapter extends BaseAdapter {
2441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public int getCount() {
2461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            int count = 0;
2471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            for (int i = 0; i < mItems.size(); i++) {
2491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                final Action action = mItems.get(i);
2501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mKeyguardShowing && !action.showDuringKeyguard()) {
2521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
2531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
2541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (!mDeviceProvisioned && !action.showBeforeProvisioning()) {
2551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
2561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
2571f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                count++;
2581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
2591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return count;
2601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
2611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
2631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled(int position) {
2641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return getItem(position).isEnabled();
2651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
2661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
2681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean areAllItemsEnabled() {
2691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return false;
2701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
2711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public Action getItem(int position) {
2731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            int filteredPos = 0;
2751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            for (int i = 0; i < mItems.size(); i++) {
2761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                final Action action = mItems.get(i);
2771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mKeyguardShowing && !action.showDuringKeyguard()) {
2781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
2791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
2801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (!mDeviceProvisioned && !action.showBeforeProvisioning()) {
2811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    continue;
2821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
2831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (filteredPos == position) {
2841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    return action;
2851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
2861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                filteredPos++;
2871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
2881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
289c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer            throw new IllegalArgumentException("position " + position
290c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer                    + " out of range of showable actions"
291c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer                    + ", filtered count=" + getCount()
292c1a9b03a35b833e639e35fe3298ed8e71b7657e9Bernhard Reutner-Fischer                    + ", keyguardshowing=" + mKeyguardShowing
2931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    + ", provisioned=" + mDeviceProvisioned);
2941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
2951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
2971f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public long getItemId(int position) {
2981f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return position;
2991f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3001f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3011f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View getView(int position, View convertView, ViewGroup parent) {
3021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            Action action = getItem(position);
3031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
3041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
3061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // note: the scheme below made more sense when we were planning on having
3081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // 8 different things in the global actions dialog.  seems overkill with
3091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // only 3 items now, but may as well keep this flexible approach so it will
3101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // be easy should someone decide at the last minute to include something
3111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    // else, such as 'enable wifi', or 'enable bluetooth'
3121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
3141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * What each item in the global actions dialog must be able to support.
3151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
3161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private interface Action {
3171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        View create(Context context, View convertView, ViewGroup parent, LayoutInflater inflater);
3181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        void onPress();
3201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
3221f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @return whether this action should appear in the dialog when the keygaurd
3231f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         *    is showing.
3241f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
3251f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean showDuringKeyguard();
3261f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3271f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
3281f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @return whether this action should appear in the dialog before the
3291f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         *   device is provisioned.
3301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
3311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean showBeforeProvisioning();
3321f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3331f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        boolean isEnabled();
3341f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
3351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
3371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * A single press action maintains no state, just responds to a press
3381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * and takes an action.
3391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
3401f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static abstract class SinglePressAction implements Action {
3411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        private final int mIconResId;
3421f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        private final int mMessageResId;
3431f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3441f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected SinglePressAction(int iconResId, int messageResId) {
3451f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mIconResId = iconResId;
3461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mMessageResId = messageResId;
3471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3481f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3491f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled() {
3501f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return true;
3511f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3521f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        abstract public void onPress();
3541f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3551f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View create(
3561f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
3576243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            View v = inflater.inflate(R.layout.global_actions_item, parent, false);
3581f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            ImageView icon = (ImageView) v.findViewById(R.id.icon);
3601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TextView messageView = (TextView) v.findViewById(R.id.message);
3611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            v.findViewById(R.id.status).setVisibility(View.GONE);
3631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            icon.setImageDrawable(context.getResources().getDrawable(mIconResId));
3651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            messageView.setText(mMessageResId);
3661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return v;
3681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
3701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    /**
3721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * A toggle action knows whether it is on or off, and displays an icon
3731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     * and status message accordingly.
3741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project     */
3751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static abstract class ToggleAction implements Action {
3761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        enum State {
3781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            Off(false),
3791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TurningOn(true),
3801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TurningOff(true),
3811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            On(false);
3821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            private final boolean inTransition;
3841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            State(boolean intermediate) {
3861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                inTransition = intermediate;
3871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
3881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            public boolean inTransition() {
3901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return inTransition;
3911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
3921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
3931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected State mState = State.Off;
3951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
3961f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        // prefs
39782d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mEnabledIconResId;
39882d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mDisabledIconResid;
39982d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mMessageResId;
40082d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mEnabledStatusMessageResId;
40182d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        protected int mDisabledStatusMessageResId;
4021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4031f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
4041f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param enabledIconResId The icon for when this action is on.
4051f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param disabledIconResid The icon for when this action is off.
4061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param essage The general information message, e.g 'Silent Mode'
4071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param enabledStatusMessageResId The on status message, e.g 'sound disabled'
4081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param disabledStatusMessageResId The off status message, e.g. 'sound enabled'
4091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
4101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public ToggleAction(int enabledIconResId,
4111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int disabledIconResid,
4121f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int essage,
4131f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int enabledStatusMessageResId,
4141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                int disabledStatusMessageResId) {
4151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mEnabledIconResId = enabledIconResId;
4161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDisabledIconResid = disabledIconResid;
4171f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mMessageResId = essage;
4181f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mEnabledStatusMessageResId = enabledStatusMessageResId;
4191f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mDisabledStatusMessageResId = disabledStatusMessageResId;
4201f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4211f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
42282d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        /**
42382d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         * Override to make changes to resource IDs just before creating the
42482d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         * View.
42582d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler         */
42682d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        void willCreate() {
42782d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
42882d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler        }
42982d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
4301f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public View create(Context context, View convertView, ViewGroup parent,
4311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                LayoutInflater inflater) {
43282d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler            willCreate();
43382d6c68b396323789e52c407b18ee4a7eab11a24Daniel Sandler
4346243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            View v = inflater.inflate(R
4351f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                            .layout.global_actions_item, parent, false);
4361f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4371f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            ImageView icon = (ImageView) v.findViewById(R.id.icon);
4381f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TextView messageView = (TextView) v.findViewById(R.id.message);
4391f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            TextView statusView = (TextView) v.findViewById(R.id.status);
4406243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            final boolean enabled = isEnabled();
4411f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4426243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (messageView != null) {
4436243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                messageView.setText(mMessageResId);
4446243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                messageView.setEnabled(enabled);
4456243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
4461f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4471f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            boolean on = ((mState == State.On) || (mState == State.TurningOn));
4486243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (icon != null) {
4496243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                icon.setImageDrawable(context.getResources().getDrawable(
4506243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                        (on ? mEnabledIconResId : mDisabledIconResid)));
4516243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                icon.setEnabled(enabled);
4526243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
4531f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4546243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (statusView != null) {
4556243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                statusView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId);
4566243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                statusView.setVisibility(View.VISIBLE);
4576243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                statusView.setEnabled(enabled);
4586243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
4591f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            v.setEnabled(enabled);
4601f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4611f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return v;
4621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public final void onPress() {
4651f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (mState.inTransition()) {
4661f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                Log.w(TAG, "shouldn't be able to toggle when in transition");
4671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                return;
4681f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
4691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            final boolean nowOn = !(mState == State.On);
4711f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            onToggle(nowOn);
4721f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            changeStateFromPress(nowOn);
4731f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4741f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4751f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public boolean isEnabled() {
4761f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            return !mState.inTransition();
4771f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4781f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        /**
4801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * Implementations may override this if their state can be in on of the intermediate
4811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * states until some notification is received (e.g airplane mode is 'turning off' until
4821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * we know the wireless connections are back online
4831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         * @param buttonOn Whether the button was turned on or off
4841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project         */
4851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        protected void changeStateFromPress(boolean buttonOn) {
4861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mState = buttonOn ? State.On : State.Off;
4871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        abstract void onToggle(boolean on);
4901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void updateState(State state) {
4921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mState = state;
4931f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
4941f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    }
4951f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
4966243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private static class SilentModeAction implements Action, View.OnClickListener {
4976243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
4986243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private final int[] ITEM_IDS = { R.id.option1, R.id.option2, R.id.option3 };
4996243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
5006243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private final AudioManager mAudioManager;
5016243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private final Handler mHandler;
5026243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
5036243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        SilentModeAction(AudioManager audioManager, Handler handler) {
5046243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mAudioManager = audioManager;
5056243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mHandler = handler;
5066243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
5076243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
5086243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private int ringerModeToIndex(int ringerMode) {
5096243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            // They just happen to coincide
5106243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return ringerMode;
5116243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
5126243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
5136243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        private int indexToRingerMode(int index) {
5146243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            // They just happen to coincide
5156243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return index;
5166243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
5176243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
5186243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public View create(Context context, View convertView, ViewGroup parent,
5196243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                LayoutInflater inflater) {
5206243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            View v = inflater.inflate(R.layout.global_actions_silent_mode, parent, false);
5216243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            // Handle clicks outside the icons and ignore
5226243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            v.setOnClickListener(this);
5236243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
5246243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            int selectedIndex = ringerModeToIndex(mAudioManager.getRingerMode());
5256243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            for (int i = 0; i < 3; i++) {
5266243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                View itemView = v.findViewById(ITEM_IDS[i]);
5276243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                itemView.setSelected(selectedIndex == i);
5286243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                // Set up click handler
5296243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                itemView.setTag(i);
5306243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                itemView.setOnClickListener(this);
5316243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
5326243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return v;
5336243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
5346243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
5356243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public void onPress() {
5366243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
5376243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
5386243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public boolean showDuringKeyguard() {
5396243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return true;
5406243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
5416243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
5426243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public boolean showBeforeProvisioning() {
5436243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return false;
5446243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
5456243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
5466243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public boolean isEnabled() {
5476243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            return true;
5486243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
5496243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
5506243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        void willCreate() {
5516243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
5526243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
5536243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public void onClick(View v) {
5546243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (!(v.getTag() instanceof Integer)) return;
5556243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
5566243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            int index = (Integer) v.getTag();
5576243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mAudioManager.setRingerMode(indexToRingerMode(index));
5586243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            mHandler.sendEmptyMessageDelayed(MESSAGE_DISMISS, DIALOG_DISMISS_DELAY);
5596243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
5606243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    }
5616243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
5621f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
5631f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void onReceive(Context context, Intent intent) {
5641f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            String action = intent.getAction();
56578866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
56678866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato                    || Intent.ACTION_SCREEN_OFF.equals(action)) {
5671f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                String reason = intent.getStringExtra(PhoneWindowManager.SYSTEM_DIALOG_REASON_KEY);
56878866b1e07b1006f6ebf4adbc8e64b558c6040ebJoe Onorato                if (!PhoneWindowManager.SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS.equals(reason)) {
5691f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mHandler.sendEmptyMessage(MESSAGE_DISMISS);
5701f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
571fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo            } else if (TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED.equals(action)) {
572fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // Airplane mode can be changed after ECM exits if airplane toggle button
573fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                // is pressed during ECM mode
574fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                if (!(intent.getBooleanExtra("PHONE_IN_ECM_STATE", false)) &&
575fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                        mIsWaitingForEcmExit) {
576fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    mIsWaitingForEcmExit = false;
577fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                    changeAirplaneModeSystemSetting(true);
578fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                }
5791f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
5801f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5811f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
5821f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5831f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
5841f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        @Override
5851f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void onServiceStateChanged(ServiceState serviceState) {
5861f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            final boolean inAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF;
5871f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAirplaneState = inAirplaneMode ? ToggleAction.State.On : ToggleAction.State.Off;
5881f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAirplaneModeOn.updateState(mAirplaneState);
5891f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            mAdapter.notifyDataSetChanged();
5901f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
5911f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
5921f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project
5936243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private BroadcastReceiver mRingerModeReceiver = new BroadcastReceiver() {
5946243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        @Override
5956243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        public void onReceive(Context context, Intent intent) {
5966243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            if (intent.getAction().equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
5976243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                mHandler.sendEmptyMessage(MESSAGE_REFRESH);
5986243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            }
5996243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani        }
6006243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    };
6016243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
6021f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private static final int MESSAGE_DISMISS = 0;
6036243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private static final int MESSAGE_REFRESH = 1;
6046243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani    private static final int DIALOG_DISMISS_DELAY = 300; // ms
6056243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani
6061f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    private Handler mHandler = new Handler() {
6071f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        public void handleMessage(Message msg) {
6081f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            if (msg.what == MESSAGE_DISMISS) {
6091f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                if (mDialog != null) {
6101f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                    mDialog.dismiss();
6111f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project                }
6126243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani            } else if (msg.what == MESSAGE_REFRESH) {
6136243edd818b84adfbe712d5d233d6414b33653acAmith Yamasani                mAdapter.notifyDataSetChanged();
6141f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project            }
6151f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project        }
6161f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project    };
617fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo
618fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    /**
619fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo     * Change the airplane mode system setting
620fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo     */
621fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    private void changeAirplaneModeSystemSetting(boolean on) {
622fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        Settings.System.putInt(
623fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                mContext.getContentResolver(),
624fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                Settings.System.AIRPLANE_MODE_ON,
625fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo                on ? 1 : 0);
626fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
627818ba11cd680de336fb9278b64a21dc2efb7517eDianne Hackborn        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
628fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        intent.putExtra("state", on);
629fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo        mContext.sendBroadcast(intent);
630fe1fee5545fee91ca0d267067f6ddf2887a7bdd3Jinghui Guo    }
6311f838aaece3cd61d07ab9e41c5c6af761d643324The Android Open Source Project}
632