summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SystemUI')
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_profiles_off.xml26
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_profiles_on.xml26
-rw-r--r--packages/SystemUI/res/layout/profiles_detail_view.xml31
-rw-r--r--packages/SystemUI/res/values/cm_strings.xml13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/ProfilesTile.java269
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java3
6 files changed, 368 insertions, 0 deletions
diff --git a/packages/SystemUI/res/drawable/ic_qs_profiles_off.xml b/packages/SystemUI/res/drawable/ic_qs_profiles_off.xml
new file mode 100644
index 0000000..f407c4d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_profiles_off.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2015 The CyanogenMod 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="64dp"
+ android:height="64dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#4DFFFFFF"
+ android:pathData="M14.304,5.455l0.79-1.93c0.079-0.193-0.013-0.413-0.206-0.492c-0.193-0.079-0.413,0.013-0.492,0.206 l-0.818,2c-0.903-0.207-2.055-0.286-3.433-0.286v0.005h0V4.953c-0.18,0-0.355,0.002-0.527,0.005H9.615 C8.468,4.976,7.495,5.06,6.71,5.239l-0.819-2C5.812,3.046,5.592,2.954,5.399,3.033C5.206,3.112,5.114,3.332,5.193,3.525l0.79,1.93 C4.934,5.852,4.377,6.523,4.377,7.6v2.261v0.587v0.644c0,1.98,1.876,2.588,5.238,2.643v0.003h0.209 c0.105,0.001,0.212,0.002,0.32,0.002v-0.002h0v0.002c0.108,0,0.214-0.001,0.32-0.002h0.015c3.484-0.034,5.432-0.628,5.432-2.646 v-0.644V9.861V7.6C15.909,6.523,15.352,5.852,14.304,5.455Z M7.179,11.014c-0.953,0-1.725-0.772-1.725-1.724 c0-0.953,0.772-1.725,1.725-1.725c0.952,0,1.724,0.772,1.724,1.725C8.904,10.242,8.132,11.014,7.179,11.014z M10.325,12.265H9.961 c-0.268,0-0.485-0.217-0.485-0.485c0-0.01,0.002-0.019,0.003-0.029h1.328c0.001,0.01,0.003,0.019,0.003,0.029 C10.81,12.048,10.593,12.265,10.325,12.265z M13.107,11.014c-0.953,0-1.725-0.772-1.725-1.724c0-0.953,0.772-1.725,1.725-1.725 c0.952,0,1.724,0.772,1.724,1.725C14.832,10.242,14.06,11.014,13.107,11.014z M21.44,10.402c-0.261,1.016-0.5,4.301-5.798,7.557 c-0.439,0.269-0.884,0.974-0.884,2.152l0.05,0.89h-1.922v0h-0.014c0-1.492-1.214-2.706-2.706-2.706 c-1.492,0-2.706,1.214-2.706,2.706v0H5.525l0.07-1.243c0,0-0.203,0.516-0.489,1.243H2.501l1.563-4.171 c0.303-0.793,1.013-1.282,1.733-1.529c0.524-0.18,1.593-0.386,3.586-0.485h1.569c0.492,0.025,0.926,0.055,1.311,0.091 c0,0,0,0,0.001,0s0,0,0.001,0c0.296,0.027,0.563,0.057,0.801,0.089c1.028,0.062,2.506-0.095,4.131-1.475 c1.423-1.209,1.591-2.051,2.28-3.895C20.285,7.463,21.816,8.936,21.44,10.402z M12.316,21h0.013v0H8.02v0H8.019 c0-1.185,0.964-2.148,2.149-2.148C11.352,18.851,12.316,19.815,12.316,21z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_profiles_on.xml b/packages/SystemUI/res/drawable/ic_qs_profiles_on.xml
new file mode 100644
index 0000000..ce752e7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_profiles_on.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2015 The CyanogenMod 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="64dp"
+ android:height="64dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M14.304,5.455l0.79-1.93c0.079-0.193-0.013-0.413-0.206-0.492c-0.193-0.079-0.413,0.013-0.492,0.206 l-0.818,2c-0.903-0.207-2.055-0.286-3.433-0.286v0.005h0V4.953c-0.18,0-0.355,0.002-0.527,0.005H9.615 C8.468,4.976,7.495,5.06,6.71,5.239l-0.819-2C5.812,3.046,5.592,2.954,5.399,3.033C5.206,3.112,5.114,3.332,5.193,3.525l0.79,1.93 C4.934,5.852,4.377,6.523,4.377,7.6v2.261v0.587v0.644c0,1.98,1.876,2.588,5.238,2.643v0.003h0.209 c0.105,0.001,0.212,0.002,0.32,0.002v-0.002h0v0.002c0.108,0,0.214-0.001,0.32-0.002h0.015c3.484-0.034,5.432-0.628,5.432-2.646 v-0.644V9.861V7.6C15.909,6.523,15.352,5.852,14.304,5.455Z M7.179,11.014c-0.953,0-1.725-0.772-1.725-1.724 c0-0.953,0.772-1.725,1.725-1.725c0.952,0,1.724,0.772,1.724,1.725C8.904,10.242,8.132,11.014,7.179,11.014z M10.325,12.265H9.961 c-0.268,0-0.485-0.217-0.485-0.485c0-0.01,0.002-0.019,0.003-0.029h1.328c0.001,0.01,0.003,0.019,0.003,0.029 C10.81,12.048,10.593,12.265,10.325,12.265z M13.107,11.014c-0.953,0-1.725-0.772-1.725-1.724c0-0.953,0.772-1.725,1.725-1.725 c0.952,0,1.724,0.772,1.724,1.725C14.832,10.242,14.06,11.014,13.107,11.014z M21.44,10.402c-0.261,1.016-0.5,4.301-5.798,7.557 c-0.439,0.269-0.884,0.974-0.884,2.152l0.05,0.89h-1.922v0h-0.014c0-1.492-1.214-2.706-2.706-2.706 c-1.492,0-2.706,1.214-2.706,2.706v0H5.525l0.07-1.243c0,0-0.203,0.516-0.489,1.243H2.501l1.563-4.171 c0.303-0.793,1.013-1.282,1.733-1.529c0.524-0.18,1.593-0.386,3.586-0.485h1.569c0.492,0.025,0.926,0.055,1.311,0.091 c0,0,0,0,0.001,0s0,0,0.001,0c0.296,0.027,0.563,0.057,0.801,0.089c1.028,0.062,2.506-0.095,4.131-1.475 c1.423-1.209,1.591-2.051,2.28-3.895C20.285,7.463,21.816,8.936,21.44,10.402z M12.316,21h0.013v0H8.02v0H8.019 c0-1.185,0.964-2.148,2.149-2.148C11.352,18.851,12.316,19.815,12.316,21z" />
+</vector>
diff --git a/packages/SystemUI/res/layout/profiles_detail_view.xml b/packages/SystemUI/res/layout/profiles_detail_view.xml
new file mode 100644
index 0000000..c366868
--- /dev/null
+++ b/packages/SystemUI/res/layout/profiles_detail_view.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 The CyanogenMod 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.
+-->
+<com.android.systemui.qs.tiles.ProfilesDetailView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp"
+ android:orientation="vertical">
+
+ <ListView
+ android:id="@android:id/list"
+ android:divider="@null"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+
+</com.android.systemui.qs.tiles.ProfilesDetailView>
diff --git a/packages/SystemUI/res/values/cm_strings.xml b/packages/SystemUI/res/values/cm_strings.xml
index ac8e7e2..7938038 100644
--- a/packages/SystemUI/res/values/cm_strings.xml
+++ b/packages/SystemUI/res/values/cm_strings.xml
@@ -68,6 +68,17 @@
<!-- Content description of the light brightness slider (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_notification_brightness">Light brightness</string>
+
+ <!-- Content description of the profiles tile in quick settings when off (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_profiles_off">Profiles off.</string>
+ <!-- Content description of the profiles tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_profiles">Profile: <xliff:g id="profile" example="Default">%s</xliff:g>.</string>
+
+ <!-- Announcement made when the profiles tile changes to off (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_profiles_changed_off">Profiles turned off.</string>
+ <!-- Announcement made when the profiles tile changes (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_profiles_changed">Profile changed to <xliff:g id="profile" example="Default">%s</xliff:g>.</string>
+
<string name="quick_settings_compass_value" translatable="false"><xliff:g id="degrees">%1$.0f</xliff:g>\u00b0 <xliff:g id="direction">%2$s</xliff:g></string>
<string name="quick_settings_compass_off">Compass off</string>
<string name="quick_settings_compass_init">Initializing\u2026</string>
@@ -97,6 +108,8 @@
<string name="qs_tile_compass">Compass</string>
<string name="quick_settings_nfc">NFC</string>
<string name="quick_settings_nfc_off">NFC off</string>
+ <string name="quick_settings_profiles">System profiles</string>
+ <string name="quick_settings_profiles_off">Profiles disabled</string>
<!-- Content description of the sync tile in quick settings when off (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_sync_off">Sync off.</string>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ProfilesTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ProfilesTile.java
new file mode 100644
index 0000000..42aa122
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ProfilesTile.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod 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.qs.tiles;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.media.AudioManager;
+import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.CheckedTextView;
+import android.widget.ListView;
+
+import com.android.internal.logging.MetricsConstants;
+import com.android.systemui.R;
+import com.android.systemui.qs.QSDetailItemsList;
+import com.android.systemui.qs.QSTile;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
+
+import cyanogenmod.app.Profile;
+import cyanogenmod.app.ProfileManager;
+import cyanogenmod.app.StatusBarPanelCustomTile;
+import cyanogenmod.providers.CMSettings;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+public class ProfilesTile extends QSTile<QSTile.State> {
+
+ private static final Intent PROFILES_SETTINGS =
+ new Intent("android.settings.PROFILES_SETTINGS");
+
+ private boolean mListening;
+ private ProfilesObserver mObserver;
+ private ProfileManager mProfileManager;
+ private QSDetailItemsList mDetails;
+ private ProfileAdapter mAdapter;
+
+ public ProfilesTile(Host host) {
+ super(host);
+ mProfileManager = ProfileManager.getInstance(mContext);
+ mObserver = new ProfilesObserver(mHandler);
+ }
+
+ @Override
+ protected State newTileState() {
+ return new State();
+ }
+
+ @Override
+ protected void handleClick() {
+ showDetail(true);
+ }
+
+ @Override
+ protected void handleLongClick() {
+ mHost.startActivityDismissingKeyguard(PROFILES_SETTINGS);
+ }
+
+ @Override
+ protected void handleUpdateState(State state, Object arg) {
+ state.visible = true;
+ if (profilesEnabled()) {
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_profiles_on);
+ state.label = mProfileManager.getActiveProfile().getName();
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_profiles, state.label);
+ } else {
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_profiles_off);
+ state.label = mContext.getString(R.string.quick_settings_profiles_off);
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_profiles_off);
+ }
+ }
+
+ @Override
+ protected String composeChangeAnnouncement() {
+ if (profilesEnabled()) {
+ return mContext.getString(R.string.accessibility_quick_settings_profiles_changed,
+ mState.label);
+ } else {
+ return mContext.getString(R.string.accessibility_quick_settings_profiles_changed_off);
+ }
+ }
+
+ private boolean profilesEnabled() {
+ return CMSettings.System.getInt(mContext.getContentResolver(),
+ CMSettings.System.SYSTEM_PROFILES_ENABLED, 1) == 1;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsConstants.DONT_TRACK_ME_BRO;
+ }
+
+ @Override
+ public void setListening(boolean listening) {
+ if (mListening == listening) return;
+ mListening = listening;
+ if (listening) {
+ mObserver.startObserving();
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(ProfileManager.INTENT_ACTION_PROFILE_SELECTED);
+ filter.addAction(ProfileManager.INTENT_ACTION_PROFILE_UPDATED);
+ mContext.registerReceiver(mReceiver, filter);
+ } else {
+ mObserver.endObserving();
+ mContext.unregisterReceiver(mReceiver);
+ }
+ }
+
+ @Override
+ public DetailAdapter getDetailAdapter() {
+ return new ProfileDetailAdapter();
+ }
+
+ private class ProfileAdapter extends ArrayAdapter<Profile> {
+ public ProfileAdapter(Context context, List<Profile> profiles) {
+ super(context, android.R.layout.simple_list_item_single_choice, profiles);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LayoutInflater inflater = LayoutInflater.from(mContext);
+ CheckedTextView label = (CheckedTextView) inflater.inflate(
+ android.R.layout.simple_list_item_single_choice, parent, false);
+
+ Profile p = getItem(position);
+ label.setText(p.getName());
+
+ return label;
+ }
+ }
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (ProfileManager.INTENT_ACTION_PROFILE_SELECTED.equals(intent.getAction())
+ || ProfileManager.INTENT_ACTION_PROFILE_UPDATED.equals(intent.getAction())) {
+ refreshState();
+ }
+ }
+ };
+
+ public class ProfileDetailAdapter implements DetailAdapter, AdapterView.OnItemClickListener {
+
+ private List<Profile> mProfilesList;
+
+ @Override
+ public int getTitle() {
+ return R.string.quick_settings_profiles;
+ }
+
+ @Override
+ public Boolean getToggleState() {
+ boolean enabled = profilesEnabled();
+ rebuildProfilesList(enabled);
+ return enabled;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsConstants.DONT_TRACK_ME_BRO;
+ }
+
+ @Override
+ public View createDetailView(Context context, View convertView, ViewGroup parent) {
+ mDetails = QSDetailItemsList.convertOrInflate(context, convertView, parent);
+ mProfilesList = new ArrayList<>();
+ mDetails.setAdapter(mAdapter = new ProfileAdapter(context, mProfilesList));
+
+ final ListView list = mDetails.getListView();
+ list.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
+ list.setOnItemClickListener(this);
+
+ mDetails.setEmptyState(R.drawable.ic_qs_profiles_off,
+ R.string.quick_settings_profiles_off);
+
+ return mDetails;
+ }
+
+ private void rebuildProfilesList(boolean populate) {
+ mProfilesList.clear();
+ if (populate) {
+ int selected = -1;
+
+ final Profile[] profiles = mProfileManager.getProfiles();
+ final Profile activeProfile = mProfileManager.getActiveProfile();
+ final UUID activeUuid = activeProfile != null ? activeProfile.getUuid() : null;
+
+ for (int i = 0; i < profiles.length; i++) {
+ mProfilesList.add(profiles[i]);
+ if (activeUuid != null && activeUuid.equals(profiles[i].getUuid())) {
+ selected = i;
+ }
+ }
+ mDetails.getListView().setItemChecked(selected, true);
+ }
+ mAdapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public Intent getSettingsIntent() {
+ return PROFILES_SETTINGS;
+ }
+
+ @Override
+ public StatusBarPanelCustomTile getCustomTile() {
+ return null;
+ }
+
+ @Override
+ public void setToggleState(boolean state) {
+ CMSettings.System.putInt(mContext.getContentResolver(),
+ CMSettings.System.SYSTEM_PROFILES_ENABLED, state ? 1 : 0);
+ fireToggleStateChanged(state);
+ rebuildProfilesList(state);
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ Profile selected = (Profile) parent.getItemAtPosition(position);
+ mProfileManager.setActiveProfile(selected.getUuid());
+ }
+ }
+
+ private class ProfilesObserver extends ContentObserver {
+ public ProfilesObserver(Handler handler) {
+ super(handler);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ refreshState();
+ }
+
+ public void startObserving() {
+ mContext.getContentResolver().registerContentObserver(
+ CMSettings.System.getUriFor(CMSettings.System.SYSTEM_PROFILES_ENABLED),
+ false, this);
+ }
+
+ public void endObserving() {
+ mContext.getContentResolver().unregisterContentObserver(this);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index 1938325..2cd0971 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -51,6 +51,7 @@ import com.android.systemui.qs.tiles.HotspotTile;
import com.android.systemui.qs.tiles.IntentTile;
import com.android.systemui.qs.tiles.LocationTile;
import com.android.systemui.qs.tiles.NfcTile;
+import com.android.systemui.qs.tiles.ProfilesTile;
import com.android.systemui.qs.tiles.RotationLockTile;
import com.android.systemui.qs.tiles.SyncTile;
import com.android.systemui.qs.tiles.VolumeTile;
@@ -336,6 +337,7 @@ public class QSTileHost implements QSTile.Host, Tunable {
else if (tileSpec.equals("edit")) return new EditTile(this);
else if (tileSpec.equals("compass")) return new CompassTile(this);
else if (tileSpec.equals("nfc")) return new NfcTile(this);
+ else if (tileSpec.equals("profiles")) return new ProfilesTile(this);
else if (tileSpec.equals("sync")) return new SyncTile(this);
else if (tileSpec.equals("volume_panel")) return new VolumeTile(this);
else if (tileSpec.startsWith(IntentTile.PREFIX)) return IntentTile.create(this,tileSpec);
@@ -411,6 +413,7 @@ public class QSTileHost implements QSTile.Host, Tunable {
else if (spec.equals("adb_network")) return R.string.qs_tile_adb_over_network;
else if (spec.equals("compass")) return R.string.qs_tile_compass;
else if (spec.equals("nfc")) return R.string.quick_settings_nfc;
+ else if (spec.equals("profiles")) return R.string.quick_settings_profiles;
else if (spec.equals("sync")) return R.string.quick_settings_sync_label;
else if (spec.equals("volume_panel")) return R.string.quick_settings_volume_panel_label;
return 0;