blob: 1b280459c8b817abb88892e062c8527db880b343 [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.phone;
import android.app.Dialog;
import android.app.PendingIntent;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.CursorLoader;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.Loader;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.LevelListDrawable;
import android.hardware.display.DisplayManager;
import android.hardware.display.WifiDisplay;
import android.hardware.display.WifiDisplayStatus;
import android.net.Uri;
import android.os.Debug;
import android.provider.ContactsContract;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.android.internal.view.RotationPolicy;
import com.android.systemui.R;
import com.android.systemui.statusbar.phone.QuickSettingsModel.BrightnessState;
import com.android.systemui.statusbar.phone.QuickSettingsModel.RSSIState;
import com.android.systemui.statusbar.phone.QuickSettingsModel.State;
import com.android.systemui.statusbar.phone.QuickSettingsModel.UserState;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.BrightnessController;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.ToggleSlider;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Set;
/**
*
*/
class QuickSettings {
private Context mContext;
private PanelBar mBar;
private QuickSettingsModel mModel;
private QuickSettingsContainerView mContainerView;
private DisplayManager mDisplayManager;
private WifiDisplayStatus mWifiDisplayStatus;
private BrightnessController mBrightnessController;
private BluetoothController mBluetoothController;
private Dialog mBrightnessDialog;
private CursorLoader mUserInfoLoader;
private LevelListDrawable mBatteryLevels;
private LevelListDrawable mChargingBatteryLevels;
// The set of QuickSettingsTiles that have dynamic spans (and need to be updated on
// configuration change)
private final ArrayList<QuickSettingsTileView> mDynamicSpannedTiles =
new ArrayList<QuickSettingsTileView>();
private final RotationPolicy.RotationPolicyListener mRotationPolicyListener =
new RotationPolicy.RotationPolicyListener() {
@Override
public void onChange() {
mModel.onRotationLockChanged();
}
};
public QuickSettings(Context context, QuickSettingsContainerView container) {
mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
mContext = context;
mContainerView = container;
mModel = new QuickSettingsModel(context);
mWifiDisplayStatus = new WifiDisplayStatus();
Resources r = mContext.getResources();
mBatteryLevels = (LevelListDrawable) r.getDrawable(R.drawable.qs_sys_battery);
mChargingBatteryLevels =
(LevelListDrawable) r.getDrawable(R.drawable.qs_sys_battery_charging);
IntentFilter filter = new IntentFilter();
filter.addAction(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED);
mContext.registerReceiver(mReceiver, filter);
}
void setBar(PanelBar bar) {
mBar = bar;
}
public void setImeWindowStatus(boolean visible) {
mModel.onImeWindowStatusChanged(visible);
}
void setup(NetworkController networkController, BluetoothController bluetoothController,
BatteryController batteryController, LocationController locationController) {
mBluetoothController = bluetoothController;
setupQuickSettings();
updateWifiDisplayStatus();
updateResources();
networkController.addNetworkSignalChangedCallback(mModel);
bluetoothController.addStateChangedCallback(mModel);
batteryController.addStateChangedCallback(mModel);
locationController.addStateChangedCallback(mModel);
RotationPolicy.registerRotationPolicyListener(mContext, mRotationPolicyListener);
}
private void queryForUserInformation() {
Uri userContactUri = Uri.withAppendedPath(
ContactsContract.Profile.CONTENT_URI,
ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
String[] selectArgs = {
ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Photo.PHOTO
};
String where = String.format("(%s = ? OR %s = ?) AND %s IS NULL",
ContactsContract.Contacts.Data.MIMETYPE,
ContactsContract.Contacts.Data.MIMETYPE,
ContactsContract.RawContacts.ACCOUNT_TYPE);
String[] whereArgs = {
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE,
ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
};
mUserInfoLoader = new CursorLoader(mContext, userContactUri, selectArgs, where, whereArgs,
null);
mUserInfoLoader.registerListener(0,
new Loader.OnLoadCompleteListener<Cursor>() {
@Override
public void onLoadComplete(Loader<Cursor> loader,
Cursor cursor) {
if (cursor != null && cursor.moveToFirst()) {
String name = cursor.getString(0); // DISPLAY_NAME
mModel.setUserTileInfo(name, null);
/*
byte[] photoData = cursor.getBlob(0);
Bitmap b =
BitmapFactory.decodeByteArray(photoData, 0, photoData.length);
*/
}
mUserInfoLoader.stopLoading();
}
});
mUserInfoLoader.startLoading();
}
private void setupQuickSettings() {
// Setup the tiles that we are going to be showing (including the temporary ones)
LayoutInflater inflater = LayoutInflater.from(mContext);
addUserTiles(mContainerView, inflater);
addSystemTiles(mContainerView, inflater);
addTemporaryTiles(mContainerView, inflater);
queryForUserInformation();
}
private void startSettingsActivity(String action) {
Intent intent = new Intent(action);
startSettingsActivity(intent);
}
private void startSettingsActivity(Intent intent) {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
mBar.collapseAllPanels(true);
mContext.startActivity(intent);
}
private void addUserTiles(ViewGroup parent, LayoutInflater inflater) {
QuickSettingsTileView userTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
userTile.setContent(R.layout.quick_settings_tile_user, inflater);
mModel.addUserTile(userTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
UserState us = (UserState) state;
TextView tv = (TextView) view.findViewById(R.id.user_textview);
tv.setText(state.label);
if (us.avatar != null) {
tv.setCompoundDrawables(null, us.avatar, null, null);
}
}
});
parent.addView(userTile);
mDynamicSpannedTiles.add(userTile);
// Time tile
QuickSettingsTileView timeTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
timeTile.setContent(R.layout.quick_settings_tile_time, inflater);
timeTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO: Jump into the alarm application
Intent intent = new Intent();
intent.setComponent(new ComponentName(
"com.google.android.deskclock",
"com.android.deskclock.AlarmClock"));
startSettingsActivity(intent);
}
});
mModel.addTimeTile(timeTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State alarmState) {
TextView tv = (TextView) view.findViewById(R.id.alarm_textview);
tv.setText(alarmState.label);
tv.setVisibility(alarmState.enabled ? View.VISIBLE : View.GONE);
}
});
parent.addView(timeTile);
mDynamicSpannedTiles.add(timeTile);
// Settings tile
QuickSettingsTileView settingsTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
settingsTile.setContent(R.layout.quick_settings_tile_settings, inflater);
settingsTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startSettingsActivity(android.provider.Settings.ACTION_SETTINGS);
}
});
parent.addView(settingsTile);
mDynamicSpannedTiles.add(settingsTile);
}
private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) {
// Wi-fi
QuickSettingsTileView wifiTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
wifiTile.setContent(R.layout.quick_settings_tile_wifi, inflater);
wifiTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startSettingsActivity(android.provider.Settings.ACTION_WIFI_SETTINGS);
}
});
mModel.addWifiTile(wifiTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
TextView tv = (TextView) view.findViewById(R.id.wifi_textview);
tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
tv.setText(state.label);
}
});
parent.addView(wifiTile);
if (mModel.deviceSupportsTelephony()) {
// RSSI
QuickSettingsTileView rssiTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
rssiTile.setContent(R.layout.quick_settings_tile_rssi, inflater);
rssiTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setComponent(new ComponentName(
"com.android.settings",
"com.android.settings.Settings$DataUsageSummaryActivity"));
startSettingsActivity(intent);
}
});
mModel.addRSSITile(rssiTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
RSSIState rssiState = (RSSIState) state;
ImageView iv = (ImageView) view.findViewById(R.id.rssi_image);
ImageView iov = (ImageView) view.findViewById(R.id.rssi_overlay_image);
TextView tv = (TextView) view.findViewById(R.id.rssi_textview);
iv.setImageResource(rssiState.signalIconId);
if (rssiState.dataTypeIconId > 0) {
iov.setImageResource(rssiState.dataTypeIconId);
} else {
iov.setImageDrawable(null);
}
tv.setText(state.label);
}
});
parent.addView(rssiTile);
}
// Rotation Lock
if (mContext.getResources().getBoolean(R.bool.quick_settings_show_rotation_lock)) {
QuickSettingsTileView rotationLockTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
rotationLockTile.setContent(R.layout.quick_settings_tile_rotation_lock, inflater);
rotationLockTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean locked = RotationPolicy.isRotationLocked(mContext);
RotationPolicy.setRotationLock(mContext, !locked);
}
});
mModel.addRotationLockTile(rotationLockTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
TextView tv = (TextView) view.findViewById(R.id.rotation_lock_textview);
tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
tv.setText(state.label);
}
});
parent.addView(rotationLockTile);
}
// Battery
QuickSettingsTileView batteryTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
batteryTile.setContent(R.layout.quick_settings_tile_battery, inflater);
batteryTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startSettingsActivity(Intent.ACTION_POWER_USAGE_SUMMARY);
}
});
mModel.addBatteryTile(batteryTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
QuickSettingsModel.BatteryState batteryState =
(QuickSettingsModel.BatteryState) state;
TextView tv = (TextView) view.findViewById(R.id.battery_textview);
ImageView iv = (ImageView) view.findViewById(R.id.battery_image);
Drawable d = batteryState.pluggedIn
? mChargingBatteryLevels
: mBatteryLevels;
String t;
if (batteryState.batteryLevel == 100) {
t = mContext.getString(R.string.quick_settings_battery_charged_label);
} else {
t = batteryState.pluggedIn
? mContext.getString(R.string.quick_settings_battery_charging_label,
batteryState.batteryLevel)
: mContext.getString(R.string.status_bar_settings_battery_meter_format,
batteryState.batteryLevel);
}
iv.setImageDrawable(d);
iv.setImageLevel(batteryState.batteryLevel);
tv.setText(t);
}
});
parent.addView(batteryTile);
// Airplane Mode
QuickSettingsTileView airplaneTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
airplaneTile.setContent(R.layout.quick_settings_tile_airplane, inflater);
mModel.addAirplaneModeTile(airplaneTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
TextView tv = (TextView) view.findViewById(R.id.airplane_mode_textview);
tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
}
});
parent.addView(airplaneTile);
// Bluetooth
if (mModel.deviceSupportsBluetooth()) {
QuickSettingsTileView bluetoothTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
bluetoothTile.setContent(R.layout.quick_settings_tile_bluetooth, inflater);
bluetoothTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startSettingsActivity(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS);
}
});
mModel.addBluetoothTile(bluetoothTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
TextView tv = (TextView) view.findViewById(R.id.bluetooth_textview);
tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
Resources r = mContext.getResources();
String label = null;
/*
//TODO: Show connected bluetooth device label
Set<BluetoothDevice> btDevices =
mBluetoothController.getBondedBluetoothDevices();
if (btDevices.size() == 1) {
// Show the name of the bluetooth device you are connected to
label = btDevices.iterator().next().getName();
} else if (btDevices.size() > 1) {
// Show a generic label about the number of bluetooth devices
label = r.getString(R.string.quick_settings_bluetooth_multiple_devices_label,
btDevices.size());
}
*/
if (label == null) {
label = r.getString(R.string.quick_settings_bluetooth_label);
}
tv.setText(label);
}
});
parent.addView(bluetoothTile);
}
// Brightness
QuickSettingsTileView brightnessTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
brightnessTile.setContent(R.layout.quick_settings_tile_brightness, inflater);
brightnessTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mBar.collapseAllPanels(true);
showBrightnessDialog();
}
});
mModel.addBrightnessTile(brightnessTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
TextView tv = (TextView) view.findViewById(R.id.brightness_textview);
tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
}
});
parent.addView(brightnessTile);
}
private void addTemporaryTiles(final ViewGroup parent, final LayoutInflater inflater) {
// Location
QuickSettingsTileView locationTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
locationTile.setContent(R.layout.quick_settings_tile_location, inflater);
locationTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startSettingsActivity(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
}
});
mModel.addLocationTile(locationTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
TextView tv = (TextView) view.findViewById(R.id.location_textview);
tv.setText(state.label);
view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
}
});
parent.addView(locationTile);
// Wifi Display
QuickSettingsTileView wifiDisplayTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
wifiDisplayTile.setContent(R.layout.quick_settings_tile_wifi_display, inflater);
wifiDisplayTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startSettingsActivity(android.provider.Settings.ACTION_WIFI_DISPLAY_SETTINGS);
}
});
mModel.addWifiDisplayTile(wifiDisplayTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
TextView tv = (TextView) view.findViewById(R.id.wifi_display_textview);
tv.setText(state.label);
view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
}
});
parent.addView(wifiDisplayTile);
// IME
QuickSettingsTileView imeTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
imeTile.setContent(R.layout.quick_settings_tile_ime, inflater);
imeTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
mBar.collapseAllPanels(true);
Intent intent = new Intent(Settings.ACTION_SHOW_INPUT_METHOD_PICKER);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
pendingIntent.send();
} catch (Exception e) {}
}
});
mModel.addImeTile(imeTile, new QuickSettingsModel.RefreshCallback() {
@Override
public void refreshView(QuickSettingsTileView view, State state) {
TextView tv = (TextView) view.findViewById(R.id.ime_textview);
if (state.label != null) {
tv.setText(state.label);
}
view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
}
});
parent.addView(imeTile);
/*
QuickSettingsTileView mediaTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
mediaTile.setContent(R.layout.quick_settings_tile_media, inflater);
parent.addView(mediaTile);
QuickSettingsTileView imeTile = (QuickSettingsTileView)
inflater.inflate(R.layout.quick_settings_tile, parent, false);
imeTile.setContent(R.layout.quick_settings_tile_ime, inflater);
imeTile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
parent.removeViewAt(0);
}
});
parent.addView(imeTile);
*/
}
void updateResources() {
Resources r = mContext.getResources();
// Update the User, Time, and Settings tiles spans, and reset everything else
int span = r.getInteger(R.integer.quick_settings_user_time_settings_tile_span);
for (QuickSettingsTileView v : mDynamicSpannedTiles) {
v.setColumnSpan(span);
}
mContainerView.requestLayout();
}
private void showBrightnessDialog() {
if (mBrightnessDialog == null) {
mBrightnessDialog = new Dialog(mContext);
mBrightnessDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
mBrightnessDialog.setContentView(R.layout.quick_settings_brightness_dialog);
mBrightnessDialog.setCanceledOnTouchOutside(true);
mBrightnessController = new BrightnessController(mContext,
(ToggleSlider) mBrightnessDialog.findViewById(R.id.brightness_slider));
mBrightnessController.addStateChangedCallback(mModel);
mBrightnessDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
mBrightnessController = null;
}
});
mBrightnessDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
mBrightnessDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
}
if (!mBrightnessDialog.isShowing()) {
mBrightnessDialog.show();
}
}
private void updateWifiDisplayStatus() {
mWifiDisplayStatus = mDisplayManager.getWifiDisplayStatus();
applyWifiDisplayStatus();
}
private void applyWifiDisplayStatus() {
mModel.onWifiDisplayStateChanged(mWifiDisplayStatus);
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) {
WifiDisplayStatus status = (WifiDisplayStatus)intent.getParcelableExtra(
DisplayManager.EXTRA_WIFI_DISPLAY_STATUS);
mWifiDisplayStatus = status;
applyWifiDisplayStatus();
}
}
};
}