OSDN Git Service

Add power off button to quick settings dropdown box
[android-x86/frameworks-base.git] / packages / SystemUI / src / com / android / systemui / statusbar / phone / QuickSettings.java
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
17 package com.android.systemui.statusbar.phone;
18
19 import com.android.internal.view.RotationPolicy;
20 import com.android.systemui.R;
21
22 import com.android.systemui.statusbar.phone.QuickSettingsModel.BluetoothState;
23 import com.android.systemui.statusbar.phone.QuickSettingsModel.RSSIState;
24 import com.android.systemui.statusbar.phone.QuickSettingsModel.State;
25 import com.android.systemui.statusbar.phone.QuickSettingsModel.UserState;
26 import com.android.systemui.statusbar.phone.QuickSettingsModel.WifiState;
27 import com.android.systemui.statusbar.policy.BatteryController;
28 import com.android.systemui.statusbar.policy.BluetoothController;
29 import com.android.systemui.statusbar.policy.LocationController;
30 import com.android.systemui.statusbar.policy.NetworkController;
31
32 import android.app.ActivityManagerNative;
33 import android.app.AlertDialog;
34 import android.app.Dialog;
35 import android.app.PendingIntent;
36 import android.bluetooth.BluetoothAdapter;
37 import android.content.BroadcastReceiver;
38 import android.content.ComponentName;
39 import android.content.Context;
40 import android.content.DialogInterface;
41 import android.content.DialogInterface.OnClickListener;
42 import android.content.Intent;
43 import android.content.IntentFilter;
44 import android.content.pm.PackageManager.NameNotFoundException;
45 import android.content.pm.UserInfo;
46 import android.content.res.Resources;
47 import android.database.Cursor;
48 import android.graphics.Bitmap;
49 import android.graphics.drawable.BitmapDrawable;
50 import android.graphics.drawable.Drawable;
51 import android.graphics.drawable.LevelListDrawable;
52 import android.hardware.display.DisplayManager;
53 import android.hardware.display.WifiDisplayStatus;
54 import android.net.wifi.WifiManager;
55 import android.os.AsyncTask;
56 import android.os.Handler;
57 import android.os.RemoteException;
58 import android.os.UserHandle;
59 import android.os.UserManager;
60 import android.provider.ContactsContract;
61 import android.provider.ContactsContract.CommonDataKinds.Phone;
62 import android.provider.ContactsContract.Profile;
63 import android.provider.Settings;
64 import android.util.Log;
65 import android.util.Pair;
66 import android.view.LayoutInflater;
67 import android.view.View;
68 import android.view.ViewGroup;
69 import android.view.WindowManager;
70 import android.view.WindowManagerGlobal;
71 import android.widget.ImageView;
72 import android.widget.TextView;
73
74 import java.util.ArrayList;
75
76
77 /**
78  *
79  */
80 class QuickSettings {
81     static final boolean DEBUG_GONE_TILES = false;
82     private static final String TAG = "QuickSettings";
83     public static final boolean SHOW_IME_TILE = false;
84
85     public static final boolean LONG_PRESS_TOGGLES = true;
86
87     private Context mContext;
88     private PanelBar mBar;
89     private QuickSettingsModel mModel;
90     private ViewGroup mContainerView;
91
92     private DisplayManager mDisplayManager;
93     private WifiDisplayStatus mWifiDisplayStatus;
94     private PhoneStatusBar mStatusBarService;
95     private BluetoothState mBluetoothState;
96     private BluetoothAdapter mBluetoothAdapter;
97     private WifiManager mWifiManager;
98
99     private BluetoothController mBluetoothController;
100
101     private AsyncTask<Void, Void, Pair<String, Drawable>> mUserInfoTask;
102
103     private LevelListDrawable mBatteryLevels;
104     private LevelListDrawable mChargingBatteryLevels;
105
106     boolean mTilesSetUp = false;
107     boolean mUseDefaultAvatar = false;
108
109     private Handler mHandler;
110
111     // The set of QuickSettingsTiles that have dynamic spans (and need to be updated on
112     // configuration change)
113     private final ArrayList<QuickSettingsTileView> mDynamicSpannedTiles =
114             new ArrayList<QuickSettingsTileView>();
115
116     private final RotationPolicy.RotationPolicyListener mRotationPolicyListener =
117             new RotationPolicy.RotationPolicyListener() {
118         @Override
119         public void onChange() {
120             mModel.onRotationLockChanged();
121         }
122     };
123
124     public QuickSettings(Context context, QuickSettingsContainerView container) {
125         mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
126         mContext = context;
127         mContainerView = container;
128         mModel = new QuickSettingsModel(context);
129         mWifiDisplayStatus = new WifiDisplayStatus();
130         mBluetoothState = new QuickSettingsModel.BluetoothState();
131         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
132         mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
133
134         mHandler = new Handler();
135
136         Resources r = mContext.getResources();
137         mBatteryLevels = (LevelListDrawable) r.getDrawable(R.drawable.qs_sys_battery);
138         mChargingBatteryLevels =
139                 (LevelListDrawable) r.getDrawable(R.drawable.qs_sys_battery_charging);
140
141         IntentFilter filter = new IntentFilter();
142         filter.addAction(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED);
143         filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
144         filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
145         filter.addAction(Intent.ACTION_USER_SWITCHED);
146         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
147         mContext.registerReceiver(mReceiver, filter);
148
149         IntentFilter profileFilter = new IntentFilter();
150         profileFilter.addAction(ContactsContract.Intents.ACTION_PROFILE_CHANGED);
151         profileFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
152         mContext.registerReceiverAsUser(mProfileReceiver, UserHandle.ALL, profileFilter,
153                 null, null);
154     }
155
156     void setBar(PanelBar bar) {
157         mBar = bar;
158     }
159
160     public void setService(PhoneStatusBar phoneStatusBar) {
161         mStatusBarService = phoneStatusBar;
162     }
163
164     public PhoneStatusBar getService() {
165         return mStatusBarService;
166     }
167
168     public void setImeWindowStatus(boolean visible) {
169         mModel.onImeWindowStatusChanged(visible);
170     }
171
172     void setup(NetworkController networkController, BluetoothController bluetoothController,
173             BatteryController batteryController, LocationController locationController) {
174         mBluetoothController = bluetoothController;
175
176         setupQuickSettings();
177         updateWifiDisplayStatus();
178         updateResources();
179
180         networkController.addNetworkSignalChangedCallback(mModel);
181         bluetoothController.addStateChangedCallback(mModel);
182         batteryController.addStateChangedCallback(mModel);
183         locationController.addStateChangedCallback(mModel);
184         RotationPolicy.registerRotationPolicyListener(mContext, mRotationPolicyListener,
185                 UserHandle.USER_ALL);
186     }
187
188     private void queryForUserInformation() {
189         Context currentUserContext = null;
190         UserInfo userInfo = null;
191         try {
192             userInfo = ActivityManagerNative.getDefault().getCurrentUser();
193             currentUserContext = mContext.createPackageContextAsUser("android", 0,
194                     new UserHandle(userInfo.id));
195         } catch (NameNotFoundException e) {
196             Log.e(TAG, "Couldn't create user context", e);
197             throw new RuntimeException(e);
198         } catch (RemoteException e) {
199             Log.e(TAG, "Couldn't get user info", e);
200         }
201         final int userId = userInfo.id;
202         final String userName = userInfo.name;
203
204         final Context context = currentUserContext;
205         mUserInfoTask = new AsyncTask<Void, Void, Pair<String, Drawable>>() {
206             @Override
207             protected Pair<String, Drawable> doInBackground(Void... params) {
208                 final UserManager um = UserManager.get(mContext);
209
210                 // Fall back to the UserManager nickname if we can't read the name from the local
211                 // profile below.
212                 String name = userName;
213                 Drawable avatar = null;
214                 Bitmap rawAvatar = um.getUserIcon(userId);
215                 if (rawAvatar != null) {
216                     avatar = new BitmapDrawable(mContext.getResources(), rawAvatar);
217                 } else {
218                     avatar = mContext.getResources().getDrawable(R.drawable.ic_qs_default_user);
219                     mUseDefaultAvatar = true;
220                 }
221
222                 // If it's a single-user device, get the profile name, since the nickname is not
223                 // usually valid
224                 if (um.getUsers().size() <= 1) {
225                     // Try and read the display name from the local profile
226                     final Cursor cursor = context.getContentResolver().query(
227                             Profile.CONTENT_URI, new String[] {Phone._ID, Phone.DISPLAY_NAME},
228                             null, null, null);
229                     if (cursor != null) {
230                         try {
231                             if (cursor.moveToFirst()) {
232                                 name = cursor.getString(cursor.getColumnIndex(Phone.DISPLAY_NAME));
233                             }
234                         } finally {
235                             cursor.close();
236                         }
237                     }
238                 }
239                 return new Pair<String, Drawable>(name, avatar);
240             }
241
242             @Override
243             protected void onPostExecute(Pair<String, Drawable> result) {
244                 super.onPostExecute(result);
245                 mModel.setUserTileInfo(result.first, result.second);
246                 mUserInfoTask = null;
247             }
248         };
249         mUserInfoTask.execute();
250     }
251
252     private void setupQuickSettings() {
253         // Setup the tiles that we are going to be showing (including the temporary ones)
254         LayoutInflater inflater = LayoutInflater.from(mContext);
255
256         addUserTiles(mContainerView, inflater);
257         addSystemTiles(mContainerView, inflater);
258         addTemporaryTiles(mContainerView, inflater);
259
260         queryForUserInformation();
261         mTilesSetUp = true;
262     }
263
264     private void startSettingsActivity(String action) {
265         Intent intent = new Intent(action);
266         startSettingsActivity(intent);
267     }
268
269     private void startSettingsActivity(Intent intent) {
270         startSettingsActivity(intent, true);
271     }
272
273     private void collapsePanels() {
274         getService().animateCollapsePanels();
275     }
276
277     private void startSettingsActivity(Intent intent, boolean onlyProvisioned) {
278         if (onlyProvisioned && !getService().isDeviceProvisioned()) return;
279         try {
280             // Dismiss the lock screen when Settings starts.
281             ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
282         } catch (RemoteException e) {
283         }
284         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
285         mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
286         collapsePanels();
287     }
288
289     private void addUserTiles(ViewGroup parent, LayoutInflater inflater) {
290         QuickSettingsTileView userTile = (QuickSettingsTileView)
291                 inflater.inflate(R.layout.quick_settings_tile, parent, false);
292         userTile.setContent(R.layout.quick_settings_tile_user, inflater);
293         userTile.setOnClickListener(new View.OnClickListener() {
294             @Override
295             public void onClick(View v) {
296                 collapsePanels();
297                 final UserManager um = UserManager.get(mContext);
298                 if (um.getUsers(true).size() > 1) {
299                     try {
300                         WindowManagerGlobal.getWindowManagerService().lockNow(null);
301                     } catch (RemoteException e) {
302                         Log.e(TAG, "Couldn't show user switcher", e);
303                     }
304                 } else {
305                     Intent intent = ContactsContract.QuickContact.composeQuickContactsIntent(
306                             mContext, v, ContactsContract.Profile.CONTENT_URI,
307                             ContactsContract.QuickContact.MODE_LARGE, null);
308                     mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
309                 }
310             }
311         });
312         mModel.addUserTile(userTile, new QuickSettingsModel.RefreshCallback() {
313             @Override
314             public void refreshView(QuickSettingsTileView view, State state) {
315                 UserState us = (UserState) state;
316                 ImageView iv = (ImageView) view.findViewById(R.id.user_imageview);
317                 TextView tv = (TextView) view.findViewById(R.id.user_textview);
318                 tv.setText(state.label);
319                 iv.setImageDrawable(us.avatar);
320                 view.setContentDescription(mContext.getString(
321                         R.string.accessibility_quick_settings_user, state.label));
322             }
323         });
324         parent.addView(userTile);
325         mDynamicSpannedTiles.add(userTile);
326
327         // Brightness
328         final QuickSettingsBasicTile brightnessTile
329                 = new QuickSettingsBasicTile(mContext);
330         brightnessTile.setImageResource(R.drawable.ic_qs_brightness_auto_off);
331         brightnessTile.setOnClickListener(new View.OnClickListener() {
332             @Override
333             public void onClick(View v) {
334                 collapsePanels();
335                 showBrightnessDialog();
336             }
337         });
338         mModel.addBrightnessTile(brightnessTile,
339                 new QuickSettingsModel.BasicRefreshCallback(brightnessTile));
340         parent.addView(brightnessTile);
341         mDynamicSpannedTiles.add(brightnessTile);
342
343         // Time tile
344         /*
345         QuickSettingsTileView timeTile = (QuickSettingsTileView)
346                 inflater.inflate(R.layout.quick_settings_tile, parent, false);
347         timeTile.setContent(R.layout.quick_settings_tile_time, inflater);
348         timeTile.setOnClickListener(new View.OnClickListener() {
349             @Override
350             public void onClick(View v) {
351                 // Quick. Clock. Quick. Clock. Quick. Clock.
352                 startSettingsActivity(Intent.ACTION_QUICK_CLOCK);
353             }
354         });
355         mModel.addTimeTile(timeTile, new QuickSettingsModel.RefreshCallback() {
356             @Override
357             public void refreshView(QuickSettingsTileView view, State alarmState) {}
358         });
359         parent.addView(timeTile);
360         mDynamicSpannedTiles.add(timeTile);
361         */
362
363         // Settings tile
364         final QuickSettingsBasicTile settingsTile = new QuickSettingsBasicTile(mContext);
365         settingsTile.setImageResource(R.drawable.ic_qs_settings);
366         settingsTile.setOnClickListener(new View.OnClickListener() {
367             @Override
368             public void onClick(View v) {
369                 startSettingsActivity(android.provider.Settings.ACTION_SETTINGS);
370             }
371         });
372         mModel.addSettingsTile(settingsTile,
373                 new QuickSettingsModel.BasicRefreshCallback(settingsTile));
374         parent.addView(settingsTile);
375         mDynamicSpannedTiles.add(settingsTile);
376     }
377
378     private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) {
379         // Wi-fi
380         final QuickSettingsBasicTile wifiTile
381                 = new QuickSettingsBasicTile(mContext);
382         wifiTile.setOnClickListener(new View.OnClickListener() {
383             @Override
384             public void onClick(View v) {
385                 startSettingsActivity(android.provider.Settings.ACTION_WIFI_SETTINGS);
386             }
387         });
388         if (LONG_PRESS_TOGGLES) {
389             wifiTile.setOnLongClickListener(new View.OnLongClickListener() {
390                 @Override
391                 public boolean onLongClick(View v) {
392                     final boolean enable =
393                             (mWifiManager.getWifiState() != WifiManager.WIFI_STATE_ENABLED);
394                     new AsyncTask<Void, Void, Void>() {
395                         @Override
396                         protected Void doInBackground(Void... args) {
397                             // Disable tethering if enabling Wifi
398                             final int wifiApState = mWifiManager.getWifiApState();
399                             if (enable && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
400                                            (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
401                                 mWifiManager.setWifiApEnabled(null, false);
402                             }
403
404                             mWifiManager.setWifiEnabled(enable);
405                             return null;
406                         }
407                     }.execute();
408                     wifiTile.setPressed(false);
409                     return true;
410                 }} );
411         }
412         mModel.addWifiTile(wifiTile, new QuickSettingsModel.RefreshCallback() {
413             @Override
414             public void refreshView(QuickSettingsTileView unused, State state) {
415                 WifiState wifiState = (WifiState) state;
416                 wifiTile.setImageResource(wifiState.iconId);
417                 wifiTile.setText(wifiState.label);
418                 wifiTile.setContentDescription(mContext.getString(
419                         R.string.accessibility_quick_settings_wifi,
420                         wifiState.signalContentDescription,
421                         (wifiState.connected) ? wifiState.label : ""));
422             }
423         });
424         parent.addView(wifiTile);
425
426         if (mModel.deviceHasMobileData()) {
427             // RSSI
428             QuickSettingsTileView rssiTile = (QuickSettingsTileView)
429                     inflater.inflate(R.layout.quick_settings_tile, parent, false);
430             rssiTile.setContent(R.layout.quick_settings_tile_rssi, inflater);
431             rssiTile.setOnClickListener(new View.OnClickListener() {
432                 @Override
433                 public void onClick(View v) {
434                     Intent intent = new Intent();
435                     intent.setComponent(new ComponentName(
436                             "com.android.settings",
437                             "com.android.settings.Settings$DataUsageSummaryActivity"));
438                     startSettingsActivity(intent);
439                 }
440             });
441             mModel.addRSSITile(rssiTile, new QuickSettingsModel.RefreshCallback() {
442                 @Override
443                 public void refreshView(QuickSettingsTileView view, State state) {
444                     RSSIState rssiState = (RSSIState) state;
445                     ImageView iv = (ImageView) view.findViewById(R.id.rssi_image);
446                     ImageView iov = (ImageView) view.findViewById(R.id.rssi_overlay_image);
447                     TextView tv = (TextView) view.findViewById(R.id.rssi_textview);
448                     // Force refresh
449                     iv.setImageDrawable(null);
450                     iv.setImageResource(rssiState.signalIconId);
451
452                     if (rssiState.dataTypeIconId > 0) {
453                         iov.setImageResource(rssiState.dataTypeIconId);
454                     } else {
455                         iov.setImageDrawable(null);
456                     }
457                     tv.setText(state.label);
458                     view.setContentDescription(mContext.getResources().getString(
459                             R.string.accessibility_quick_settings_mobile,
460                             rssiState.signalContentDescription, rssiState.dataContentDescription,
461                             state.label));
462                 }
463             });
464             parent.addView(rssiTile);
465         }
466
467         // Rotation Lock
468         if (mContext.getResources().getBoolean(R.bool.quick_settings_show_rotation_lock)
469                 || DEBUG_GONE_TILES) {
470             final QuickSettingsBasicTile rotationLockTile
471                     = new QuickSettingsBasicTile(mContext);
472             rotationLockTile.setOnClickListener(new View.OnClickListener() {
473                 @Override
474                 public void onClick(View v) {
475                     boolean locked = RotationPolicy.isRotationLocked(mContext);
476                     RotationPolicy.setRotationLock(mContext, !locked);
477                 }
478             });
479             mModel.addRotationLockTile(rotationLockTile,
480                     new QuickSettingsModel.BasicRefreshCallback(rotationLockTile));
481             parent.addView(rotationLockTile);
482         }
483
484         // Battery
485         final QuickSettingsBasicTile batteryTile = new QuickSettingsBasicTile(mContext);
486         batteryTile.setOnClickListener(new View.OnClickListener() {
487             @Override
488             public void onClick(View v) {
489                 startSettingsActivity(Intent.ACTION_POWER_USAGE_SUMMARY);
490             }
491         });
492         mModel.addBatteryTile(batteryTile, new QuickSettingsModel.RefreshCallback() {
493             @Override
494             public void refreshView(QuickSettingsTileView unused, State state) {
495                 QuickSettingsModel.BatteryState batteryState =
496                         (QuickSettingsModel.BatteryState) state;
497                 Drawable d = batteryState.pluggedIn
498                         ? mChargingBatteryLevels
499                         : mBatteryLevels;
500                 String t;
501                 if (batteryState.batteryLevel == 100) {
502                     t = mContext.getString(R.string.quick_settings_battery_charged_label);
503                 } else {
504                     t = batteryState.pluggedIn
505                         ? mContext.getString(R.string.quick_settings_battery_charging_label,
506                                 batteryState.batteryLevel)
507                         : mContext.getString(R.string.status_bar_settings_battery_meter_format,
508                                 batteryState.batteryLevel);
509                 }
510                 batteryTile.setImageDrawable(d);
511                 batteryTile.getImageView().setImageLevel(batteryState.batteryLevel);
512                 batteryTile.setText(t);
513                 batteryTile.setContentDescription(
514                         mContext.getString(R.string.accessibility_quick_settings_battery, t));
515             }
516         });
517         parent.addView(batteryTile);
518
519         // Airplane Mode
520         final QuickSettingsBasicTile airplaneTile
521                 = new QuickSettingsBasicTile(mContext);
522         mModel.addAirplaneModeTile(airplaneTile, new QuickSettingsModel.RefreshCallback() {
523             @Override
524             public void refreshView(QuickSettingsTileView unused, State state) {
525                 airplaneTile.setImageResource(state.iconId);
526
527                 String airplaneState = mContext.getString(
528                         (state.enabled) ? R.string.accessibility_desc_on
529                                 : R.string.accessibility_desc_off);
530                 airplaneTile.setContentDescription(
531                         mContext.getString(R.string.accessibility_quick_settings_airplane, airplaneState));
532                 airplaneTile.setText(state.label);
533             }
534         });
535         parent.addView(airplaneTile);
536
537         // Bluetooth
538         if (mModel.deviceSupportsBluetooth()
539                 || DEBUG_GONE_TILES) {
540             final QuickSettingsBasicTile bluetoothTile
541                     = new QuickSettingsBasicTile(mContext);
542             bluetoothTile.setOnClickListener(new View.OnClickListener() {
543                 @Override
544                 public void onClick(View v) {
545                     startSettingsActivity(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS);
546                 }
547             });
548             if (LONG_PRESS_TOGGLES) {
549                 bluetoothTile.setOnLongClickListener(new View.OnLongClickListener() {
550                     @Override
551                     public boolean onLongClick(View v) {
552                         if (mBluetoothAdapter.isEnabled()) {
553                             mBluetoothAdapter.disable();
554                         } else {
555                             mBluetoothAdapter.enable();
556                         }
557                         bluetoothTile.setPressed(false);
558                         return true;
559                     }});
560             }
561             mModel.addBluetoothTile(bluetoothTile, new QuickSettingsModel.RefreshCallback() {
562                 @Override
563                 public void refreshView(QuickSettingsTileView unused, State state) {
564                     BluetoothState bluetoothState = (BluetoothState) state;
565                     bluetoothTile.setImageResource(state.iconId);
566
567                     /*
568                     Resources r = mContext.getResources();
569                     //TODO: Show connected bluetooth device label
570                     Set<BluetoothDevice> btDevices =
571                             mBluetoothController.getBondedBluetoothDevices();
572                     if (btDevices.size() == 1) {
573                         // Show the name of the bluetooth device you are connected to
574                         label = btDevices.iterator().next().getName();
575                     } else if (btDevices.size() > 1) {
576                         // Show a generic label about the number of bluetooth devices
577                         label = r.getString(R.string.quick_settings_bluetooth_multiple_devices_label,
578                                 btDevices.size());
579                     }
580                     */
581                     bluetoothTile.setContentDescription(mContext.getString(
582                             R.string.accessibility_quick_settings_bluetooth,
583                             bluetoothState.stateContentDescription));
584                     bluetoothTile.setText(state.label);
585                 }
586             });
587             parent.addView(bluetoothTile);
588         }
589
590         // Power off
591         QuickSettingsTileView powerOffTile = (QuickSettingsTileView)
592                 inflater.inflate(R.layout.quick_settings_tile, parent, false);
593         powerOffTile.setContent(R.layout.quick_settings_tile_poweroff, inflater);
594         powerOffTile.setOnClickListener(new View.OnClickListener() {
595             @Override
596             public void onClick(View v) {
597                   onClickPowerOff();
598             }
599         });
600         mModel.addPowerOffTile(powerOffTile, new QuickSettingsModel.RefreshCallback() {
601             @Override
602             public void refreshView(QuickSettingsTileView view, State state) {
603                 TextView tv = (TextView) view.findViewById(R.id.poweroff_tileview);
604                 tv.setText(state.label);
605             }
606         });
607         parent.addView(powerOffTile);
608     }
609
610     private void addTemporaryTiles(final ViewGroup parent, final LayoutInflater inflater) {
611         // Alarm tile
612         final QuickSettingsBasicTile alarmTile
613                 = new QuickSettingsBasicTile(mContext);
614         alarmTile.setImageResource(R.drawable.ic_qs_alarm_on);
615         alarmTile.setOnClickListener(new View.OnClickListener() {
616             @Override
617             public void onClick(View v) {
618                 // TODO: Jump into the alarm application
619                 Intent intent = new Intent();
620                 intent.setComponent(new ComponentName(
621                         "com.google.android.deskclock",
622                         "com.android.deskclock.AlarmClock"));
623                 startSettingsActivity(intent);
624             }
625         });
626         mModel.addAlarmTile(alarmTile, new QuickSettingsModel.RefreshCallback() {
627             @Override
628             public void refreshView(QuickSettingsTileView unused, State alarmState) {
629                 alarmTile.setText(alarmState.label);
630                 alarmTile.setVisibility(alarmState.enabled ? View.VISIBLE : View.GONE);
631                 alarmTile.setContentDescription(mContext.getString(
632                         R.string.accessibility_quick_settings_alarm, alarmState.label));
633             }
634         });
635         parent.addView(alarmTile);
636
637         // Location
638         final QuickSettingsBasicTile locationTile
639                 = new QuickSettingsBasicTile(mContext);
640         locationTile.setImageResource(R.drawable.ic_qs_location);
641         locationTile.setTextResource(R.string.quick_settings_location_label);
642         locationTile.setOnClickListener(new View.OnClickListener() {
643             @Override
644             public void onClick(View v) {
645                 startSettingsActivity(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
646             }
647         });
648         mModel.addLocationTile(locationTile,
649                 new QuickSettingsModel.BasicRefreshCallback(locationTile)
650                         .setShowWhenEnabled(true));
651         parent.addView(locationTile);
652
653         // Wifi Display
654         QuickSettingsBasicTile wifiDisplayTile
655                 = new QuickSettingsBasicTile(mContext);
656         wifiDisplayTile.setImageResource(R.drawable.ic_qs_remote_display);
657         wifiDisplayTile.setOnClickListener(new View.OnClickListener() {
658             @Override
659             public void onClick(View v) {
660                 startSettingsActivity(android.provider.Settings.ACTION_WIFI_DISPLAY_SETTINGS);
661             }
662         });
663         mModel.addWifiDisplayTile(wifiDisplayTile,
664                 new QuickSettingsModel.BasicRefreshCallback(wifiDisplayTile)
665                         .setShowWhenEnabled(true));
666         parent.addView(wifiDisplayTile);
667
668         if (SHOW_IME_TILE || DEBUG_GONE_TILES) {
669             // IME
670             final QuickSettingsBasicTile imeTile
671                     = new QuickSettingsBasicTile(mContext);
672             imeTile.setImageResource(R.drawable.ic_qs_ime);
673             imeTile.setOnClickListener(new View.OnClickListener() {
674                 @Override
675                 public void onClick(View v) {
676                     try {
677                         collapsePanels();
678                         Intent intent = new Intent(Settings.ACTION_SHOW_INPUT_METHOD_PICKER);
679                         PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
680                         pendingIntent.send();
681                     } catch (Exception e) {}
682                 }
683             });
684             mModel.addImeTile(imeTile,
685                     new QuickSettingsModel.BasicRefreshCallback(imeTile)
686                             .setShowWhenEnabled(true));
687             parent.addView(imeTile);
688         }
689
690         // Bug reports
691         final QuickSettingsBasicTile bugreportTile
692                 = new QuickSettingsBasicTile(mContext);
693         bugreportTile.setImageResource(com.android.internal.R.drawable.stat_sys_adb);
694         bugreportTile.setTextResource(com.android.internal.R.string.bugreport_title);
695         bugreportTile.setOnClickListener(new View.OnClickListener() {
696             @Override
697             public void onClick(View v) {
698                 collapsePanels();
699                 showBugreportDialog();
700             }
701         });
702         mModel.addBugreportTile(bugreportTile, new QuickSettingsModel.RefreshCallback() {
703             @Override
704             public void refreshView(QuickSettingsTileView view, State state) {
705                 view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
706             }
707         });
708         parent.addView(bugreportTile);
709         /*
710         QuickSettingsTileView mediaTile = (QuickSettingsTileView)
711                 inflater.inflate(R.layout.quick_settings_tile, parent, false);
712         mediaTile.setContent(R.layout.quick_settings_tile_media, inflater);
713         parent.addView(mediaTile);
714         QuickSettingsTileView imeTile = (QuickSettingsTileView)
715                 inflater.inflate(R.layout.quick_settings_tile, parent, false);
716         imeTile.setContent(R.layout.quick_settings_tile_ime, inflater);
717         imeTile.setOnClickListener(new View.OnClickListener() {
718             @Override
719             public void onClick(View v) {
720                 parent.removeViewAt(0);
721             }
722         });
723         parent.addView(imeTile);
724         */
725     }
726
727     void updateResources() {
728         Resources r = mContext.getResources();
729
730         // Update the model
731         mModel.updateResources();
732
733         // Update the User, Time, and Settings tiles spans, and reset everything else
734         int span = r.getInteger(R.integer.quick_settings_user_time_settings_tile_span);
735         for (QuickSettingsTileView v : mDynamicSpannedTiles) {
736             v.setColumnSpan(span);
737         }
738         ((QuickSettingsContainerView)mContainerView).updateResources();
739         mContainerView.requestLayout();
740     }
741
742
743     private void showBrightnessDialog() {
744         Intent intent = new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG);
745         mContext.sendBroadcast(intent);
746     }
747
748     private void showBugreportDialog() {
749         final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
750         builder.setPositiveButton(com.android.internal.R.string.report, new OnClickListener() {
751             @Override
752             public void onClick(DialogInterface dialog, int which) {
753                 if (which == DialogInterface.BUTTON_POSITIVE) {
754                     // Add a little delay before executing, to give the
755                     // dialog a chance to go away before it takes a
756                     // screenshot.
757                     mHandler.postDelayed(new Runnable() {
758                         @Override public void run() {
759                             try {
760                                 ActivityManagerNative.getDefault()
761                                         .requestBugReport();
762                             } catch (RemoteException e) {
763                             }
764                         }
765                     }, 500);
766                 }
767             }
768         });
769         builder.setMessage(com.android.internal.R.string.bugreport_message);
770         builder.setTitle(com.android.internal.R.string.bugreport_title);
771         builder.setCancelable(true);
772         final Dialog dialog = builder.create();
773         dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
774         try {
775             WindowManagerGlobal.getWindowManagerService().dismissKeyguard();
776         } catch (RemoteException e) {
777         }
778         dialog.show();
779     }
780
781     private void updateWifiDisplayStatus() {
782         mWifiDisplayStatus = mDisplayManager.getWifiDisplayStatus();
783         applyWifiDisplayStatus();
784     }
785
786     private void applyWifiDisplayStatus() {
787         mModel.onWifiDisplayStateChanged(mWifiDisplayStatus);
788     }
789
790     private void applyBluetoothStatus() {
791         mModel.onBluetoothStateChange(mBluetoothState);
792     }
793
794     void reloadUserInfo() {
795         if (mUserInfoTask != null) {
796             mUserInfoTask.cancel(false);
797             mUserInfoTask = null;
798         }
799         if (mTilesSetUp) {
800             queryForUserInformation();
801         }
802     }
803
804     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
805         @Override
806         public void onReceive(Context context, Intent intent) {
807             final String action = intent.getAction();
808             if (DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED.equals(action)) {
809                 WifiDisplayStatus status = (WifiDisplayStatus)intent.getParcelableExtra(
810                         DisplayManager.EXTRA_WIFI_DISPLAY_STATUS);
811                 mWifiDisplayStatus = status;
812                 applyWifiDisplayStatus();
813             } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
814                 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
815                         BluetoothAdapter.ERROR);
816                 mBluetoothState.enabled = (state == BluetoothAdapter.STATE_ON);
817                 applyBluetoothStatus();
818             } else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
819                 int status = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
820                         BluetoothAdapter.STATE_DISCONNECTED);
821                 mBluetoothState.connected = (status == BluetoothAdapter.STATE_CONNECTED);
822                 applyBluetoothStatus();
823             } else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
824                 reloadUserInfo();
825             } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
826                 if (mUseDefaultAvatar) {
827                     queryForUserInformation();
828                 }
829             }
830         }
831     };
832
833     private final BroadcastReceiver mProfileReceiver = new BroadcastReceiver() {
834         @Override
835         public void onReceive(Context context, Intent intent) {
836             final String action = intent.getAction();
837             if (ContactsContract.Intents.ACTION_PROFILE_CHANGED.equals(action) ||
838                     Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
839                 try {
840                     final int currentUser = ActivityManagerNative.getDefault().getCurrentUser().id;
841                     final int changedUser =
842                             intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId());
843                     if (changedUser == currentUser) {
844                         reloadUserInfo();
845                     }
846                 } catch (RemoteException e) {
847                     Log.e(TAG, "Couldn't get current user id for profile change", e);
848                 }
849             }
850
851         }
852     };
853
854     // Power off
855     // ----------------------------
856     private void onClickPowerOff() {
857         if (mBar != null) {
858             mBar.collapseAllPanels(true);
859         }
860
861         // Create dialog to get user confirmation
862         final AlertDialog dialog = new AlertDialog.Builder(mContext)
863                     .setTitle(com.android.internal.R.string.power_off)
864                     .setMessage(com.android.internal.R.string.shutdown_confirm_question)
865                     .setPositiveButton(com.android.internal.R.string.yes,
866                         new DialogInterface.OnClickListener() {
867                         public void onClick(DialogInterface dialog, int which) {
868                             // Send request to start ShutdownActivity
869                             Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
870                             intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
871                             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
872                             mContext.startActivity(intent);
873                         }
874                     })
875                     .setNegativeButton(com.android.internal.R.string.no, null)
876                     .create();
877         dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
878         dialog.show();
879     }
880 }