QuickSettings.java revision efba3235fcd5b71e17de13edd4be9819970014a9
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    }
163
164    private void queryForUserInformation() {
165        System.out.println("queryForUserInformation");
166
167        Uri userContactUri = Uri.withAppendedPath(
168            ContactsContract.Profile.CONTENT_URI,
169            ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
170
171        String[] selectArgs = {
172            ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
173            ContactsContract.CommonDataKinds.Photo.PHOTO
174        };
175        String where = String.format("(%s = ? OR %s = ?) AND %s IS NULL",
176            ContactsContract.Contacts.Data.MIMETYPE,
177            ContactsContract.Contacts.Data.MIMETYPE,
178            ContactsContract.RawContacts.ACCOUNT_TYPE);
179        String[] whereArgs = {
180            ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE,
181            ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
182        };
183
184        mUserInfoLoader = new CursorLoader(mContext, userContactUri, selectArgs, where, whereArgs,
185                null);
186        mUserInfoLoader.registerListener(0,
187                new Loader.OnLoadCompleteListener<Cursor>() {
188                    @Override
189                    public void onLoadComplete(Loader<Cursor> loader,
190                            Cursor cursor) {
191                        UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
192                        if (cursor != null && cursor.moveToFirst()) {
193                            String name = cursor.getString(0); // DISPLAY_NAME
194                            BitmapDrawable d = new BitmapDrawable(userManager.getUserIcon(userManager.getUserHandle()));
195                            mModel.setUserTileInfo(name, d);
196                            /*
197                            byte[] photoData = cursor.getBlob(0);
198                            Bitmap b =
199                                BitmapFactory.decodeByteArray(photoData, 0, photoData.length);
200                             */
201                        }
202                        mUserInfoLoader.stopLoading();
203                    }
204                });
205        mUserInfoLoader.startLoading();
206    }
207
208    private void setupQuickSettings() {
209        // Setup the tiles that we are going to be showing (including the temporary ones)
210        LayoutInflater inflater = LayoutInflater.from(mContext);
211
212        addUserTiles(mContainerView, inflater);
213        addSystemTiles(mContainerView, inflater);
214        addTemporaryTiles(mContainerView, inflater);
215
216        queryForUserInformation();
217    }
218
219    private void startSettingsActivity(String action) {
220        Intent intent = new Intent(action);
221        startSettingsActivity(intent);
222    }
223
224    private void startSettingsActivity(Intent intent) {
225        startSettingsActivity(intent, true);
226    }
227
228    private void startSettingsActivity(Intent intent, boolean onlyProvisioned) {
229        if (onlyProvisioned && !getService().isDeviceProvisioned()) return;
230        try {
231            // Dismiss the lock screen when Settings starts.
232            ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
233        } catch (RemoteException e) {
234        }
235        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
236        mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
237        getService().animateCollapseNotifications();
238    }
239
240    private void addUserTiles(ViewGroup parent, LayoutInflater inflater) {
241        QuickSettingsTileView userTile = (QuickSettingsTileView)
242                inflater.inflate(R.layout.quick_settings_tile, parent, false);
243        userTile.setContent(R.layout.quick_settings_tile_user, inflater);
244        userTile.setOnClickListener(new View.OnClickListener() {
245            @Override
246            public void onClick(View v) {
247                mBar.collapseAllPanels(true);
248                ContactsContract.QuickContact.showQuickContact(mContext, v,
249                        ContactsContract.Profile.CONTENT_URI,
250                        ContactsContract.QuickContact.MODE_LARGE, null);
251            }
252        });
253        mModel.addUserTile(userTile, new QuickSettingsModel.RefreshCallback() {
254            @Override
255            public void refreshView(QuickSettingsTileView view, State state) {
256                UserState us = (UserState) state;
257                ImageView iv = (ImageView) view.findViewById(R.id.user_imageview);
258                TextView tv = (TextView) view.findViewById(R.id.user_textview);
259                tv.setText(state.label);
260                if (us.avatar != null) {
261                    iv.setImageDrawable(us.avatar);
262                }
263            }
264        });
265        parent.addView(userTile);
266        mDynamicSpannedTiles.add(userTile);
267
268        // Time tile
269        QuickSettingsTileView timeTile = (QuickSettingsTileView)
270                inflater.inflate(R.layout.quick_settings_tile, parent, false);
271        timeTile.setContent(R.layout.quick_settings_tile_time, inflater);
272        timeTile.setOnClickListener(new View.OnClickListener() {
273            @Override
274            public void onClick(View v) {
275                // TODO: Jump into the clock application
276                Intent intent = new Intent();
277                intent.setComponent(new ComponentName(
278                        "com.google.android.deskclock",
279                        "com.android.deskclock.DeskClock"));
280                startSettingsActivity(intent);
281            }
282        });
283        mModel.addTimeTile(timeTile, new QuickSettingsModel.RefreshCallback() {
284            @Override
285            public void refreshView(QuickSettingsTileView view, State alarmState) {}
286        });
287        parent.addView(timeTile);
288        mDynamicSpannedTiles.add(timeTile);
289
290        // Settings tile
291        QuickSettingsTileView settingsTile = (QuickSettingsTileView)
292                inflater.inflate(R.layout.quick_settings_tile, parent, false);
293        settingsTile.setContent(R.layout.quick_settings_tile_settings, inflater);
294        settingsTile.setOnClickListener(new View.OnClickListener() {
295            @Override
296            public void onClick(View v) {
297                startSettingsActivity(android.provider.Settings.ACTION_SETTINGS);
298            }
299        });
300        mModel.addSettingsTile(settingsTile, new QuickSettingsModel.RefreshCallback() {
301            @Override
302            public void refreshView(QuickSettingsTileView view, State state) {
303                TextView tv = (TextView) view.findViewById(R.id.settings_tileview);
304                tv.setText(state.label);
305            }
306        });
307        parent.addView(settingsTile);
308        mDynamicSpannedTiles.add(settingsTile);
309    }
310
311    private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) {
312        // Wi-fi
313        QuickSettingsTileView wifiTile = (QuickSettingsTileView)
314                inflater.inflate(R.layout.quick_settings_tile, parent, false);
315        wifiTile.setContent(R.layout.quick_settings_tile_wifi, inflater);
316        wifiTile.setOnClickListener(new View.OnClickListener() {
317            @Override
318            public void onClick(View v) {
319                startSettingsActivity(android.provider.Settings.ACTION_WIFI_SETTINGS);
320            }
321        });
322        mModel.addWifiTile(wifiTile, new QuickSettingsModel.RefreshCallback() {
323            @Override
324            public void refreshView(QuickSettingsTileView view, State state) {
325                TextView tv = (TextView) view.findViewById(R.id.wifi_textview);
326                tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
327                tv.setText(state.label);
328            }
329        });
330        parent.addView(wifiTile);
331
332        if (mModel.deviceSupportsTelephony()) {
333            // RSSI
334            QuickSettingsTileView rssiTile = (QuickSettingsTileView)
335                    inflater.inflate(R.layout.quick_settings_tile, parent, false);
336            rssiTile.setContent(R.layout.quick_settings_tile_rssi, inflater);
337            rssiTile.setOnClickListener(new View.OnClickListener() {
338                @Override
339                public void onClick(View v) {
340                    Intent intent = new Intent();
341                    intent.setComponent(new ComponentName(
342                            "com.android.settings",
343                            "com.android.settings.Settings$DataUsageSummaryActivity"));
344                    startSettingsActivity(intent);
345                }
346            });
347            mModel.addRSSITile(rssiTile, new QuickSettingsModel.RefreshCallback() {
348                @Override
349                public void refreshView(QuickSettingsTileView view, State state) {
350                    RSSIState rssiState = (RSSIState) state;
351                    ImageView iv = (ImageView) view.findViewById(R.id.rssi_image);
352                    ImageView iov = (ImageView) view.findViewById(R.id.rssi_overlay_image);
353                    TextView tv = (TextView) view.findViewById(R.id.rssi_textview);
354                    iv.setImageResource(rssiState.signalIconId);
355                    if (rssiState.dataTypeIconId > 0) {
356                        iov.setImageResource(rssiState.dataTypeIconId);
357                    } else {
358                        iov.setImageDrawable(null);
359                    }
360                    tv.setText(state.label);
361                }
362            });
363            parent.addView(rssiTile);
364        }
365
366        // Rotation Lock
367        if (mContext.getResources().getBoolean(R.bool.quick_settings_show_rotation_lock)) {
368            QuickSettingsTileView rotationLockTile = (QuickSettingsTileView)
369                    inflater.inflate(R.layout.quick_settings_tile, parent, false);
370            rotationLockTile.setContent(R.layout.quick_settings_tile_rotation_lock, inflater);
371            rotationLockTile.setOnClickListener(new View.OnClickListener() {
372                @Override
373                public void onClick(View v) {
374                    boolean locked = RotationPolicy.isRotationLocked(mContext);
375                    RotationPolicy.setRotationLock(mContext, !locked);
376                }
377            });
378            mModel.addRotationLockTile(rotationLockTile, new QuickSettingsModel.RefreshCallback() {
379                @Override
380                public void refreshView(QuickSettingsTileView view, State state) {
381                    TextView tv = (TextView) view.findViewById(R.id.rotation_lock_textview);
382                    tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
383                    tv.setText(state.label);
384                }
385            });
386            parent.addView(rotationLockTile);
387        }
388
389        // Battery
390        QuickSettingsTileView batteryTile = (QuickSettingsTileView)
391                inflater.inflate(R.layout.quick_settings_tile, parent, false);
392        batteryTile.setContent(R.layout.quick_settings_tile_battery, inflater);
393        batteryTile.setOnClickListener(new View.OnClickListener() {
394            @Override
395            public void onClick(View v) {
396                startSettingsActivity(Intent.ACTION_POWER_USAGE_SUMMARY);
397            }
398        });
399        mModel.addBatteryTile(batteryTile, new QuickSettingsModel.RefreshCallback() {
400            @Override
401            public void refreshView(QuickSettingsTileView view, State state) {
402                QuickSettingsModel.BatteryState batteryState =
403                        (QuickSettingsModel.BatteryState) state;
404                TextView tv = (TextView) view.findViewById(R.id.battery_textview);
405                ImageView iv = (ImageView) view.findViewById(R.id.battery_image);
406                Drawable d = batteryState.pluggedIn
407                        ? mChargingBatteryLevels
408                        : mBatteryLevels;
409                String t;
410                if (batteryState.batteryLevel == 100) {
411                    t = mContext.getString(R.string.quick_settings_battery_charged_label);
412                } else {
413                    t = batteryState.pluggedIn
414                        ? mContext.getString(R.string.quick_settings_battery_charging_label,
415                                batteryState.batteryLevel)
416                        : mContext.getString(R.string.status_bar_settings_battery_meter_format,
417                                batteryState.batteryLevel);
418                }
419                iv.setImageDrawable(d);
420                iv.setImageLevel(batteryState.batteryLevel);
421                tv.setText(t);
422            }
423        });
424        parent.addView(batteryTile);
425
426        // Airplane Mode
427        QuickSettingsTileView airplaneTile = (QuickSettingsTileView)
428                inflater.inflate(R.layout.quick_settings_tile, parent, false);
429        airplaneTile.setContent(R.layout.quick_settings_tile_airplane, inflater);
430        mModel.addAirplaneModeTile(airplaneTile, new QuickSettingsModel.RefreshCallback() {
431            @Override
432            public void refreshView(QuickSettingsTileView view, State state) {
433                TextView tv = (TextView) view.findViewById(R.id.airplane_mode_textview);
434                tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
435                tv.setText(state.label);
436            }
437        });
438        parent.addView(airplaneTile);
439
440        // Bluetooth
441        if (mModel.deviceSupportsBluetooth()) {
442            QuickSettingsTileView bluetoothTile = (QuickSettingsTileView)
443                    inflater.inflate(R.layout.quick_settings_tile, parent, false);
444            bluetoothTile.setContent(R.layout.quick_settings_tile_bluetooth, inflater);
445            bluetoothTile.setOnClickListener(new View.OnClickListener() {
446                @Override
447                public void onClick(View v) {
448                    startSettingsActivity(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS);
449                }
450            });
451            mModel.addBluetoothTile(bluetoothTile, new QuickSettingsModel.RefreshCallback() {
452                @Override
453                public void refreshView(QuickSettingsTileView view, State state) {
454                    TextView tv = (TextView) view.findViewById(R.id.bluetooth_textview);
455                    tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
456
457                    Resources r = mContext.getResources();
458                    String label = state.label;
459                    /*
460                    //TODO: Show connected bluetooth device label
461                    Set<BluetoothDevice> btDevices =
462                            mBluetoothController.getBondedBluetoothDevices();
463                    if (btDevices.size() == 1) {
464                        // Show the name of the bluetooth device you are connected to
465                        label = btDevices.iterator().next().getName();
466                    } else if (btDevices.size() > 1) {
467                        // Show a generic label about the number of bluetooth devices
468                        label = r.getString(R.string.quick_settings_bluetooth_multiple_devices_label,
469                                btDevices.size());
470                    }
471                    */
472                    tv.setText(label);
473                }
474            });
475            parent.addView(bluetoothTile);
476        }
477
478        // Brightness
479        QuickSettingsTileView brightnessTile = (QuickSettingsTileView)
480                inflater.inflate(R.layout.quick_settings_tile, parent, false);
481        brightnessTile.setContent(R.layout.quick_settings_tile_brightness, inflater);
482        brightnessTile.setOnClickListener(new View.OnClickListener() {
483            @Override
484            public void onClick(View v) {
485                mBar.collapseAllPanels(true);
486                showBrightnessDialog();
487            }
488        });
489        mModel.addBrightnessTile(brightnessTile, new QuickSettingsModel.RefreshCallback() {
490            @Override
491            public void refreshView(QuickSettingsTileView view, State state) {
492                TextView tv = (TextView) view.findViewById(R.id.brightness_textview);
493                tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
494                tv.setText(state.label);
495                dismissBrightnessDialog(mBrightnessDialogShortTimeout);
496            }
497        });
498        parent.addView(brightnessTile);
499    }
500
501    private void addTemporaryTiles(final ViewGroup parent, final LayoutInflater inflater) {
502        // Alarm tile
503        QuickSettingsTileView alarmTile = (QuickSettingsTileView)
504                inflater.inflate(R.layout.quick_settings_tile, parent, false);
505        alarmTile.setContent(R.layout.quick_settings_tile_alarm, inflater);
506        alarmTile.setOnClickListener(new View.OnClickListener() {
507            @Override
508            public void onClick(View v) {
509                // TODO: Jump into the alarm application
510                Intent intent = new Intent();
511                intent.setComponent(new ComponentName(
512                        "com.google.android.deskclock",
513                        "com.android.deskclock.AlarmClock"));
514                startSettingsActivity(intent);
515            }
516        });
517        mModel.addAlarmTile(alarmTile, new QuickSettingsModel.RefreshCallback() {
518            @Override
519            public void refreshView(QuickSettingsTileView view, State alarmState) {
520                TextView tv = (TextView) view.findViewById(R.id.alarm_textview);
521                tv.setText(alarmState.label);
522                view.setVisibility(alarmState.enabled ? View.VISIBLE : View.GONE);
523            }
524        });
525        parent.addView(alarmTile);
526
527        // Location
528        QuickSettingsTileView locationTile = (QuickSettingsTileView)
529                inflater.inflate(R.layout.quick_settings_tile, parent, false);
530        locationTile.setContent(R.layout.quick_settings_tile_location, inflater);
531        locationTile.setOnClickListener(new View.OnClickListener() {
532            @Override
533            public void onClick(View v) {
534                startSettingsActivity(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
535            }
536        });
537        mModel.addLocationTile(locationTile, new QuickSettingsModel.RefreshCallback() {
538            @Override
539            public void refreshView(QuickSettingsTileView view, State state) {
540                TextView tv = (TextView) view.findViewById(R.id.location_textview);
541                tv.setText(state.label);
542                view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
543            }
544        });
545        parent.addView(locationTile);
546
547        // Wifi Display
548        QuickSettingsTileView wifiDisplayTile = (QuickSettingsTileView)
549                inflater.inflate(R.layout.quick_settings_tile, parent, false);
550        wifiDisplayTile.setContent(R.layout.quick_settings_tile_wifi_display, inflater);
551        wifiDisplayTile.setOnClickListener(new View.OnClickListener() {
552            @Override
553            public void onClick(View v) {
554                startSettingsActivity(android.provider.Settings.ACTION_WIFI_DISPLAY_SETTINGS);
555            }
556        });
557        mModel.addWifiDisplayTile(wifiDisplayTile, new QuickSettingsModel.RefreshCallback() {
558            @Override
559            public void refreshView(QuickSettingsTileView view, State state) {
560                TextView tv = (TextView) view.findViewById(R.id.wifi_display_textview);
561                tv.setText(state.label);
562                view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
563            }
564        });
565        parent.addView(wifiDisplayTile);
566
567        // IME
568        QuickSettingsTileView imeTile = (QuickSettingsTileView)
569                inflater.inflate(R.layout.quick_settings_tile, parent, false);
570        imeTile.setContent(R.layout.quick_settings_tile_ime, inflater);
571        imeTile.setOnClickListener(new View.OnClickListener() {
572            @Override
573            public void onClick(View v) {
574                try {
575                    mBar.collapseAllPanels(true);
576                    Intent intent = new Intent(Settings.ACTION_SHOW_INPUT_METHOD_PICKER);
577                    PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
578                    pendingIntent.send();
579                } catch (Exception e) {}
580            }
581        });
582        mModel.addImeTile(imeTile, new QuickSettingsModel.RefreshCallback() {
583            @Override
584            public void refreshView(QuickSettingsTileView view, State state) {
585                TextView tv = (TextView) view.findViewById(R.id.ime_textview);
586                if (state.label != null) {
587                    tv.setText(state.label);
588                }
589                view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
590            }
591        });
592        parent.addView(imeTile);
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                    SystemProperties.set("ctl.start", "bugreport");
710                }
711            }
712        });
713        builder.setMessage(com.android.internal.R.string.bugreport_message);
714        builder.setTitle(com.android.internal.R.string.bugreport_title);
715        builder.setCancelable(true);
716        final Dialog dialog = builder.create();
717        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
718        dialog.show();
719    }
720
721    private void updateWifiDisplayStatus() {
722        mWifiDisplayStatus = mDisplayManager.getWifiDisplayStatus();
723        applyWifiDisplayStatus();
724    }
725
726    private void applyWifiDisplayStatus() {
727        mModel.onWifiDisplayStateChanged(mWifiDisplayStatus);
728    }
729
730    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
731        @Override
732        public void onReceive(Context context, Intent intent) {
733            if (intent.getAction().equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) {
734                WifiDisplayStatus status = (WifiDisplayStatus)intent.getParcelableExtra(
735                        DisplayManager.EXTRA_WIFI_DISPLAY_STATUS);
736                mWifiDisplayStatus = status;
737                applyWifiDisplayStatus();
738            }
739        }
740    };
741}
742