blob: cad6d576f4beae4f90463fade84a0a37067e37c3 [file] [log] [blame]
Winson Chungd63c59782012-09-05 17:34:41 -07001/*
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
Jeff Brown508257b2012-09-08 23:15:12 -070019import android.app.Dialog;
Winson Chungd63c59782012-09-05 17:34:41 -070020import android.bluetooth.BluetoothAdapter;
21import android.bluetooth.BluetoothAdapter.BluetoothStateChangeCallback;
Jeff Brown508257b2012-09-08 23:15:12 -070022import android.content.BroadcastReceiver;
Winson Chungd63c59782012-09-05 17:34:41 -070023import android.content.Context;
24import android.content.CursorLoader;
25import android.content.Intent;
Jeff Brown508257b2012-09-08 23:15:12 -070026import android.content.IntentFilter;
Winson Chungd63c59782012-09-05 17:34:41 -070027import android.content.Loader;
28import android.content.res.Resources;
29import android.database.Cursor;
30import android.graphics.drawable.ClipDrawable;
Jeff Brown508257b2012-09-08 23:15:12 -070031import android.hardware.display.DisplayManager;
32import android.hardware.display.WifiDisplay;
33import android.hardware.display.WifiDisplayStatus;
Winson Chungd63c59782012-09-05 17:34:41 -070034import android.net.Uri;
Christopher Tatec09cdce2012-09-10 16:50:14 -070035import android.os.UserHandle;
Winson Chungd63c59782012-09-05 17:34:41 -070036import android.provider.ContactsContract;
37import android.provider.Settings;
38import android.view.LayoutInflater;
39import android.view.View;
40import android.view.ViewGroup;
Jeff Brown508257b2012-09-08 23:15:12 -070041import android.view.WindowManager;
42import android.widget.AdapterView;
43import android.widget.ArrayAdapter;
44import android.widget.Button;
Jeff Brown508257b2012-09-08 23:15:12 -070045import android.widget.ListView;
Winson Chungd63c59782012-09-05 17:34:41 -070046import android.widget.TextView;
47
48import java.util.ArrayList;
Jeff Brown508257b2012-09-08 23:15:12 -070049import java.util.Comparator;
Winson Chungd63c59782012-09-05 17:34:41 -070050
51import com.android.systemui.R;
52import com.android.systemui.statusbar.phone.QuickSettingsModel.State;
53import com.android.systemui.statusbar.policy.BatteryController;
Jeff Brown508257b2012-09-08 23:15:12 -070054import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
Winson Chungd63c59782012-09-05 17:34:41 -070055import com.android.systemui.statusbar.policy.BluetoothController;
56import com.android.systemui.statusbar.policy.LocationController;
Jeff Brown508257b2012-09-08 23:15:12 -070057import com.android.systemui.statusbar.policy.LocationController.LocationGpsStateChangeCallback;
Winson Chungd63c59782012-09-05 17:34:41 -070058import com.android.systemui.statusbar.policy.NetworkController;
Jeff Brown508257b2012-09-08 23:15:12 -070059import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
Winson Chungd63c59782012-09-05 17:34:41 -070060
61class QuickSettingsModel implements BluetoothStateChangeCallback,
Jeff Brown508257b2012-09-08 23:15:12 -070062 NetworkSignalChangedCallback,
63 BatteryStateChangeCallback,
64 LocationGpsStateChangeCallback {
Winson Chungd63c59782012-09-05 17:34:41 -070065
66 /** Represents the state of a given attribute. */
67 static class State {
68 int iconId;
69 String label;
70 boolean enabled;
71 }
72 static class BatteryState extends State {
73 int batteryLevel;
74 boolean pluggedIn;
75 }
76
77 /** The callback to update a given tile. */
78 interface RefreshCallback {
79 public void refreshView(QuickSettingsTileView view, State state);
80 }
81
82 private Context mContext;
83
84 private QuickSettingsTileView mUserTile;
85 private RefreshCallback mUserCallback;
86 private State mUserState = new State();
87
88 private QuickSettingsTileView mAirplaneModeTile;
89 private RefreshCallback mAirplaneModeCallback;
90 private State mAirplaneModeState = new State();
91
92 private QuickSettingsTileView mWifiTile;
93 private RefreshCallback mWifiCallback;
94 private State mWifiState = new State();
95
Jeff Brown508257b2012-09-08 23:15:12 -070096 private QuickSettingsTileView mWifiDisplayTile;
97 private RefreshCallback mWifiDisplayCallback;
98 private State mWifiDisplayState = new State();
99
Winson Chungd63c59782012-09-05 17:34:41 -0700100 private QuickSettingsTileView mRSSITile;
101 private RefreshCallback mRSSICallback;
102 private State mRSSIState = new State();
103
104 private QuickSettingsTileView mBluetoothTile;
105 private RefreshCallback mBluetoothCallback;
106 private State mBluetoothState = new State();
107
108 private QuickSettingsTileView mBatteryTile;
109 private RefreshCallback mBatteryCallback;
110 private BatteryState mBatteryState = new BatteryState();
111
112 private QuickSettingsTileView mLocationTile;
113 private RefreshCallback mLocationCallback;
114 private State mLocationState = new State();
115
116 public QuickSettingsModel(Context context) {
117 mContext = context;
118 }
119
120 // User
121 void addUserTile(QuickSettingsTileView view, RefreshCallback cb) {
122 mUserTile = view;
123 mUserCallback = cb;
124 mUserCallback.refreshView(mUserTile, mUserState);
125 }
126 void setUserTileInfo(String name) {
127 mUserState.label = name;
128 mUserCallback.refreshView(mUserTile, mUserState);
129 }
130
131 // Airplane Mode
132 void addAirplaneModeTile(QuickSettingsTileView view, RefreshCallback cb) {
133 mAirplaneModeTile = view;
134 mAirplaneModeTile.setOnClickListener(new View.OnClickListener() {
135 @Override
136 public void onClick(View v) {
137 if (mAirplaneModeState.enabled) {
138 setAirplaneModeState(false);
139 } else {
140 setAirplaneModeState(true);
141 }
142 }
143 });
144 mAirplaneModeCallback = cb;
145 mAirplaneModeCallback.refreshView(mAirplaneModeTile, mAirplaneModeState);
146 }
147 private void setAirplaneModeState(boolean enabled) {
148 // TODO: Sets the view to be "awaiting" if not already awaiting
149
150 // Change the system setting
Christopher Tatec09cdce2012-09-10 16:50:14 -0700151 Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
Winson Chungd63c59782012-09-05 17:34:41 -0700152 enabled ? 1 : 0);
153
154 // TODO: Update the UI to reflect system setting
155 // mCheckBoxPref.setChecked(enabled);
156
157 // Post the intent
158 Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
159 intent.putExtra("state", enabled);
Christopher Tatec09cdce2012-09-10 16:50:14 -0700160 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Winson Chungd63c59782012-09-05 17:34:41 -0700161 }
162 // NetworkSignalChanged callback
163 @Override
164 public void onAirplaneModeChanged(boolean enabled) {
165 // TODO: If view is in awaiting state, disable
166 Resources r = mContext.getResources();
167 mAirplaneModeState.enabled = enabled;
168 mAirplaneModeState.iconId = (enabled ?
169 R.drawable.ic_qs_airplane_enabled :
170 R.drawable.ic_qs_airplane_normal);
171 mAirplaneModeCallback.refreshView(mAirplaneModeTile, mAirplaneModeState);
172 }
173
174 // Wifi
175 void addWifiTile(QuickSettingsTileView view, RefreshCallback cb) {
176 mWifiTile = view;
177 mWifiCallback = cb;
178 mWifiCallback.refreshView(mWifiTile, mWifiState);
179 }
180 // NetworkSignalChanged callback
181 @Override
182 public void onWifiSignalChanged(boolean enabled, String description) {
183 // TODO: If view is in awaiting state, disable
184 Resources r = mContext.getResources();
185 // TODO: Check if wifi is enabled
186 mWifiState.enabled = enabled;
187 mWifiState.iconId = (enabled ?
188 R.drawable.ic_qs_wifi_enabled :
189 R.drawable.ic_qs_wifi_normal);
190 mWifiState.label = (enabled ?
191 description :
192 r.getString(R.string.quick_settings_wifi_no_network));
193 mWifiCallback.refreshView(mWifiTile, mWifiState);
194 }
195
196 // RSSI
197 void addRSSITile(QuickSettingsTileView view, RefreshCallback cb) {
198 mRSSITile = view;
199 mRSSICallback = cb;
200 mRSSICallback.refreshView(mRSSITile, mRSSIState);
201 }
202 private void setRSSIState(boolean enabled) {
203 // TODO: Set RSSI enabled
204 // TODO: Sets the view to be "awaiting" if not already awaiting
205 }
206 // NetworkSignalChanged callback
207 @Override
208 public void onMobileDataSignalChanged(boolean enabled, String description) {
209 // TODO: If view is in awaiting state, disable
210 Resources r = mContext.getResources();
211 // TODO: Check if RSSI is enabled
212 mRSSIState.enabled = enabled;
213 mRSSIState.iconId = (enabled ?
214 R.drawable.ic_qs_rssi_enabled :
215 R.drawable.ic_qs_rssi_normal);
216 mRSSIState.label = (enabled ?
217 description :
218 r.getString(R.string.quick_settings_rssi_emergency_only));
219 mRSSICallback.refreshView(mRSSITile, mRSSIState);
220 }
221
222 // Bluetooth
223 void addBluetoothTile(QuickSettingsTileView view, RefreshCallback cb) {
224 mBluetoothTile = view;
225 mBluetoothTile.setOnClickListener(new View.OnClickListener() {
226 @Override
227 public void onClick(View v) {
228 if (mBluetoothState.enabled) {
229 setBluetoothState(false);
230 } else {
231 setBluetoothState(true);
232 }
233 }
234 });
235 mBluetoothCallback = cb;
236
237 final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
238 onBluetoothStateChange(adapter.isEnabled());
239 }
240 private void setBluetoothState(boolean enabled) {
241 // TODO: Sets the view to be "awaiting" if not already awaiting
242 final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
243 if (adapter != null) {
244 if (enabled) {
245 adapter.enable();
246 } else {
247 adapter.disable();
248 }
249 }
250 }
251 // BluetoothController callback
252 @Override
253 public void onBluetoothStateChange(boolean on) {
254 // TODO: If view is in awaiting state, disable
255 Resources r = mContext.getResources();
256 mBluetoothState.enabled = on;
257 if (on) {
258 mBluetoothState.iconId = R.drawable.ic_qs_bluetooth_enabled;
259 } else {
260 mBluetoothState.iconId = R.drawable.ic_qs_bluetooth_normal;
261 }
262 mBluetoothCallback.refreshView(mBluetoothTile, mBluetoothState);
263 }
264
265 // Battery
266 void addBatteryTile(QuickSettingsTileView view, RefreshCallback cb) {
267 mBatteryTile = view;
268 mBatteryCallback = cb;
269 mBatteryCallback.refreshView(mBatteryTile, mBatteryState);
270 }
271 // BatteryController callback
272 @Override
273 public void onBatteryLevelChanged(int level, boolean pluggedIn) {
274 mBatteryState.batteryLevel = level;
275 mBatteryState.pluggedIn = pluggedIn;
276 mBatteryCallback.refreshView(mBatteryTile, mBatteryState);
277 }
278
279 // Location
280 void addLocationTile(QuickSettingsTileView view, RefreshCallback cb) {
281 mLocationTile = view;
282 mLocationCallback = cb;
283 mLocationCallback.refreshView(mLocationTile, mLocationState);
284 disableLocationTile();
285 }
286 private void enableLocationTile() {
287 mLocationTile.setVisibility(View.VISIBLE);
288 }
289 private void disableLocationTile() {
290 mLocationTile.setVisibility(View.GONE);
291 }
292 // LocationController callback
293 @Override
294 public void onLocationGpsStateChanged(boolean inUse, String description) {
295 if (inUse) {
296 mLocationState.enabled = inUse;
297 mLocationState.label = description;
298 mLocationCallback.refreshView(mLocationTile, mLocationState);
299 enableLocationTile();
300 } else {
301 disableLocationTile();
302 }
303 }
304
Jeff Brown508257b2012-09-08 23:15:12 -0700305 // Wifi Display
306 void addWifiDisplayTile(QuickSettingsTileView view, RefreshCallback cb) {
307 mWifiDisplayTile = view;
308 mWifiDisplayCallback = cb;
309 }
310 private void enableWifiDisplayTile() {
311 mWifiDisplayTile.setVisibility(View.VISIBLE);
312 }
313 private void disableWifiDisplayTile() {
314 mWifiDisplayTile.setVisibility(View.GONE);
315 }
316 public void onWifiDisplayStateChanged(WifiDisplayStatus status) {
317 if (status.isEnabled()) {
318 if (status.getActiveDisplay() != null) {
319 mWifiDisplayState.label = status.getActiveDisplay().getDeviceName();
320 } else {
321 mWifiDisplayState.label = mContext.getString(
322 R.string.quick_settings_wifi_display_no_connection_label);
323 }
324 mWifiDisplayCallback.refreshView(mWifiDisplayTile, mWifiDisplayState);
325 enableWifiDisplayTile();
326 } else {
327 disableWifiDisplayTile();
328 }
329 }
330
Winson Chungd63c59782012-09-05 17:34:41 -0700331}
332
333/**
334 *
335 */
336class QuickSettings {
337
338 private Context mContext;
339 private PanelBar mBar;
340 private QuickSettingsModel mModel;
341 private QuickSettingsContainerView mContainerView;
342
Jeff Brown508257b2012-09-08 23:15:12 -0700343 private DisplayManager mDisplayManager;
344 private WifiDisplayStatus mWifiDisplayStatus;
345 private WifiDisplayListAdapter mWifiDisplayListAdapter;
346
Winson Chungd63c59782012-09-05 17:34:41 -0700347 private CursorLoader mUserInfoLoader;
348
349 // The set of QuickSettingsTiles that have dynamic spans (and need to be updated on
350 // configuration change)
351 private final ArrayList<QuickSettingsTileView> mDynamicSpannedTiles =
352 new ArrayList<QuickSettingsTileView>();
353
354 public QuickSettings(Context context, QuickSettingsContainerView container) {
Jeff Brown508257b2012-09-08 23:15:12 -0700355 mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
Winson Chungd63c59782012-09-05 17:34:41 -0700356 mContext = context;
Winson Chungd63c59782012-09-05 17:34:41 -0700357 mContainerView = container;
Jeff Brown508257b2012-09-08 23:15:12 -0700358 mModel = new QuickSettingsModel(context);
359 mWifiDisplayStatus = new WifiDisplayStatus();
360 mWifiDisplayListAdapter = new WifiDisplayListAdapter(context);
361
362 IntentFilter filter = new IntentFilter();
363 filter.addAction(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED);
364 mContext.registerReceiver(mReceiver, filter);
Winson Chungd63c59782012-09-05 17:34:41 -0700365
366 setupQuickSettings();
Jeff Brown508257b2012-09-08 23:15:12 -0700367 updateWifiDisplayStatus();
Winson Chungd63c59782012-09-05 17:34:41 -0700368 updateResources();
369 }
370
371 void setBar(PanelBar bar) {
372 mBar = bar;
373 }
374
375 void setup(NetworkController networkController, BluetoothController bluetoothController,
376 BatteryController batteryController, LocationController locationController) {
377 networkController.addNetworkSignalChangedCallback(mModel);
378 bluetoothController.addStateChangedCallback(mModel);
379 batteryController.addStateChangedCallback(mModel);
380 locationController.addStateChangedCallback(mModel);
381 }
382
383 private void queryForUserInformation() {
384 Uri userContactUri = Uri.withAppendedPath(
385 ContactsContract.Profile.CONTENT_URI,
386 ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
387
388 String[] selectArgs = {
389 ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
390 ContactsContract.CommonDataKinds.Photo.PHOTO
391 };
392 String where = String.format("(%s = ? OR %s = ?) AND %s IS NULL",
393 ContactsContract.Contacts.Data.MIMETYPE,
394 ContactsContract.Contacts.Data.MIMETYPE,
395 ContactsContract.RawContacts.ACCOUNT_TYPE);
396 String[] whereArgs = {
397 ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE,
398 ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
399 };
400
401 mUserInfoLoader = new CursorLoader(mContext, userContactUri, selectArgs, where, whereArgs,
402 null);
403 mUserInfoLoader.registerListener(0,
404 new Loader.OnLoadCompleteListener<Cursor>() {
405 @Override
406 public void onLoadComplete(Loader<Cursor> loader,
407 Cursor cursor) {
Jeff Brown7a8cce32012-09-09 17:26:50 -0700408 if (cursor != null && cursor.moveToFirst()) {
Winson Chungd63c59782012-09-05 17:34:41 -0700409 String name = cursor.getString(0); // DISPLAY_NAME
410 mModel.setUserTileInfo(name);
411 /*
412 byte[] photoData = cursor.getBlob(0);
413 Bitmap b =
414 BitmapFactory.decodeByteArray(photoData, 0, photoData.length);
415 */
416 }
417 mUserInfoLoader.stopLoading();
418 }
419 });
420 mUserInfoLoader.startLoading();
421 }
422
423 private void setupQuickSettings() {
424 // Setup the tiles that we are going to be showing (including the temporary ones)
425 LayoutInflater inflater = LayoutInflater.from(mContext);
426
427 addUserTiles(mContainerView, inflater);
428 addSystemTiles(mContainerView, inflater);
429 addTemporaryTiles(mContainerView, inflater);
430
431 queryForUserInformation();
432 }
433
434 private void addUserTiles(ViewGroup parent, LayoutInflater inflater) {
435 QuickSettingsTileView userTile = (QuickSettingsTileView)
436 inflater.inflate(R.layout.quick_settings_tile, parent, false);
437 userTile.setContent(R.layout.quick_settings_tile_user, inflater);
438 mModel.addUserTile(userTile, new QuickSettingsModel.RefreshCallback() {
439 @Override
440 public void refreshView(QuickSettingsTileView view, State state) {
441 TextView tv = (TextView) view.findViewById(R.id.user_textview);
442 tv.setText(state.label);
443 }
444 });
445 parent.addView(userTile);
446 mDynamicSpannedTiles.add(userTile);
447
448 // Time tile
449 QuickSettingsTileView timeTile = (QuickSettingsTileView)
450 inflater.inflate(R.layout.quick_settings_tile, parent, false);
451 timeTile.setContent(R.layout.quick_settings_tile_time, inflater);
452 parent.addView(timeTile);
453 mDynamicSpannedTiles.add(timeTile);
454
455 // Settings tile
456 QuickSettingsTileView settingsTile = (QuickSettingsTileView)
457 inflater.inflate(R.layout.quick_settings_tile, parent, false);
458 settingsTile.setContent(R.layout.quick_settings_tile_settings, inflater);
459 settingsTile.setOnClickListener(new View.OnClickListener() {
460 @Override
461 public void onClick(View v) {
462 Intent intent = new Intent(android.provider.Settings.ACTION_SETTINGS);
463 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
464 mContext.startActivity(intent);
465 mBar.collapseAllPanels(true);
466 }
467 });
468 parent.addView(settingsTile);
469 mDynamicSpannedTiles.add(settingsTile);
470 }
471
472 private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) {
473 // Wi-fi
474 QuickSettingsTileView wifiTile = (QuickSettingsTileView)
475 inflater.inflate(R.layout.quick_settings_tile, parent, false);
476 wifiTile.setContent(R.layout.quick_settings_tile_wifi, inflater);
477 wifiTile.setOnClickListener(new View.OnClickListener() {
478 @Override
479 public void onClick(View v) {
480 Intent intent = new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS);
481 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
482 mContext.startActivity(intent);
483 mBar.collapseAllPanels(true);
484 }
485 });
486 mModel.addWifiTile(wifiTile, new QuickSettingsModel.RefreshCallback() {
487 @Override
488 public void refreshView(QuickSettingsTileView view, State state) {
489 TextView tv = (TextView) view.findViewById(R.id.wifi_textview);
490 tv.setCompoundDrawablesRelativeWithIntrinsicBounds(0, state.iconId, 0, 0);
491 tv.setText(state.label);
492 }
493 });
494 parent.addView(wifiTile);
495
496 // RSSI
497 QuickSettingsTileView rssiTile = (QuickSettingsTileView)
498 inflater.inflate(R.layout.quick_settings_tile, parent, false);
499 rssiTile.setContent(R.layout.quick_settings_tile_rssi, inflater);
500 rssiTile.setOnClickListener(new View.OnClickListener() {
501 @Override
502 public void onClick(View v) {
503 Intent intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS);
504 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
505 mContext.startActivity(intent);
506 mBar.collapseAllPanels(true);
507 }
508 });
509 mModel.addRSSITile(rssiTile, new QuickSettingsModel.RefreshCallback() {
510 @Override
511 public void refreshView(QuickSettingsTileView view, State state) {
512 TextView tv = (TextView) view.findViewById(R.id.rssi_textview);
513 tv.setCompoundDrawablesRelativeWithIntrinsicBounds(0, state.iconId, 0, 0);
514 tv.setText(state.label);
515 }
516 });
517 parent.addView(rssiTile);
518
519 // Battery
520 QuickSettingsTileView batteryTile = (QuickSettingsTileView)
521 inflater.inflate(R.layout.quick_settings_tile, parent, false);
522 batteryTile.setContent(R.layout.quick_settings_tile_battery, inflater);
523 batteryTile.setOnClickListener(new View.OnClickListener() {
524 @Override
525 public void onClick(View v) {
526 Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
527 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
528 mContext.startActivity(intent);
529 mBar.collapseAllPanels(true);
530 }
531 });
532 mModel.addBatteryTile(batteryTile, new QuickSettingsModel.RefreshCallback() {
533 @Override
534 public void refreshView(QuickSettingsTileView view, State state) {
535 QuickSettingsModel.BatteryState batteryState =
536 (QuickSettingsModel.BatteryState) state;
537 TextView tv = (TextView) view.findViewById(R.id.battery_textview);
538 ClipDrawable drawable = (ClipDrawable) tv.getCompoundDrawables()[1];
539 drawable.setLevel((int) (10000 * (batteryState.batteryLevel / 100.0f)));
540 // TODO: use format string
541 tv.setText(batteryState.batteryLevel + "%");
542 }
543 });
544 parent.addView(batteryTile);
545
546 // Airplane Mode
547 QuickSettingsTileView airplaneTile = (QuickSettingsTileView)
548 inflater.inflate(R.layout.quick_settings_tile, parent, false);
549 airplaneTile.setContent(R.layout.quick_settings_tile_airplane, inflater);
550 mModel.addAirplaneModeTile(airplaneTile, new QuickSettingsModel.RefreshCallback() {
551 @Override
552 public void refreshView(QuickSettingsTileView view, State state) {
553 TextView tv = (TextView) view.findViewById(R.id.airplane_mode_textview);
554 tv.setCompoundDrawablesRelativeWithIntrinsicBounds(0, state.iconId, 0, 0);
555 }
556 });
557 parent.addView(airplaneTile);
558
559 // Bluetooth
560 QuickSettingsTileView bluetoothTile = (QuickSettingsTileView)
561 inflater.inflate(R.layout.quick_settings_tile, parent, false);
562 bluetoothTile.setContent(R.layout.quick_settings_tile_bluetooth, inflater);
563 mModel.addBluetoothTile(bluetoothTile, new QuickSettingsModel.RefreshCallback() {
564 @Override
565 public void refreshView(QuickSettingsTileView view, State state) {
566 TextView tv = (TextView) view.findViewById(R.id.bluetooth_textview);
567 tv.setCompoundDrawablesRelativeWithIntrinsicBounds(0, state.iconId, 0, 0);
568 }
569 });
570 parent.addView(bluetoothTile);
571
572 // Brightness
573 QuickSettingsTileView brightnessTile = (QuickSettingsTileView)
574 inflater.inflate(R.layout.quick_settings_tile, parent, false);
575 brightnessTile.setContent(R.layout.quick_settings_tile_brightness, inflater);
576 brightnessTile.setOnClickListener(new View.OnClickListener() {
577 @Override
578 public void onClick(View v) {
579 Intent intent = new Intent(android.provider.Settings.ACTION_DISPLAY_SETTINGS);
580 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
581 mContext.startActivity(intent);
582 mBar.collapseAllPanels(true);
583 }
584 });
585 parent.addView(brightnessTile);
586 }
587
588 private void addTemporaryTiles(final ViewGroup parent, final LayoutInflater inflater) {
589 // Location
590 QuickSettingsTileView locationTile = (QuickSettingsTileView)
591 inflater.inflate(R.layout.quick_settings_tile, parent, false);
592 locationTile.setContent(R.layout.quick_settings_tile_location, inflater);
593 locationTile.setOnClickListener(new View.OnClickListener() {
594 @Override
595 public void onClick(View v) {
596 Intent intent =
597 new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
598 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
599 mContext.startActivity(intent);
600 mBar.collapseAllPanels(true);
601 }
602 });
603 mModel.addLocationTile(locationTile, new QuickSettingsModel.RefreshCallback() {
604 @Override
605 public void refreshView(QuickSettingsTileView view, State state) {
606 TextView tv = (TextView) view.findViewById(R.id.location_textview);
607 tv.setText(state.label);
608 }
609 });
610 parent.addView(locationTile);
611
Jeff Brown508257b2012-09-08 23:15:12 -0700612 // Wifi Display
613 QuickSettingsTileView wifiDisplayTile = (QuickSettingsTileView)
614 inflater.inflate(R.layout.quick_settings_tile, parent, false);
615 wifiDisplayTile.setContent(R.layout.quick_settings_tile_wifi_display, inflater);
616 wifiDisplayTile.setOnClickListener(new View.OnClickListener() {
617 @Override
618 public void onClick(View v) {
619 showWifiDisplayDialog();
620 mBar.collapseAllPanels(true);
621 }
622 });
623 mModel.addWifiDisplayTile(wifiDisplayTile, new QuickSettingsModel.RefreshCallback() {
624 @Override
625 public void refreshView(QuickSettingsTileView view, State state) {
626 TextView tv = (TextView) view.findViewById(R.id.wifi_display_textview);
627 tv.setText(state.label);
628 }
629 });
630 parent.addView(wifiDisplayTile);
631
Winson Chungd63c59782012-09-05 17:34:41 -0700632 /*
633 QuickSettingsTileView mediaTile = (QuickSettingsTileView)
634 inflater.inflate(R.layout.quick_settings_tile, parent, false);
635 mediaTile.setContent(R.layout.quick_settings_tile_media, inflater);
636 parent.addView(mediaTile);
637 QuickSettingsTileView imeTile = (QuickSettingsTileView)
638 inflater.inflate(R.layout.quick_settings_tile, parent, false);
639 imeTile.setContent(R.layout.quick_settings_tile_ime, inflater);
640 imeTile.setOnClickListener(new View.OnClickListener() {
641 @Override
642 public void onClick(View v) {
643 parent.removeViewAt(0);
644 }
645 });
646 parent.addView(imeTile);
647 */
648 }
649
650 void updateResources() {
651 Resources r = mContext.getResources();
652
653 // Update the User, Time, and Settings tiles spans, and reset everything else
654 int span = r.getInteger(R.integer.quick_settings_user_time_settings_tile_span);
655 for (QuickSettingsTileView v : mDynamicSpannedTiles) {
656 v.setColumnSpan(span);
657 }
658 mContainerView.requestLayout();
659 }
Jeff Brown508257b2012-09-08 23:15:12 -0700660
661 private void showWifiDisplayDialog() {
662 mDisplayManager.scanWifiDisplays();
663 updateWifiDisplayStatus();
664
665 Dialog dialog = new Dialog(mContext);
666 dialog.setContentView(R.layout.wifi_display_dialog);
667 dialog.setCanceledOnTouchOutside(true);
668 dialog.setTitle(R.string.wifi_display_dialog_title);
669
670 Button scanButton = (Button)dialog.findViewById(R.id.scan);
671 scanButton.setOnClickListener(new View.OnClickListener() {
672 @Override
673 public void onClick(View v) {
674 mDisplayManager.scanWifiDisplays();
675 }
676 });
677
678 Button disconnectButton = (Button)dialog.findViewById(R.id.disconnect);
679 disconnectButton.setOnClickListener(new View.OnClickListener() {
680 @Override
681 public void onClick(View v) {
682 mDisplayManager.disconnectWifiDisplay();
683 }
684 });
685
686 ListView list = (ListView)dialog.findViewById(R.id.list);
687 list.setAdapter(mWifiDisplayListAdapter);
688 list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
689 @Override
690 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
691 WifiDisplay display = mWifiDisplayListAdapter.getItem(position);
692 mDisplayManager.connectWifiDisplay(display.getDeviceAddress());
693 }
694 });
695
696 dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
697 dialog.show();
698 }
699
700 private void updateWifiDisplayStatus() {
701 applyWifiDisplayStatus(mDisplayManager.getWifiDisplayStatus());
702 }
703
704 private void applyWifiDisplayStatus(WifiDisplayStatus status) {
705 mWifiDisplayStatus = status;
706
707 mWifiDisplayListAdapter.clear();
708 mWifiDisplayListAdapter.addAll(status.getKnownDisplays());
709 if (status.getActiveDisplay() != null
710 && !contains(status.getKnownDisplays(), status.getActiveDisplay())) {
711 mWifiDisplayListAdapter.add(status.getActiveDisplay());
712 }
713 mWifiDisplayListAdapter.sort(mWifiDisplayComparator);
714
715 mModel.onWifiDisplayStateChanged(status);
716 }
717
718 private static boolean contains(WifiDisplay[] displays, WifiDisplay display) {
719 for (WifiDisplay d : displays) {
720 if (d.equals(display)) {
721 return true;
722 }
723 }
724 return false;
725 }
726
727 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
728 @Override
729 public void onReceive(Context context, Intent intent) {
730 if (intent.getAction().equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) {
731 WifiDisplayStatus status = (WifiDisplayStatus)intent.getParcelableExtra(
732 DisplayManager.EXTRA_WIFI_DISPLAY_STATUS);
733 applyWifiDisplayStatus(status);
734 }
735 }
736 };
737
738 private final class WifiDisplayListAdapter extends ArrayAdapter<WifiDisplay> {
739 private final LayoutInflater mInflater;
740
741 public WifiDisplayListAdapter(Context context) {
742 super(context, android.R.layout.simple_list_item_2);
743 mInflater = LayoutInflater.from(context);
744 }
745
746 @Override
747 public View getView(int position, View convertView, ViewGroup parent) {
748 WifiDisplay item = getItem(position);
749 View view = convertView;
750 if (view == null) {
751 view = mInflater.inflate(android.R.layout.simple_list_item_2,
752 parent, false);
753 }
754 TextView headline = (TextView) view.findViewById(android.R.id.text1);
755 TextView subText = (TextView) view.findViewById(android.R.id.text2);
756 headline.setText(item.getDeviceName());
757
758 int state = WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED;
759 if (item.equals(mWifiDisplayStatus.getActiveDisplay())) {
760 state = mWifiDisplayStatus.getActiveDisplayState();
761 }
762 switch (state) {
763 case WifiDisplayStatus.DISPLAY_STATE_CONNECTING:
764 subText.setText(R.string.wifi_display_state_connecting);
765 break;
766 case WifiDisplayStatus.DISPLAY_STATE_CONNECTED:
767 subText.setText(R.string.wifi_display_state_connected);
768 break;
769 case WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED:
770 default:
771 subText.setText(R.string.wifi_display_state_available);
772 break;
773 }
774 return view;
775 }
776 }
777
778 private final Comparator<WifiDisplay> mWifiDisplayComparator = new Comparator<WifiDisplay>() {
779 @Override
780 public int compare(WifiDisplay lhs, WifiDisplay rhs) {
781 int c = lhs.getDeviceName().compareToIgnoreCase(rhs.getDeviceName());
782 if (c == 0) {
783 c = lhs.getDeviceAddress().compareToIgnoreCase(rhs.getDeviceAddress());
784 }
785 return c;
786 }
787 };
Winson Chungd63c59782012-09-05 17:34:41 -0700788}