QuickSettings.java revision 5e08af03a3dffff8b8fc098790e5133589601d8f
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.systemui.statusbar.phone;
18
19import android.app.ActivityManagerNative;
20import android.app.AlertDialog;
21import android.app.Dialog;
22import android.app.PendingIntent;
23import android.content.BroadcastReceiver;
24import android.content.ComponentName;
25import android.content.Context;
26import android.content.CursorLoader;
27import android.content.DialogInterface;
28import android.content.DialogInterface.OnClickListener;
29import android.content.Intent;
30import android.content.IntentFilter;
31import android.content.Loader;
32import android.content.res.Resources;
33import android.database.Cursor;
34import android.graphics.drawable.BitmapDrawable;
35import android.graphics.drawable.Drawable;
36import android.graphics.drawable.LevelListDrawable;
37import android.hardware.display.DisplayManager;
38import android.hardware.display.WifiDisplayStatus;
39import android.net.Uri;
40import android.os.Handler;
41import android.os.RemoteException;
42import android.os.SystemProperties;
43import android.os.UserHandle;
44import android.os.UserManager;
45import android.provider.ContactsContract;
46import android.provider.Settings;
47import android.view.LayoutInflater;
48import android.view.View;
49import android.view.ViewGroup;
50import android.view.Window;
51import android.view.WindowManager;
52import android.widget.ImageView;
53import android.widget.TextView;
54
55import com.android.internal.view.RotationPolicy;
56import com.android.systemui.R;
57import com.android.systemui.statusbar.phone.QuickSettingsModel.RSSIState;
58import com.android.systemui.statusbar.phone.QuickSettingsModel.State;
59import com.android.systemui.statusbar.phone.QuickSettingsModel.UserState;
60import com.android.systemui.statusbar.policy.BatteryController;
61import com.android.systemui.statusbar.policy.BluetoothController;
62import com.android.systemui.statusbar.policy.BrightnessController;
63import com.android.systemui.statusbar.policy.LocationController;
64import com.android.systemui.statusbar.policy.NetworkController;
65import com.android.systemui.statusbar.policy.ToggleSlider;
66
67import java.util.ArrayList;
68
69
70/**
71 *
72 */
73class QuickSettings {
74
75    private Context mContext;
76    private PanelBar mBar;
77    private QuickSettingsModel mModel;
78    private QuickSettingsContainerView mContainerView;
79
80    private DisplayManager mDisplayManager;
81    private WifiDisplayStatus mWifiDisplayStatus;
82    private PhoneStatusBar mStatusBarService;
83
84    private BrightnessController mBrightnessController;
85    private BluetoothController mBluetoothController;
86
87    private Dialog mBrightnessDialog;
88    private int mBrightnessDialogShortTimeout;
89    private int mBrightnessDialogLongTimeout;
90
91    private CursorLoader mUserInfoLoader;
92
93    private LevelListDrawable mBatteryLevels;
94    private LevelListDrawable mChargingBatteryLevels;
95
96    private Handler mHandler;
97
98    // The set of QuickSettingsTiles that have dynamic spans (and need to be updated on
99    // configuration change)
100    private final ArrayList<QuickSettingsTileView> mDynamicSpannedTiles =
101            new ArrayList<QuickSettingsTileView>();
102
103    private final RotationPolicy.RotationPolicyListener mRotationPolicyListener =
104            new RotationPolicy.RotationPolicyListener() {
105        @Override
106        public void onChange() {
107            mModel.onRotationLockChanged();
108        }
109    };
110
111    public QuickSettings(Context context, QuickSettingsContainerView container) {
112        mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
113        mContext = context;
114        mContainerView = container;
115        mModel = new QuickSettingsModel(context);
116        mWifiDisplayStatus = new WifiDisplayStatus();
117        mHandler = new Handler();
118
119        Resources r = mContext.getResources();
120        mBatteryLevels = (LevelListDrawable) r.getDrawable(R.drawable.qs_sys_battery);
121        mChargingBatteryLevels =
122                (LevelListDrawable) r.getDrawable(R.drawable.qs_sys_battery_charging);
123        mBrightnessDialogLongTimeout =
124                r.getInteger(R.integer.quick_settings_brightness_dialog_long_timeout);
125        mBrightnessDialogShortTimeout =
126                r.getInteger(R.integer.quick_settings_brightness_dialog_short_timeout);
127
128        IntentFilter filter = new IntentFilter();
129        filter.addAction(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED);
130        mContext.registerReceiver(mReceiver, filter);
131    }
132
133    void setBar(PanelBar bar) {
134        mBar = bar;
135    }
136
137    public void setService(PhoneStatusBar phoneStatusBar) {
138        mStatusBarService = phoneStatusBar;
139    }
140
141    public PhoneStatusBar getService() {
142        return mStatusBarService;
143    }
144
145    public void setImeWindowStatus(boolean visible) {
146        mModel.onImeWindowStatusChanged(visible);
147    }
148
149    void setup(NetworkController networkController, BluetoothController bluetoothController,
150            BatteryController batteryController, LocationController locationController) {
151        mBluetoothController = bluetoothController;
152
153        setupQuickSettings();
154        updateWifiDisplayStatus();
155        updateResources();
156
157        networkController.addNetworkSignalChangedCallback(mModel);
158        bluetoothController.addStateChangedCallback(mModel);
159        batteryController.addStateChangedCallback(mModel);
160        locationController.addStateChangedCallback(mModel);
161        RotationPolicy.registerRotationPolicyListener(mContext, mRotationPolicyListener,
162                UserHandle.USER_ALL);
163    }
164
165    private void queryForUserInformation() {
166        System.out.println("queryForUserInformation");
167
168        Uri userContactUri = Uri.withAppendedPath(
169            ContactsContract.Profile.CONTENT_URI,
170            ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
171
172        String[] selectArgs = {
173            ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
174            ContactsContract.CommonDataKinds.Photo.PHOTO
175        };
176        String where = String.format("(%s = ? OR %s = ?) AND %s IS NULL",
177            ContactsContract.Contacts.Data.MIMETYPE,
178            ContactsContract.Contacts.Data.MIMETYPE,
179            ContactsContract.RawContacts.ACCOUNT_TYPE);
180        String[] whereArgs = {
181            ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE,
182            ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
183        };
184
185        mUserInfoLoader = new CursorLoader(mContext, userContactUri, selectArgs, where, whereArgs,
186                null);
187        mUserInfoLoader.registerListener(0,
188                new Loader.OnLoadCompleteListener<Cursor>() {
189                    @Override
190                    public void onLoadComplete(Loader<Cursor> loader,
191                            Cursor cursor) {
192                        UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
193                        if (cursor != null && cursor.moveToFirst()) {
194                            String name = cursor.getString(0); // DISPLAY_NAME
195                            BitmapDrawable d = new BitmapDrawable(userManager.getUserIcon(userManager.getUserHandle()));
196                            mModel.setUserTileInfo(name, d);
197                            /*
198                            byte[] photoData = cursor.getBlob(0);
199                            Bitmap b =
200                                BitmapFactory.decodeByteArray(photoData, 0, photoData.length);
201                             */
202                        }
203                        mUserInfoLoader.stopLoading();
204                    }
205                });
206        mUserInfoLoader.startLoading();
207    }
208
209    private void setupQuickSettings() {
210        // Setup the tiles that we are going to be showing (including the temporary ones)
211        LayoutInflater inflater = LayoutInflater.from(mContext);
212
213        addUserTiles(mContainerView, inflater);
214        addSystemTiles(mContainerView, inflater);
215        addTemporaryTiles(mContainerView, inflater);
216
217        queryForUserInformation();
218    }
219
220    private void startSettingsActivity(String action) {
221        Intent intent = new Intent(action);
222        startSettingsActivity(intent);
223    }
224
225    private void startSettingsActivity(Intent intent) {
226        startSettingsActivity(intent, true);
227    }
228
229    private void startSettingsActivity(Intent intent, boolean onlyProvisioned) {
230        if (onlyProvisioned && !getService().isDeviceProvisioned()) return;
231        try {
232            // Dismiss the lock screen when Settings starts.
233            ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
234        } catch (RemoteException e) {
235        }
236        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
237        mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
238        getService().animateCollapseNotifications();
239    }
240
241    private void addUserTiles(ViewGroup parent, LayoutInflater inflater) {
242        QuickSettingsTileView userTile = (QuickSettingsTileView)
243                inflater.inflate(R.layout.quick_settings_tile, parent, false);
244        userTile.setContent(R.layout.quick_settings_tile_user, inflater);
245        userTile.setOnClickListener(new View.OnClickListener() {
246            @Override
247            public void onClick(View v) {
248                mBar.collapseAllPanels(true);
249                ContactsContract.QuickContact.showQuickContact(mContext, v,
250                        ContactsContract.Profile.CONTENT_URI,
251                        ContactsContract.QuickContact.MODE_LARGE, null);
252            }
253        });
254        mModel.addUserTile(userTile, new QuickSettingsModel.RefreshCallback() {
255            @Override
256            public void refreshView(QuickSettingsTileView view, State state) {
257                UserState us = (UserState) state;
258                ImageView iv = (ImageView) view.findViewById(R.id.user_imageview);
259                TextView tv = (TextView) view.findViewById(R.id.user_textview);
260                tv.setText(state.label);
261                if (us.avatar != null) {
262                    iv.setImageDrawable(us.avatar);
263                }
264            }
265        });
266        parent.addView(userTile);
267        mDynamicSpannedTiles.add(userTile);
268
269        // Time tile
270        QuickSettingsTileView timeTile = (QuickSettingsTileView)
271                inflater.inflate(R.layout.quick_settings_tile, parent, false);
272        timeTile.setContent(R.layout.quick_settings_tile_time, inflater);
273        timeTile.setOnClickListener(new View.OnClickListener() {
274            @Override
275            public void onClick(View v) {
276                // TODO: Jump into the clock application
277                Intent intent = new Intent();
278                intent.setComponent(new ComponentName(
279                        "com.google.android.deskclock",
280                        "com.android.deskclock.DeskClock"));
281                startSettingsActivity(intent);
282            }
283        });
284        mModel.addTimeTile(timeTile, new QuickSettingsModel.RefreshCallback() {
285            @Override
286            public void refreshView(QuickSettingsTileView view, State alarmState) {}
287        });
288        parent.addView(timeTile);
289        mDynamicSpannedTiles.add(timeTile);
290
291        // Settings tile
292        QuickSettingsTileView settingsTile = (QuickSettingsTileView)
293                inflater.inflate(R.layout.quick_settings_tile, parent, false);
294        settingsTile.setContent(R.layout.quick_settings_tile_settings, inflater);
295        settingsTile.setOnClickListener(new View.OnClickListener() {
296            @Override
297            public void onClick(View v) {
298                startSettingsActivity(android.provider.Settings.ACTION_SETTINGS);
299            }
300        });
301        mModel.addSettingsTile(settingsTile, new QuickSettingsModel.RefreshCallback() {
302            @Override
303            public void refreshView(QuickSettingsTileView view, State state) {
304                TextView tv = (TextView) view.findViewById(R.id.settings_tileview);
305                tv.setText(state.label);
306            }
307        });
308        parent.addView(settingsTile);
309        mDynamicSpannedTiles.add(settingsTile);
310    }
311
312    private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) {
313        // Wi-fi
314        QuickSettingsTileView wifiTile = (QuickSettingsTileView)
315                inflater.inflate(R.layout.quick_settings_tile, parent, false);
316        wifiTile.setContent(R.layout.quick_settings_tile_wifi, inflater);
317        wifiTile.setOnClickListener(new View.OnClickListener() {
318            @Override
319            public void onClick(View v) {
320                startSettingsActivity(android.provider.Settings.ACTION_WIFI_SETTINGS);
321            }
322        });
323        mModel.addWifiTile(wifiTile, new QuickSettingsModel.RefreshCallback() {
324            @Override
325            public void refreshView(QuickSettingsTileView view, State state) {
326                TextView tv = (TextView) view.findViewById(R.id.wifi_textview);
327                tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
328                tv.setText(state.label);
329            }
330        });
331        parent.addView(wifiTile);
332
333        if (mModel.deviceSupportsTelephony()) {
334            // RSSI
335            QuickSettingsTileView rssiTile = (QuickSettingsTileView)
336                    inflater.inflate(R.layout.quick_settings_tile, parent, false);
337            rssiTile.setContent(R.layout.quick_settings_tile_rssi, inflater);
338            rssiTile.setOnClickListener(new View.OnClickListener() {
339                @Override
340                public void onClick(View v) {
341                    Intent intent = new Intent();
342                    intent.setComponent(new ComponentName(
343                            "com.android.settings",
344                            "com.android.settings.Settings$DataUsageSummaryActivity"));
345                    startSettingsActivity(intent);
346                }
347            });
348            mModel.addRSSITile(rssiTile, new QuickSettingsModel.RefreshCallback() {
349                @Override
350                public void refreshView(QuickSettingsTileView view, State state) {
351                    RSSIState rssiState = (RSSIState) state;
352                    ImageView iv = (ImageView) view.findViewById(R.id.rssi_image);
353                    ImageView iov = (ImageView) view.findViewById(R.id.rssi_overlay_image);
354                    TextView tv = (TextView) view.findViewById(R.id.rssi_textview);
355                    iv.setImageResource(rssiState.signalIconId);
356                    if (rssiState.dataTypeIconId > 0) {
357                        iov.setImageResource(rssiState.dataTypeIconId);
358                    } else {
359                        iov.setImageDrawable(null);
360                    }
361                    tv.setText(state.label);
362                }
363            });
364            parent.addView(rssiTile);
365        }
366
367        // Rotation Lock
368        if (mContext.getResources().getBoolean(R.bool.quick_settings_show_rotation_lock)) {
369            QuickSettingsTileView rotationLockTile = (QuickSettingsTileView)
370                    inflater.inflate(R.layout.quick_settings_tile, parent, false);
371            rotationLockTile.setContent(R.layout.quick_settings_tile_rotation_lock, inflater);
372            rotationLockTile.setOnClickListener(new View.OnClickListener() {
373                @Override
374                public void onClick(View v) {
375                    boolean locked = RotationPolicy.isRotationLocked(mContext);
376                    RotationPolicy.setRotationLock(mContext, !locked);
377                }
378            });
379            mModel.addRotationLockTile(rotationLockTile, new QuickSettingsModel.RefreshCallback() {
380                @Override
381                public void refreshView(QuickSettingsTileView view, State state) {
382                    TextView tv = (TextView) view.findViewById(R.id.rotation_lock_textview);
383                    tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
384                    tv.setText(state.label);
385                }
386            });
387            parent.addView(rotationLockTile);
388        }
389
390        // Battery
391        QuickSettingsTileView batteryTile = (QuickSettingsTileView)
392                inflater.inflate(R.layout.quick_settings_tile, parent, false);
393        batteryTile.setContent(R.layout.quick_settings_tile_battery, inflater);
394        batteryTile.setOnClickListener(new View.OnClickListener() {
395            @Override
396            public void onClick(View v) {
397                startSettingsActivity(Intent.ACTION_POWER_USAGE_SUMMARY);
398            }
399        });
400        mModel.addBatteryTile(batteryTile, new QuickSettingsModel.RefreshCallback() {
401            @Override
402            public void refreshView(QuickSettingsTileView view, State state) {
403                QuickSettingsModel.BatteryState batteryState =
404                        (QuickSettingsModel.BatteryState) state;
405                TextView tv = (TextView) view.findViewById(R.id.battery_textview);
406                ImageView iv = (ImageView) view.findViewById(R.id.battery_image);
407                Drawable d = batteryState.pluggedIn
408                        ? mChargingBatteryLevels
409                        : mBatteryLevels;
410                String t;
411                if (batteryState.batteryLevel == 100) {
412                    t = mContext.getString(R.string.quick_settings_battery_charged_label);
413                } else {
414                    t = batteryState.pluggedIn
415                        ? mContext.getString(R.string.quick_settings_battery_charging_label,
416                                batteryState.batteryLevel)
417                        : mContext.getString(R.string.status_bar_settings_battery_meter_format,
418                                batteryState.batteryLevel);
419                }
420                iv.setImageDrawable(d);
421                iv.setImageLevel(batteryState.batteryLevel);
422                tv.setText(t);
423            }
424        });
425        parent.addView(batteryTile);
426
427        // Airplane Mode
428        QuickSettingsTileView airplaneTile = (QuickSettingsTileView)
429                inflater.inflate(R.layout.quick_settings_tile, parent, false);
430        airplaneTile.setContent(R.layout.quick_settings_tile_airplane, inflater);
431        mModel.addAirplaneModeTile(airplaneTile, new QuickSettingsModel.RefreshCallback() {
432            @Override
433            public void refreshView(QuickSettingsTileView view, State state) {
434                TextView tv = (TextView) view.findViewById(R.id.airplane_mode_textview);
435                tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
436                tv.setText(state.label);
437            }
438        });
439        parent.addView(airplaneTile);
440
441        // Bluetooth
442        if (mModel.deviceSupportsBluetooth()) {
443            QuickSettingsTileView bluetoothTile = (QuickSettingsTileView)
444                    inflater.inflate(R.layout.quick_settings_tile, parent, false);
445            bluetoothTile.setContent(R.layout.quick_settings_tile_bluetooth, inflater);
446            bluetoothTile.setOnClickListener(new View.OnClickListener() {
447                @Override
448                public void onClick(View v) {
449                    startSettingsActivity(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS);
450                }
451            });
452            mModel.addBluetoothTile(bluetoothTile, new QuickSettingsModel.RefreshCallback() {
453                @Override
454                public void refreshView(QuickSettingsTileView view, State state) {
455                    TextView tv = (TextView) view.findViewById(R.id.bluetooth_textview);
456                    tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
457
458                    Resources r = mContext.getResources();
459                    String label = state.label;
460                    /*
461                    //TODO: Show connected bluetooth device label
462                    Set<BluetoothDevice> btDevices =
463                            mBluetoothController.getBondedBluetoothDevices();
464                    if (btDevices.size() == 1) {
465                        // Show the name of the bluetooth device you are connected to
466                        label = btDevices.iterator().next().getName();
467                    } else if (btDevices.size() > 1) {
468                        // Show a generic label about the number of bluetooth devices
469                        label = r.getString(R.string.quick_settings_bluetooth_multiple_devices_label,
470                                btDevices.size());
471                    }
472                    */
473                    tv.setText(label);
474                }
475            });
476            parent.addView(bluetoothTile);
477        }
478
479        // Brightness
480        QuickSettingsTileView brightnessTile = (QuickSettingsTileView)
481                inflater.inflate(R.layout.quick_settings_tile, parent, false);
482        brightnessTile.setContent(R.layout.quick_settings_tile_brightness, inflater);
483        brightnessTile.setOnClickListener(new View.OnClickListener() {
484            @Override
485            public void onClick(View v) {
486                mBar.collapseAllPanels(true);
487                showBrightnessDialog();
488            }
489        });
490        mModel.addBrightnessTile(brightnessTile, new QuickSettingsModel.RefreshCallback() {
491            @Override
492            public void refreshView(QuickSettingsTileView view, State state) {
493                TextView tv = (TextView) view.findViewById(R.id.brightness_textview);
494                tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
495                tv.setText(state.label);
496                dismissBrightnessDialog(mBrightnessDialogShortTimeout);
497            }
498        });
499        parent.addView(brightnessTile);
500    }
501
502    private void addTemporaryTiles(final ViewGroup parent, final LayoutInflater inflater) {
503        // Alarm tile
504        QuickSettingsTileView alarmTile = (QuickSettingsTileView)
505                inflater.inflate(R.layout.quick_settings_tile, parent, false);
506        alarmTile.setContent(R.layout.quick_settings_tile_alarm, inflater);
507        alarmTile.setOnClickListener(new View.OnClickListener() {
508            @Override
509            public void onClick(View v) {
510                // TODO: Jump into the alarm application
511                Intent intent = new Intent();
512                intent.setComponent(new ComponentName(
513                        "com.google.android.deskclock",
514                        "com.android.deskclock.AlarmClock"));
515                startSettingsActivity(intent);
516            }
517        });
518        mModel.addAlarmTile(alarmTile, new QuickSettingsModel.RefreshCallback() {
519            @Override
520            public void refreshView(QuickSettingsTileView view, State alarmState) {
521                TextView tv = (TextView) view.findViewById(R.id.alarm_textview);
522                tv.setText(alarmState.label);
523                view.setVisibility(alarmState.enabled ? View.VISIBLE : View.GONE);
524            }
525        });
526        parent.addView(alarmTile);
527
528        // Location
529        QuickSettingsTileView locationTile = (QuickSettingsTileView)
530                inflater.inflate(R.layout.quick_settings_tile, parent, false);
531        locationTile.setContent(R.layout.quick_settings_tile_location, inflater);
532        locationTile.setOnClickListener(new View.OnClickListener() {
533            @Override
534            public void onClick(View v) {
535                startSettingsActivity(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
536            }
537        });
538        mModel.addLocationTile(locationTile, new QuickSettingsModel.RefreshCallback() {
539            @Override
540            public void refreshView(QuickSettingsTileView view, State state) {
541                TextView tv = (TextView) view.findViewById(R.id.location_textview);
542                tv.setText(state.label);
543                view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
544            }
545        });
546        parent.addView(locationTile);
547
548        // Wifi Display
549        QuickSettingsTileView wifiDisplayTile = (QuickSettingsTileView)
550                inflater.inflate(R.layout.quick_settings_tile, parent, false);
551        wifiDisplayTile.setContent(R.layout.quick_settings_tile_wifi_display, inflater);
552        wifiDisplayTile.setOnClickListener(new View.OnClickListener() {
553            @Override
554            public void onClick(View v) {
555                startSettingsActivity(android.provider.Settings.ACTION_WIFI_DISPLAY_SETTINGS);
556            }
557        });
558        mModel.addWifiDisplayTile(wifiDisplayTile, new QuickSettingsModel.RefreshCallback() {
559            @Override
560            public void refreshView(QuickSettingsTileView view, State state) {
561                TextView tv = (TextView) view.findViewById(R.id.wifi_display_textview);
562                tv.setText(state.label);
563                view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
564            }
565        });
566        parent.addView(wifiDisplayTile);
567
568        // IME
569        QuickSettingsTileView imeTile = (QuickSettingsTileView)
570                inflater.inflate(R.layout.quick_settings_tile, parent, false);
571        imeTile.setContent(R.layout.quick_settings_tile_ime, inflater);
572        imeTile.setOnClickListener(new View.OnClickListener() {
573            @Override
574            public void onClick(View v) {
575                try {
576                    mBar.collapseAllPanels(true);
577                    Intent intent = new Intent(Settings.ACTION_SHOW_INPUT_METHOD_PICKER);
578                    PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
579                    pendingIntent.send();
580                } catch (Exception e) {}
581            }
582        });
583        mModel.addImeTile(imeTile, new QuickSettingsModel.RefreshCallback() {
584            @Override
585            public void refreshView(QuickSettingsTileView view, State state) {
586                TextView tv = (TextView) view.findViewById(R.id.ime_textview);
587                if (state.label != null) {
588                    tv.setText(state.label);
589                }
590                view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
591            }
592        });
593        parent.addView(imeTile);
594
595        // Bug reports
596        QuickSettingsTileView bugreportTile = (QuickSettingsTileView)
597                inflater.inflate(R.layout.quick_settings_tile, parent, false);
598        bugreportTile.setContent(R.layout.quick_settings_tile_bugreport, inflater);
599        bugreportTile.setOnClickListener(new View.OnClickListener() {
600            @Override
601            public void onClick(View v) {
602                mBar.collapseAllPanels(true);
603                showBugreportDialog();
604            }
605        });
606        mModel.addBugreportTile(bugreportTile, new QuickSettingsModel.RefreshCallback() {
607            @Override
608            public void refreshView(QuickSettingsTileView view, State state) {
609                view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
610            }
611        });
612        parent.addView(bugreportTile);
613        /*
614        QuickSettingsTileView mediaTile = (QuickSettingsTileView)
615                inflater.inflate(R.layout.quick_settings_tile, parent, false);
616        mediaTile.setContent(R.layout.quick_settings_tile_media, inflater);
617        parent.addView(mediaTile);
618        QuickSettingsTileView imeTile = (QuickSettingsTileView)
619                inflater.inflate(R.layout.quick_settings_tile, parent, false);
620        imeTile.setContent(R.layout.quick_settings_tile_ime, inflater);
621        imeTile.setOnClickListener(new View.OnClickListener() {
622            @Override
623            public void onClick(View v) {
624                parent.removeViewAt(0);
625            }
626        });
627        parent.addView(imeTile);
628        */
629    }
630
631    void updateResources() {
632        Resources r = mContext.getResources();
633
634        // Update the model
635        mModel.updateResources();
636
637        // Update the User, Time, and Settings tiles spans, and reset everything else
638        int span = r.getInteger(R.integer.quick_settings_user_time_settings_tile_span);
639        for (QuickSettingsTileView v : mDynamicSpannedTiles) {
640            v.setColumnSpan(span);
641        }
642        mContainerView.requestLayout();
643
644        // Reset the dialog
645        boolean isBrightnessDialogVisible = false;
646        if (mBrightnessDialog != null) {
647            removeAllBrightnessDialogCallbacks();
648
649            isBrightnessDialogVisible = mBrightnessDialog.isShowing();
650            mBrightnessDialog.dismiss();
651        }
652        mBrightnessDialog = null;
653        if (isBrightnessDialogVisible) {
654            showBrightnessDialog();
655        }
656    }
657
658    private void removeAllBrightnessDialogCallbacks() {
659        mHandler.removeCallbacks(mDismissBrightnessDialogRunnable);
660    }
661
662    private Runnable mDismissBrightnessDialogRunnable = new Runnable() {
663        public void run() {
664            if (mBrightnessDialog != null && mBrightnessDialog.isShowing()) {
665                mBrightnessDialog.dismiss();
666            }
667            removeAllBrightnessDialogCallbacks();
668        };
669    };
670
671    private void showBrightnessDialog() {
672        if (mBrightnessDialog == null) {
673            mBrightnessDialog = new Dialog(mContext);
674            mBrightnessDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
675            mBrightnessDialog.setContentView(R.layout.quick_settings_brightness_dialog);
676            mBrightnessDialog.setCanceledOnTouchOutside(true);
677
678            mBrightnessController = new BrightnessController(mContext,
679                    (ToggleSlider) mBrightnessDialog.findViewById(R.id.brightness_slider));
680            mBrightnessController.addStateChangedCallback(mModel);
681            mBrightnessDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
682                @Override
683                public void onDismiss(DialogInterface dialog) {
684                    mBrightnessController = null;
685                }
686            });
687
688            mBrightnessDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
689            mBrightnessDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
690        }
691        if (!mBrightnessDialog.isShowing()) {
692            mBrightnessDialog.show();
693            dismissBrightnessDialog(mBrightnessDialogLongTimeout);
694        }
695    }
696
697    private void dismissBrightnessDialog(int timeout) {
698        removeAllBrightnessDialogCallbacks();
699        if (mBrightnessDialog != null) {
700            mHandler.postDelayed(mDismissBrightnessDialogRunnable, timeout);
701        }
702    }
703
704    private void showBugreportDialog() {
705        final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
706        builder.setPositiveButton(com.android.internal.R.string.report, new OnClickListener() {
707            @Override
708            public void onClick(DialogInterface dialog, int which) {
709                if (which == DialogInterface.BUTTON_POSITIVE) {
710                    SystemProperties.set("ctl.start", "bugreport");
711                }
712            }
713        });
714        builder.setMessage(com.android.internal.R.string.bugreport_message);
715        builder.setTitle(com.android.internal.R.string.bugreport_title);
716        builder.setCancelable(true);
717        final Dialog dialog = builder.create();
718        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
719        dialog.show();
720    }
721
722    private void updateWifiDisplayStatus() {
723        mWifiDisplayStatus = mDisplayManager.getWifiDisplayStatus();
724        applyWifiDisplayStatus();
725    }
726
727    private void applyWifiDisplayStatus() {
728        mModel.onWifiDisplayStateChanged(mWifiDisplayStatus);
729    }
730
731    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
732        @Override
733        public void onReceive(Context context, Intent intent) {
734            if (intent.getAction().equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) {
735                WifiDisplayStatus status = (WifiDisplayStatus)intent.getParcelableExtra(
736                        DisplayManager.EXTRA_WIFI_DISPLAY_STATUS);
737                mWifiDisplayStatus = status;
738                applyWifiDisplayStatus();
739            }
740        }
741    };
742}
743