diff options
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.java | 349 |
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; + } + } +} |