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