diff options
Diffstat (limited to 'packages/SystemUI')
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; |