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