summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI/src/com/android/systemui/qs/tiles/CustomQSTile.java
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SystemUI/src/com/android/systemui/qs/tiles/CustomQSTile.java')
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CustomQSTile.java349
1 files changed, 349 insertions, 0 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CustomQSTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CustomQSTile.java
new file mode 100644
index 0000000..40c7184
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CustomQSTile.java
@@ -0,0 +1,349 @@
+/*
+ * 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.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.content.res.ThemeConfig;
+import android.net.Uri;
+import android.os.Process;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.Log;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.RemoteViews;
+import android.widget.TextView;
+
+import com.android.systemui.qs.QSDetailItemsGrid;
+import com.android.systemui.qs.QSDetailItemsList;
+import cyanogenmod.app.CustomTile;
+import cyanogenmod.app.StatusBarPanelCustomTile;
+
+import com.android.systemui.R;
+import com.android.systemui.qs.QSTile;
+import org.cyanogenmod.internal.logging.CMMetricsLogger;
+
+import java.util.Arrays;
+
+public class CustomQSTile extends QSTile<QSTile.State> {
+
+ private static final String HIDDEN_TILES_PREF_NAME = "user_hidden_qs_tiles";
+
+ private CustomTile.ExpandedStyle mExpandedStyle;
+ private PendingIntent mOnClick;
+ private PendingIntent mOnLongClick;
+ private Uri mOnClickUri;
+ private int mCurrentUserId;
+ private StatusBarPanelCustomTile mTile;
+ private CustomQSDetailAdapter mDetailAdapter;
+ private boolean mCollapsePanel;
+ private boolean mUserRemoved;
+ private String mPersistedPlaceHolderKey;
+
+ public CustomQSTile(Host host, String persistedSpec) {
+ super(host);
+ mTile = null;
+ mPersistedPlaceHolderKey = persistedSpec;
+ }
+
+ public CustomQSTile(Host host, StatusBarPanelCustomTile tile) {
+ super(host);
+ mTile = tile;
+ mUserRemoved = getIsUserRemovedPersisted();
+ }
+
+ private String getPersistableKey() {
+ if (mPersistedPlaceHolderKey != null) {
+ return mPersistedPlaceHolderKey;
+ } else {
+ return getTile().persistableKey();
+ }
+ }
+
+ private boolean getIsUserRemovedPersisted() {
+ return getCustomQSTilePrefs(mContext).getBoolean(getPersistableKey(), false);
+ }
+
+ public boolean isUserRemoved() {
+ return mUserRemoved;
+ }
+
+ public void setUserRemoved(boolean removed) {
+ if (mUserRemoved != removed) {
+ if (removed) {
+ getCustomQSTilePrefs(mContext).edit().putBoolean(getPersistableKey(), true).apply();
+ } else {
+ getCustomQSTilePrefs(mContext).edit().remove(getPersistableKey()).apply();
+ }
+ mUserRemoved = removed;
+ refreshState();
+ }
+ }
+
+ public static SharedPreferences getCustomQSTilePrefs(Context context) {
+ return context.getSharedPreferences(HIDDEN_TILES_PREF_NAME, Context.MODE_PRIVATE);
+ }
+
+ @Override
+ public DetailAdapter getDetailAdapter() {
+ return mDetailAdapter;
+ }
+
+ @Override
+ public void setListening(boolean listening) {
+ }
+
+ @Override
+ protected State newTileState() {
+ return new State();
+ }
+
+ @Override
+ protected void handleUserSwitch(int newUserId) {
+ super.handleUserSwitch(newUserId);
+ mCurrentUserId = newUserId;
+ }
+
+ public void update(StatusBarPanelCustomTile customTile) {
+ refreshState(customTile);
+ }
+
+ @Override
+ protected void handleLongClick() {
+ if (mOnLongClick != null) {
+ if (mOnLongClick.isActivity()) {
+ getHost().collapsePanels();
+ }
+ try {
+ mOnLongClick.send();
+ } catch (Throwable e) {
+ Log.w(TAG, "Error sending long click intent", e);
+ }
+ } else if (mExpandedStyle == null) {
+ showDetail(true);
+ }
+ }
+
+ @Override
+ protected void handleClick() {
+ try {
+ if (mExpandedStyle != null &&
+ mExpandedStyle.getStyle() != CustomTile.ExpandedStyle.NO_STYLE) {
+ showDetail(true);
+ return;
+ }
+ if (mCollapsePanel) {
+ mHost.collapsePanels();
+ }
+ if (mOnClick != null) {
+ mOnClick.send();
+ } else if (mOnClickUri != null) {
+ mHost.collapsePanels();
+ final Intent intent = new Intent().setData(mOnClickUri);
+ mContext.sendBroadcastAsUser(intent, new UserHandle(mCurrentUserId));
+ }
+ } catch (Throwable t) {
+ Log.w(TAG, "Error sending click intent", t);
+ }
+ }
+
+ public StatusBarPanelCustomTile getTile() {
+ return mTile;
+ }
+
+ @Override
+ protected void handleUpdateState(State state, Object arg) {
+ if (arg instanceof StatusBarPanelCustomTile) {
+ mTile = (StatusBarPanelCustomTile) arg;
+ mPersistedPlaceHolderKey = null;
+ mUserRemoved = getIsUserRemovedPersisted();
+ }
+ if (mTile == null) {
+ state.visible = false;
+ // nothing to show, it's a place holder for now
+ return;
+ }
+ final CustomTile customTile = mTile.getCustomTile();
+ state.contentDescription = customTile.contentDescription;
+ state.label = customTile.label;
+ state.visible = !mUserRemoved;
+ final int iconId = customTile.icon;
+ if (iconId != 0 && (customTile.remoteIcon == null)) {
+ final String iconPackage = mTile.getResPkg();
+ if (!TextUtils.isEmpty(iconPackage)) {
+ state.icon = new ExternalIcon(iconPackage, iconId);
+ }
+ } else {
+ state.icon = new ExternalBitmapIcon(customTile.remoteIcon);
+ }
+ mOnClick = customTile.onClick;
+ mOnLongClick = customTile.onLongClick;
+ mOnClickUri = customTile.onClickUri;
+ mExpandedStyle = customTile.expandedStyle;
+ mCollapsePanel = customTile.collapsePanel;
+ mDetailAdapter = new CustomQSDetailAdapter();
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return CMMetricsLogger.TILE_CUSTOM_QS;
+ }
+
+ private boolean isDynamicTile() {
+ return mTile.getPackage().equals(mContext.getPackageName())
+ || mTile.getUid() == Process.SYSTEM_UID;
+ }
+
+ private class CustomQSDetailAdapter implements DetailAdapter, AdapterView.OnItemClickListener,
+ QSDetailItemsGrid.QSDetailItemsGridAdapter.OnPseudoGriditemClickListener {
+ private QSDetailItemsList.QSCustomDetailListAdapter mListAdapter;
+ private QSDetailItemsGrid.QSDetailItemsGridAdapter mGridAdapter;
+
+ public int getTitle() {
+ if (isDynamicTile()) {
+ return mContext.getResources().getIdentifier(
+ String.format("dynamic_qs_tile_%s_label", mTile.getTag()),
+ "string", mContext.getPackageName());
+ }
+ return R.string.quick_settings_custom_tile_detail_title;
+ }
+
+ @Override
+ public Boolean getToggleState() {
+ return null;
+ }
+
+
+ @Override
+ public Intent getSettingsIntent() {
+ return mTile.getCustomTile().onSettingsClick;
+ }
+
+ @Override
+ public StatusBarPanelCustomTile getCustomTile() {
+ return mTile;
+ }
+
+ @Override
+ public void setToggleState(boolean state) {
+ // noop
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return CMMetricsLogger.TILE_CUSTOM_QS_DETAIL;
+ }
+
+ @Override
+ public View createDetailView(Context context, View convertView, ViewGroup parent) {
+ View rootView = null;
+ if (mExpandedStyle == null) {
+ rootView = (LinearLayout) LayoutInflater.from(context)
+ .inflate(R.layout.qs_custom_detail, parent, false);
+ ImageView imageView = (ImageView)
+ rootView.findViewById(R.id.custom_qs_tile_icon);
+ TextView customTileTitle = (TextView)
+ rootView.findViewById(R.id.custom_qs_tile_title);
+ TextView customTilePkg = (TextView) rootView
+ .findViewById(R.id.custom_qs_tile_package);
+ TextView customTileContentDesc = (TextView) rootView
+ .findViewById(R.id.custom_qs_tile_content_description);
+ // icon is cached in state, fetch it
+ imageView.setImageDrawable(getState().icon.getDrawable(mContext));
+ customTileTitle.setText(mTile.getCustomTile().label);
+ if (isDynamicTile()) {
+ customTilePkg.setText(R.string.quick_settings_dynamic_tile_detail_title);
+ } else {
+ customTilePkg.setText(mTile.getPackage());
+ customTileContentDesc.setText(mTile.getCustomTile().contentDescription);
+ }
+ } else {
+ switch (mExpandedStyle.getStyle()) {
+ case CustomTile.ExpandedStyle.GRID_STYLE:
+ rootView = QSDetailItemsGrid.inflate(context, parent, false);
+ mGridAdapter = ((QSDetailItemsGrid) rootView)
+ .createAndSetAdapter(mTile.getPackage(),
+ mExpandedStyle.getExpandedItems());
+ mGridAdapter.setOnPseudoGridItemClickListener(this);
+ break;
+ case CustomTile.ExpandedStyle.REMOTE_STYLE:
+ rootView = (LinearLayout) LayoutInflater.from(context)
+ .inflate(R.layout.qs_custom_detail_remote, parent, false);
+ RemoteViews remoteViews = mExpandedStyle.getContentViews();
+ if (remoteViews != null) {
+ View localView = mTile.getCustomTile().expandedStyle.getContentViews()
+ .apply(context, (ViewGroup) rootView,
+ mHost.getOnClickHandler(), getThemePackageName());
+ ((LinearLayout) rootView).addView(localView);
+ } else {
+ Log.d(TAG, "Unable to add null remoteview for " + mTile.getOpPkg());
+ }
+ break;
+ case CustomTile.ExpandedStyle.LIST_STYLE:
+ default:
+ rootView = QSDetailItemsList.convertOrInflate(context, convertView, parent);
+ ListView listView = ((QSDetailItemsList) rootView).getListView();
+ listView.setDivider(null);
+ listView.setOnItemClickListener(this);
+ listView.setAdapter(mListAdapter =
+ new QSDetailItemsList.QSCustomDetailListAdapter(mTile.getPackage(),
+ context, Arrays.asList(mExpandedStyle.getExpandedItems())));
+ break;
+ }
+ }
+ return rootView;
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
+ CustomTile.ExpandedItem item = mListAdapter.getItem(position);
+ sendEvent(item.onClickPendingIntent);
+ }
+
+ @Override
+ public void onPsuedoGridItemClick(View view, CustomTile.ExpandedItem item) {
+ sendEvent(item.onClickPendingIntent);
+ }
+
+ private void sendEvent(PendingIntent intent) {
+ try {
+ if (intent.isActivity()) {
+ mHost.collapsePanels();
+ }
+ intent.send();
+ } catch (PendingIntent.CanceledException e) {
+ //
+ }
+ }
+
+ private String getThemePackageName() {
+ final Configuration config = mContext.getResources().getConfiguration();
+ final ThemeConfig themeConfig = config != null ? config.themeConfig : null;
+ return themeConfig != null ? themeConfig.getOverlayForStatusBar() : null;
+ }
+ }
+}