summaryrefslogtreecommitdiffstats
path: root/src/org/cyanogenmod/theme/chooser2/ComponentSelector.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/cyanogenmod/theme/chooser2/ComponentSelector.java')
-rw-r--r--src/org/cyanogenmod/theme/chooser2/ComponentSelector.java934
1 files changed, 934 insertions, 0 deletions
diff --git a/src/org/cyanogenmod/theme/chooser2/ComponentSelector.java b/src/org/cyanogenmod/theme/chooser2/ComponentSelector.java
new file mode 100644
index 0000000..178c9b6
--- /dev/null
+++ b/src/org/cyanogenmod/theme/chooser2/ComponentSelector.java
@@ -0,0 +1,934 @@
+/*
+ * Copyright (C) 2016 Cyanogen, Inc.
+ * Copyright (C) 2016 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 org.cyanogenmod.theme.chooser2;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.graphics.Typeface;
+import android.graphics.drawable.BitmapDrawable;
+import android.media.MediaPlayer;
+import android.media.RingtoneManager;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.Loader;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.Animation.AnimationListener;
+import android.view.animation.AnimationUtils;
+import android.widget.ComponentSelectorLinearLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import org.cyanogenmod.theme.util.AudioUtils;
+import org.cyanogenmod.theme.util.CursorLoaderHelper;
+import org.cyanogenmod.theme.util.ThemedTypefaceHelper;
+import org.cyanogenmod.theme.util.TypefaceHelperCache;
+import org.cyanogenmod.theme.util.Utils;
+
+import cyanogenmod.providers.ThemesContract;
+import cyanogenmod.providers.ThemesContract.PreviewColumns;
+import cyanogenmod.providers.ThemesContract.ThemesColumns;
+
+import java.util.Map;
+
+import static cyanogenmod.providers.ThemesContract.ThemesColumns.MODIFIES_ALARMS;
+import static cyanogenmod.providers.ThemesContract.ThemesColumns.MODIFIES_BOOT_ANIM;
+import static cyanogenmod.providers.ThemesContract.ThemesColumns.MODIFIES_LAUNCHER;
+import static cyanogenmod.providers.ThemesContract.ThemesColumns.MODIFIES_LIVE_LOCK_SCREEN;
+import static cyanogenmod.providers.ThemesContract.ThemesColumns.MODIFIES_LOCKSCREEN;
+import static cyanogenmod.providers.ThemesContract.ThemesColumns.MODIFIES_NOTIFICATIONS;
+import static cyanogenmod.providers.ThemesContract.ThemesColumns.MODIFIES_OVERLAYS;
+import static cyanogenmod.providers.ThemesContract.ThemesColumns.MODIFIES_RINGTONES;
+import static cyanogenmod.providers.ThemesContract.ThemesColumns.MODIFIES_STATUS_BAR;
+import static cyanogenmod.providers.ThemesContract.ThemesColumns.MODIFIES_NAVIGATION_BAR;
+import static cyanogenmod.providers.ThemesContract.ThemesColumns.MODIFIES_ICONS;
+import static cyanogenmod.providers.ThemesContract.ThemesColumns.MODIFIES_FONTS;
+
+import static org.cyanogenmod.theme.util.CursorLoaderHelper.LOADER_ID_STATUS_BAR;
+import static org.cyanogenmod.theme.util.CursorLoaderHelper.LOADER_ID_FONT;
+import static org.cyanogenmod.theme.util.CursorLoaderHelper.LOADER_ID_ICONS;
+import static org.cyanogenmod.theme.util.CursorLoaderHelper.LOADER_ID_WALLPAPER;
+import static org.cyanogenmod.theme.util.CursorLoaderHelper.LOADER_ID_NAVIGATION_BAR;
+import static org.cyanogenmod.theme.util.CursorLoaderHelper.LOADER_ID_LOCKSCREEN;
+import static org.cyanogenmod.theme.util.CursorLoaderHelper.LOADER_ID_STYLE;
+import static org.cyanogenmod.theme.util.CursorLoaderHelper.LOADER_ID_BOOT_ANIMATION;
+import static org.cyanogenmod.theme.util.CursorLoaderHelper.LOADER_ID_RINGTONE;
+import static org.cyanogenmod.theme.util.CursorLoaderHelper.LOADER_ID_NOTIFICATION;
+import static org.cyanogenmod.theme.util.CursorLoaderHelper.LOADER_ID_ALARM;
+
+public class ComponentSelector extends LinearLayout
+ implements LoaderManager.LoaderCallbacks<Cursor> {
+ private static final String TAG = ComponentSelector.class.getSimpleName();
+
+ public static final boolean DEBUG_SELECTOR = false;
+
+ public static final String EXTERNAL_WALLPAPER = "external";
+
+ public static final String MOD_LOCK = "mod_lock";
+
+ private static final int EXTRA_WALLPAPER_COMPONENTS = 2;
+
+ private static final int EXTRA_LOCK_SCREEN_WALLPAPER_COMPONENTS = 3;
+
+ protected static final long DEFAULT_COMPONENT_ID = 0;
+
+ private Context mContext;
+ private LayoutInflater mInflater;
+ private ComponentSelectorLinearLayout mContent;
+ private LinearLayout.LayoutParams mItemParams;
+ private LinearLayout.LayoutParams mSoundItemParams =
+ new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0, 1.0f);
+
+ private String mComponentType;
+ private int mBatteryStyle;
+ private int mItemsPerPage;
+ private String mAppliedComponentPkgName;
+ private String mSelectedComponentPkgName;
+ private long mSelectedComponentId;
+
+ // animations for bringing selector in and out of view
+ private Animation mAnimateIn;
+ private Animation mAnimateOut;
+
+ private OnItemClickedListener mListener;
+
+ private OnOpenCloseListener mOpenCloseListener;
+
+ private MediaPlayer mMediaPlayer;
+ private ImageView mCurrentPlayPause;
+
+ private TypefaceHelperCache mTypefaceCache;
+
+ private ThemesObserver mThemesObserver;
+
+ public static final String IS_LIVE_LOCK_SCREEN_VIEW = "is_live_lock_screen_view";
+ private View mPrevLockScreenView;
+
+ public ComponentSelector(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ComponentSelector);
+ mItemsPerPage = a.getInt(R.styleable.ComponentSelector_itemsPerPage,
+ context.getResources().getInteger(R.integer.default_items_per_page));
+ a.recycle();
+
+ mContext = context;
+ mInflater = LayoutInflater.from(context);
+ // TODO: Load from settings once available
+ mBatteryStyle = 0; /*Settings.System.getInt(context.getContentResolver(),
+ Settings.System.STATUS_BAR_BATTERY_STYLE, 0);*/
+
+ mAnimateIn = AnimationUtils.loadAnimation(mContext,
+ R.anim.component_selection_animate_in);
+ mAnimateOut = AnimationUtils.loadAnimation(mContext,
+ R.anim.component_selection_animate_out);
+ mAnimateIn.setAnimationListener(new AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) {
+ }
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ if (mOpenCloseListener != null) mOpenCloseListener.onSelectorOpened();
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) {
+ }
+ });
+ mAnimateOut.setAnimationListener(new AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) {
+ if (mOpenCloseListener != null) mOpenCloseListener.onSelectorClosing();
+ }
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) {
+ }
+ });
+ mMediaPlayer = new MediaPlayer();
+ mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+ @Override
+ public void onCompletion(MediaPlayer mp) {
+ if (mCurrentPlayPause != null) {
+ mCurrentPlayPause.setImageResource(R.drawable.media_sound_selector_preview);
+ mCurrentPlayPause = null;
+ }
+ }
+ });
+ mTypefaceCache = TypefaceHelperCache.getInstance();
+ mThemesObserver = new ThemesObserver();
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mContent = (ComponentSelectorLinearLayout) findViewById(R.id.content);
+ setEnabled(false);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mThemesObserver.register();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mThemesObserver.unregister();
+ }
+
+ @Override
+ protected void onWindowVisibilityChanged(int visibility) {
+ super.onWindowVisibilityChanged(visibility);
+ // Window visibility transitions as follows
+ // VISIBLE -> INVISIBLE -> GONE
+ // GONE -> INVISIBLE -> VISIBLE
+ if (visibility == View.GONE) {
+ mThemesObserver.unregister();
+ } else if (visibility == View.VISIBLE) {
+ mThemesObserver.register();
+ }
+ }
+
+ public void resetComponentType() {
+ mComponentType = null;
+ }
+
+ public void setComponentType(String component) {
+ setComponentType(component, null, DEFAULT_COMPONENT_ID);
+ }
+
+ public void setComponentType(String component, String selectedPkgName) {
+ setComponentType(component, null, DEFAULT_COMPONENT_ID);
+ }
+
+ public void setComponentType(String component, String selectedPkgName,
+ long selectedComponentId) {
+ mSelectedComponentPkgName = selectedPkgName;
+ mSelectedComponentId = selectedComponentId;
+ if (mComponentType == null || !mComponentType.equals(component)) {
+ mContent.removeAllViews();
+ mComponentType = component;
+ ((FragmentActivity) mContext).getSupportLoaderManager().restartLoader(
+ getLoaderIdFromComponent(component), null, this);
+ } else if (mComponentType != null) {
+ int count = mContent.getChildCount();
+ final Resources res = getResources();
+ boolean highlightTitle;
+ Map<String, String> selectedComponents = null;
+ if (mComponentType.equals(MODIFIES_LOCKSCREEN)) {
+ selectedComponents = ((ChooserActivity)mContext)
+ .getSelectedComponentsMap();
+ }
+ for (int i = 0; i < count; i++) {
+ final View child = mContent.getChildAt(i);
+ final TextView tv = (TextView) child.findViewById(R.id.title);
+ // The child itself may have the tag, or in the case of sounds its the grandchild,
+ // either way the parent of the textview will have the pkgName in its tag
+ final View viewWithTag = (View) tv.getParent();
+ final String pkgName = (String) viewWithTag.getTag(R.id.tag_key_package_name);
+ Long cmpntId = (Long) viewWithTag.getTag(R.id.tag_key_component_id);
+ if (cmpntId == null) {
+ cmpntId = DEFAULT_COMPONENT_ID;
+ }
+ Boolean isLLS = (Boolean) viewWithTag.getTag(R.id.tag_key_live_lock_screen);
+ highlightTitle = false;
+ if (selectedComponents != null && isLLS != null) {
+ if ((TextUtils.equals(selectedComponents.get(MODIFIES_LOCKSCREEN), pkgName)
+ && !isLLS) || (TextUtils.equals(selectedComponents.get(
+ MODIFIES_LIVE_LOCK_SCREEN), pkgName) && isLLS)) {
+ highlightTitle = true;
+ }
+ } else if (pkgName.equals(selectedPkgName) && cmpntId == selectedComponentId) {
+ highlightTitle = true;
+ }
+ if (highlightTitle) {
+ tv.setTextColor(res.getColor(R.color.component_selection_current_text_color));
+ } else {
+ tv.setTextColor(res.getColor(android.R.color.white));
+ }
+ }
+ }
+ }
+
+ public String getComponentType() {
+ return mComponentType;
+ }
+
+ public void setNumItemsPerPage(int itemsPerPage) {
+ if (mItemsPerPage != itemsPerPage) {
+ mItemsPerPage = itemsPerPage;
+ }
+ }
+
+ public void setHeight(int height) {
+ ViewGroup.LayoutParams params = mContent.getLayoutParams();
+ if (params.height != height) {
+ params.height = height;
+ mContent.setLayoutParams(params);
+ requestLayout();
+ }
+ }
+
+ public void show(String componentType, int itemsPerPage, int height) {
+ show(componentType, null, itemsPerPage, height);
+ }
+
+ public void show(String componentType, String selectedPkgName, int itemsPerPage, int height) {
+ show(componentType, selectedPkgName, DEFAULT_COMPONENT_ID, itemsPerPage, height);
+ }
+
+ public void show(String componentType, String selectedPkgName, long selectedComponentId,
+ int itemsPerPage, int height) {
+ setNumItemsPerPage(itemsPerPage);
+ setHeight(height);
+ setComponentType(componentType, selectedPkgName, selectedComponentId);
+ show();
+ }
+
+ public void show() {
+ if (getVisibility() == View.GONE) {
+ setEnabled(true);
+ setVisibility(View.VISIBLE);
+ startAnimation(mAnimateIn);
+ }
+ }
+
+ public void hide() {
+ if (getVisibility() == View.VISIBLE && isEnabled()) {
+ setEnabled(false);
+ startAnimation(mAnimateOut);
+ }
+ if (mMediaPlayer != null && mMediaPlayer.isPlaying()) mMediaPlayer.stop();
+ }
+
+ private int getLoaderIdFromComponent(String component) {
+ if (MODIFIES_STATUS_BAR.equals(component)) {
+ return LOADER_ID_STATUS_BAR;
+ }
+ if (MODIFIES_NAVIGATION_BAR.equals(component)) {
+ return LOADER_ID_NAVIGATION_BAR;
+ }
+ if (MODIFIES_FONTS.equals(component)) {
+ return LOADER_ID_FONT;
+ }
+ if (MODIFIES_ICONS.equals(component)) {
+ return LOADER_ID_ICONS;
+ }
+ if (MODIFIES_OVERLAYS.equals(component)) {
+ return LOADER_ID_STYLE;
+ }
+ if (MODIFIES_LAUNCHER.equals(component)) {
+ return LOADER_ID_WALLPAPER;
+ }
+ if (MODIFIES_BOOT_ANIM.equals(component)) {
+ return LOADER_ID_BOOT_ANIMATION;
+ }
+ if (MODIFIES_RINGTONES.equals(component)) {
+ return LOADER_ID_RINGTONE;
+ }
+ if (MODIFIES_NOTIFICATIONS.equals(component)) {
+ return LOADER_ID_NOTIFICATION;
+ }
+ if (MODIFIES_ALARMS.equals(component)) {
+ return LOADER_ID_ALARM;
+ }
+ if (MODIFIES_LOCKSCREEN.equals(component)) {
+ return LOADER_ID_LOCKSCREEN;
+ }
+ return -1;
+ }
+
+ @Override
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ return CursorLoaderHelper.componentSelectorCursorLoader(mContext, id);
+ }
+
+ @Override
+ public void onLoadFinished(Loader<Cursor> loader, final Cursor data) {
+ int currentLoaderId = loader.getId();
+ int count = data.getCount();
+ int screenWidth = mContext.getResources().getDisplayMetrics().widthPixels;
+ final Resources res = getResources();
+ int dividerPadding = res.getDimensionPixelSize(R.dimen.component_divider_padding_top);
+ int dividerHeight = res.getDimensionPixelSize(R.dimen.component_divider_height);
+ MatrixCursor lockScreenMatrixCursor = null;
+
+ switch (currentLoaderId) {
+ case LOADER_ID_ALARM:
+ case LOADER_ID_NOTIFICATION:
+ case LOADER_ID_RINGTONE:
+ mItemParams = new LayoutParams(screenWidth,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ // Sounds are a special case where there are two items laid out
+ // vertically. This layout is added as a single item so we need to
+ // adjust the count by dividing by the number of items per page and
+ // rounding up so we include all items.
+ count = (int) Math.ceil((double)count / mItemsPerPage);
+ mContent.setShowDividers(LinearLayout.SHOW_DIVIDER_NONE);
+ break;
+ case LOADER_ID_BOOT_ANIMATION:
+ dividerPadding = res.getDimensionPixelSize(
+ R.dimen.component_divider_padding_top_bootani);
+ dividerHeight = res.getDimensionPixelSize(R.dimen.component_divider_height_bootani);
+ // fall through to default
+ default:
+ mItemParams = new LayoutParams(screenWidth / mItemsPerPage,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ if (currentLoaderId == LOADER_ID_WALLPAPER ||
+ currentLoaderId == LOADER_ID_LOCKSCREEN) {
+ count += EXTRA_WALLPAPER_COMPONENTS;
+ }
+
+ if (currentLoaderId == LOADER_ID_LOCKSCREEN) {
+ lockScreenMatrixCursor = splitLockScreenCursor(data);
+ if (lockScreenMatrixCursor != null) {
+ count = lockScreenMatrixCursor.getCount() + EXTRA_WALLPAPER_COMPONENTS;
+ }
+ }
+
+ mContent.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
+ break;
+ }
+
+ mContent.setDividerPadding(dividerPadding);
+ mContent.setDividerHeight(dividerHeight);
+
+ new LoadItemsTask().execute((lockScreenMatrixCursor != null)
+ ? lockScreenMatrixCursor : data, count);
+ }
+
+ /* Some themes might contain a lock wallpaper AND a live lock screen.
+ * ThemesProvider will return one single row containing both thumbnail paths
+ * (ThemesProvider groups by theme_id) so we need to create a cursor on the
+ * fly to split that row into 2 to properly generate a view for each thumbnail
+ */
+ private MatrixCursor splitLockScreenCursor(Cursor data) {
+ int lockWallPaperThumbnailIndx, llsThumbnailIndx, pkgIndx;
+ String lockWallPaperThumbnail, liveLockScreenThumbnail, pkgName;
+ MatrixCursor lockScreenMatrixCursor;
+ int needToSplitRowAt = -1;
+
+ lockWallPaperThumbnailIndx = data.getColumnIndex(PreviewColumns.LOCK_WALLPAPER_THUMBNAIL);
+ llsThumbnailIndx = data.getColumnIndex(PreviewColumns.LIVE_LOCK_SCREEN_THUMBNAIL);
+ pkgIndx = data.getColumnIndex(ThemesColumns.PKG_NAME);
+
+ if (lockWallPaperThumbnailIndx < 0 || llsThumbnailIndx < 0 || pkgIndx < 0) {
+ //An invalid cursor was provided, we can't continue processing
+ Log.e(TAG, "Failed to process cursor due to missing columns");
+ return null;
+ }
+
+ //Let's find out if we really need to allocate a MatrixCursor.
+ //If we find at least one row with valid data in lock_wallpaper_thumbnail AND
+ //live_lock_screen_thumbnail it means we do.
+ data.moveToPosition(-1);
+ while (data.moveToNext()) {
+ lockWallPaperThumbnail = data.getString(lockWallPaperThumbnailIndx);
+ liveLockScreenThumbnail = data.getString(llsThumbnailIndx);
+ if (!TextUtils.isEmpty(lockWallPaperThumbnail)
+ && !TextUtils.isEmpty(liveLockScreenThumbnail)) {
+ needToSplitRowAt = data.getPosition();
+ break;
+ }
+ }
+
+ if (needToSplitRowAt == -1) return null;
+
+ lockScreenMatrixCursor = new MatrixCursor(data.getColumnNames());
+ //Clone all the *regular* rows up to needToSplitRowAt
+ for (int indx = 0; indx < needToSplitRowAt; indx++) {
+ data.moveToPosition(indx);
+ lockScreenMatrixCursor.addRow(CursorLoaderHelper.getRowFromCursor(data));
+ }
+ if (needToSplitRowAt == 0) {
+ data.moveToPosition(-1);
+ }
+ while (data.moveToNext()) {
+ lockWallPaperThumbnail = data.getString(lockWallPaperThumbnailIndx);
+ liveLockScreenThumbnail = data.getString(llsThumbnailIndx);
+ if (!TextUtils.isEmpty(lockWallPaperThumbnail)
+ && !TextUtils.isEmpty(liveLockScreenThumbnail)) {
+ pkgName = data.getString(pkgIndx);
+
+ MatrixCursor.RowBuilder lockWallpaperRow = lockScreenMatrixCursor.newRow();
+ MatrixCursor.RowBuilder liveLockScreenRow = lockScreenMatrixCursor.newRow();
+
+ for (String col : data.getColumnNames()) {
+ if (TextUtils.equals(col, PreviewColumns.LOCK_WALLPAPER_THUMBNAIL)) {
+ lockWallpaperRow.add(PreviewColumns.LOCK_WALLPAPER_THUMBNAIL,
+ lockWallPaperThumbnail);
+ liveLockScreenRow.add(PreviewColumns.LOCK_WALLPAPER_THUMBNAIL, null);
+ } else if (TextUtils.equals(col, PreviewColumns.LIVE_LOCK_SCREEN_THUMBNAIL)) {
+ lockWallpaperRow.add(PreviewColumns.LIVE_LOCK_SCREEN_THUMBNAIL, null);
+ liveLockScreenRow.add(PreviewColumns.LIVE_LOCK_SCREEN_THUMBNAIL,
+ liveLockScreenThumbnail);
+ } else if (TextUtils.equals(col, MODIFIES_LIVE_LOCK_SCREEN)) {
+ lockWallpaperRow.add(MODIFIES_LIVE_LOCK_SCREEN, 0);
+ liveLockScreenRow.add(MODIFIES_LIVE_LOCK_SCREEN, 1);
+ } else {
+ int colIndx = data.getColumnIndex(col);
+ lockWallpaperRow.add(col, CursorLoaderHelper.getFieldValueFromRow(data,
+ colIndx));
+ liveLockScreenRow.add(col, CursorLoaderHelper.getFieldValueFromRow(data,
+ colIndx));
+ }
+ }
+ } else {
+ //This is a regular row, so just clone it
+ lockScreenMatrixCursor.addRow(CursorLoaderHelper.getRowFromCursor(data));
+ }
+ }
+ return lockScreenMatrixCursor;
+ }
+
+ @Override
+ public void onLoaderReset(Loader<Cursor> loader) {
+ }
+
+ public void setOnItemClickedListener(OnItemClickedListener listener) {
+ mListener = listener;
+ }
+
+ public void setOnOpenCloseListener(OnOpenCloseListener listener) {
+ mOpenCloseListener = listener;
+ }
+
+ private View newView(Cursor cursor, int position, ViewGroup container) {
+ if (MODIFIES_STATUS_BAR.equals(mComponentType)) {
+ return newStatusBarView(cursor, container, position);
+ }
+ if (MODIFIES_NAVIGATION_BAR.equals(mComponentType)) {
+ return newNavBarView(cursor, container, position);
+ }
+ if (MODIFIES_FONTS.equals(mComponentType)) {
+ return newFontView(cursor, container, position);
+ }
+ if (MODIFIES_ICONS.equals(mComponentType)) {
+ return newIconView(cursor, container, position);
+ }
+ if (MODIFIES_OVERLAYS.equals(mComponentType)) {
+ return newStyleView(cursor, container, position);
+ }
+ if (MODIFIES_LAUNCHER.equals(mComponentType)) {
+ return newWallpapersView(cursor, container, position,
+ cursor.getColumnIndex(PreviewColumns.WALLPAPER_THUMBNAIL), false,
+ EXTRA_WALLPAPER_COMPONENTS);
+ }
+ if (MODIFIES_BOOT_ANIM.equals(mComponentType)) {
+ return newBootanimationView(cursor, container, position);
+ }
+ if (MODIFIES_RINGTONES.equals(mComponentType) ||
+ MODIFIES_NOTIFICATIONS.equals(mComponentType) ||
+ MODIFIES_ALARMS.equals(mComponentType)) {
+ return newSoundView(cursor, container, position, mComponentType);
+ }
+ if (MODIFIES_LOCKSCREEN.equals(mComponentType)) {
+ boolean isLiveLockScreen = false;
+ if (position >= EXTRA_LOCK_SCREEN_WALLPAPER_COMPONENTS) {
+ cursor.moveToPosition(position - EXTRA_LOCK_SCREEN_WALLPAPER_COMPONENTS);
+ int liveLockIndex = cursor.getColumnIndex(MODIFIES_LIVE_LOCK_SCREEN);
+ isLiveLockScreen = liveLockIndex >= 0 &&
+ cursor.getInt(liveLockIndex) == 1;
+ }
+ int index = isLiveLockScreen
+ ? cursor.getColumnIndex(PreviewColumns.LIVE_LOCK_SCREEN_THUMBNAIL)
+ : cursor.getColumnIndex(PreviewColumns.LOCK_WALLPAPER_THUMBNAIL);
+ return newWallpapersView(cursor, container, position, index, isLiveLockScreen,
+ EXTRA_LOCK_SCREEN_WALLPAPER_COMPONENTS);
+ }
+ return null;
+ }
+
+ private View newStatusBarView(Cursor cursor, ViewGroup parent, int position) {
+ cursor.moveToPosition(position);
+ View v = mInflater.inflate(R.layout.status_bar_component_selection_item,
+ parent, false);
+ int wifiIndex = cursor.getColumnIndex(PreviewColumns.STATUSBAR_WIFI_ICON);
+ int signalIndex = cursor.getColumnIndex(PreviewColumns.STATUSBAR_SIGNAL_ICON);
+ int bluetoothIndex = cursor.getColumnIndex(PreviewColumns.STATUSBAR_BLUETOOTH_ICON);
+ int batteryIndex = cursor.getColumnIndex(Utils.getBatteryIndex(mBatteryStyle));
+ int backgroundIndex = cursor.getColumnIndex(PreviewColumns.STATUSBAR_BACKGROUND);
+ int pkgNameIndex = cursor.getColumnIndex(ThemesContract.ThemesColumns.PKG_NAME);
+
+ ((ImageView) v.findViewById(R.id.slot1)).setImageBitmap(
+ Utils.loadBitmapBlob(cursor, wifiIndex));
+ ((ImageView) v.findViewById(R.id.slot2)).setImageBitmap(
+ Utils.loadBitmapBlob(cursor, signalIndex));
+ ((ImageView) v.findViewById(R.id.slot3)).setImageBitmap(
+ Utils.loadBitmapBlob(cursor, bluetoothIndex));
+ ((ImageView) v.findViewById(R.id.slot4)).setImageBitmap(
+ Utils.loadBitmapBlob(cursor, batteryIndex));
+ setTitle(((TextView) v.findViewById(R.id.title)), cursor);
+ v.findViewById(R.id.container).setBackground(
+ new BitmapDrawable(Utils.loadBitmapBlob(cursor, backgroundIndex)));
+ v.setTag(R.id.tag_key_package_name, cursor.getString(pkgNameIndex));
+ v.setOnClickListener(mItemClickListener);
+ return v;
+ }
+
+ private View newNavBarView(Cursor cursor, ViewGroup parent, int position) {
+ cursor.moveToPosition(position);
+ View v = mInflater.inflate(R.layout.navigation_bar_component_selection_item, parent,
+ false);
+ int backIndex = cursor.getColumnIndex(PreviewColumns.NAVBAR_BACK_BUTTON);
+ int backgroundIndex = cursor.getColumnIndex(PreviewColumns.STATUSBAR_BACKGROUND);
+ int pkgNameIndex = cursor.getColumnIndex(ThemesContract.ThemesColumns.PKG_NAME);
+
+ ((ImageView) v.findViewById(R.id.back)).setImageBitmap(
+ Utils.loadBitmapBlob(cursor, backIndex));
+ setTitle(((TextView) v.findViewById(R.id.title)), cursor);
+ v.findViewById(R.id.container).setBackground(
+ new BitmapDrawable(Utils.loadBitmapBlob(cursor, backgroundIndex)));
+ v.setTag(R.id.tag_key_package_name, cursor.getString(pkgNameIndex));
+ v.setOnClickListener(mItemClickListener);
+ return v;
+ }
+
+ private View newFontView(Cursor cursor, ViewGroup parent, int position) {
+ cursor.moveToPosition(position);
+ View v = mInflater.inflate(R.layout.font_component_selection_item, parent, false);
+ int pkgNameIndex = cursor.getColumnIndex(ThemesContract.ThemesColumns.PKG_NAME);
+
+ TextView preview = (TextView) v.findViewById(R.id.text_preview);
+ String pkgName = cursor.getString(pkgNameIndex);
+
+ ThemedTypefaceHelper helper = mTypefaceCache.getHelperForTheme(mContext, pkgName);
+ Typeface typefaceNormal = helper.getTypeface(Typeface.NORMAL);
+ preview.setTypeface(typefaceNormal);
+
+ setTitle(((TextView) v.findViewById(R.id.title)), cursor);
+ v.setTag(R.id.tag_key_package_name, cursor.getString(pkgNameIndex));
+ v.setOnClickListener(mItemClickListener);
+ return v;
+ }
+
+ private View newIconView(Cursor cursor, ViewGroup parent, int position) {
+ cursor.moveToPosition(position);
+ View v = mInflater.inflate(R.layout.icon_component_selection_item, parent,
+ false);
+ int iconIndex = cursor.getColumnIndex(PreviewColumns.ICON_PREVIEW_1);
+ int pkgNameIndex = cursor.getColumnIndex(ThemesContract.ThemesColumns.PKG_NAME);
+
+ ((ImageView) v.findViewById(R.id.icon)).setImageBitmap(
+ Utils.loadBitmapBlob(cursor, iconIndex));
+ setTitle(((TextView) v.findViewById(R.id.title)), cursor);
+ v.setTag(R.id.tag_key_package_name, cursor.getString(pkgNameIndex));
+ v.setOnClickListener(mItemClickListener);
+ return v;
+ }
+
+ private View newStyleView(Cursor cursor, ViewGroup parent, int position) {
+ cursor.moveToPosition(position);
+ View v = mInflater.inflate(R.layout.icon_component_selection_item, parent,
+ false);
+ int styleIndex = cursor.getColumnIndex(PreviewColumns.STYLE_THUMBNAIL);
+ int pkgNameIndex = cursor.getColumnIndex(ThemesContract.ThemesColumns.PKG_NAME);
+
+ ((ImageView) v.findViewById(R.id.icon)).setImageBitmap(
+ Utils.loadBitmapBlob(cursor, styleIndex));
+ setTitle(((TextView) v.findViewById(R.id.title)), cursor);
+ v.setTag(R.id.tag_key_package_name, cursor.getString(pkgNameIndex));
+ v.setOnClickListener(mItemClickListener);
+ return v;
+ }
+
+ private View newWallpapersView(Cursor cursor, ViewGroup parent, int position,
+ int wallpaperIndex, boolean isLiveLockScreen, int numExtraComponents) {
+ View v = mInflater.inflate(R.layout.wallpaper_component_selection_item, parent,
+ false);
+ ImageView iv = (ImageView) v.findViewById(R.id.icon);
+ if (position == 0) {
+ iv.setImageResource(R.drawable.img_wallpaper_none);
+ v.setTag(R.id.tag_key_package_name, "");
+ ((TextView) v.findViewById(R.id.title)).setText(R.string.wallpaper_none_title);
+ } else if (position == 1) {
+ iv.setImageResource(R.drawable.img_wallpaper_external);
+ v.setTag(R.id.tag_key_package_name, EXTERNAL_WALLPAPER);
+ ((TextView) v.findViewById(R.id.title))
+ .setText(R.string.wallpaper_external_title);
+ } else if (numExtraComponents == EXTRA_LOCK_SCREEN_WALLPAPER_COMPONENTS && position == 2) {
+ // TODO: update drawable once the asset is provided by design
+ iv.setImageResource(android.R.drawable.ic_lock_lock);
+ v.setTag(R.id.tag_key_package_name, MOD_LOCK);
+ ((TextView) v.findViewById(R.id.title))
+ .setText(R.string.mod_lock_title);
+ } else {
+ cursor.moveToPosition(position - numExtraComponents);
+ int pkgNameIndex = cursor.getColumnIndex(ThemesContract.ThemesColumns.PKG_NAME);
+ int cmpntIdIndex = cursor.getColumnIndex(PreviewColumns.COMPONENT_ID);
+ long cmpntId = (cmpntIdIndex >= 0) ?
+ cursor.getLong(cmpntIdIndex) : DEFAULT_COMPONENT_ID;
+ iv.setImageBitmap(
+ Utils.loadBitmapBlob(cursor, wallpaperIndex));
+ setTitle(((TextView) v.findViewById(R.id.title)), cursor);
+ v.setTag(R.id.tag_key_package_name, cursor.getString(pkgNameIndex));
+ v.setTag(R.id.tag_key_component_id, cmpntId);
+ v.setTag(R.id.tag_key_live_lock_screen, isLiveLockScreen);
+ v.findViewById(R.id.live_lock_screen_badge)
+ .setVisibility(isLiveLockScreen ? View.VISIBLE : View.GONE);
+ }
+ v.setOnClickListener(mItemClickListener);
+ return v;
+ }
+
+ private View newBootanimationView(Cursor cursor, ViewGroup parent, int position) {
+ cursor.moveToPosition(position);
+ View v = mInflater.inflate(R.layout.bootani_component_selection_item, parent,
+ false);
+ int wallpaperIndex = cursor.getColumnIndex(PreviewColumns.BOOTANIMATION_THUMBNAIL);
+ int pkgNameIndex = cursor.getColumnIndex(ThemesContract.ThemesColumns.PKG_NAME);
+
+ ((ImageView) v.findViewById(R.id.preview)).setImageBitmap(
+ Utils.loadBitmapBlob(cursor, wallpaperIndex));
+ setTitle(((TextView) v.findViewById(R.id.title)), cursor);
+ v.setTag(R.id.tag_key_package_name, cursor.getString(pkgNameIndex));
+ v.setOnClickListener(mItemClickListener);
+ return v;
+ }
+
+ private View newSoundView(Cursor cursor, ViewGroup parent, int position,
+ final String component) {
+ LinearLayout container = (LinearLayout) mInflater.inflate(
+ R.layout.component_selection_sounds_pager_item, parent, false);
+ container.setWeightSum(mItemsPerPage);
+ for (int i = 0; i < mItemsPerPage; i++) {
+ int index = position * mItemsPerPage + i;
+ if (cursor.getCount() <= index) continue;
+ cursor.moveToPosition(index);
+ View v = mInflater.inflate(R.layout.sound_component_selection_item, parent,
+ false);
+ final int pkgNameIndex = cursor.getColumnIndex(ThemesContract.ThemesColumns.PKG_NAME);
+
+ setTitle(((TextView) v.findViewById(R.id.title)), cursor);
+ v.setTag(R.id.tag_key_package_name, cursor.getString(pkgNameIndex));
+ v.setOnClickListener(mItemClickListener);
+ container.addView(v, mSoundItemParams);
+ final View playButton = v.findViewById(R.id.play_button);
+ playButton.setTag(cursor.getString(pkgNameIndex));
+ playButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ int type;
+ String pkgName = (String) v.getTag();
+ if (component.equals(MODIFIES_RINGTONES)) {
+ type = RingtoneManager.TYPE_RINGTONE;
+ } else if (component.equals(MODIFIES_NOTIFICATIONS)) {
+ type = RingtoneManager.TYPE_NOTIFICATION;
+ } else {
+ type = RingtoneManager.TYPE_ALARM;
+ }
+ boolean shouldStop = playButton == mCurrentPlayPause;
+ try {
+ if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
+ mMediaPlayer.stop();
+ if (mCurrentPlayPause != null) {
+ mCurrentPlayPause.setImageResource(
+ R.drawable.media_sound_selector_preview);
+ }
+ mCurrentPlayPause = null;
+ }
+ if (mCurrentPlayPause != playButton && !shouldStop) {
+ AudioUtils.loadThemeAudible(mContext, type, pkgName,
+ mMediaPlayer);
+ mMediaPlayer.start();
+ mCurrentPlayPause = (ImageView) playButton;
+ mCurrentPlayPause.setImageResource(
+ R.drawable.media_sound_selector_stop);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Unable to play preview sound", e);
+ }
+ }
+ });
+ }
+
+ return container;
+ }
+
+ private class LoadItemsTask extends AsyncTask<Object, Void, Void> {
+
+ @Override
+ protected Void doInBackground(Object... params) {
+ Cursor c = (Cursor) params[0];
+ int count = (Integer) params[1];
+ for (int i = 0; i < count && !isCancelled(); i++) {
+ final View v = newView(c, i, mContent);
+ mContent.post(new Runnable() {
+ @Override
+ public void run() {
+ mContent.addView(v, mItemParams);
+ }
+ });
+ }
+
+ if (c instanceof MatrixCursor) {
+ c.close();
+ }
+
+ // destroy the loader now that we are done with it
+ ComponentSelector.this.post(new Runnable() {
+ @Override
+ public void run() {
+ ((FragmentActivity)mContext).getSupportLoaderManager().destroyLoader(
+ getLoaderIdFromComponent(mComponentType));
+ }
+ });
+ return null;
+ }
+ }
+
+ private void setTitle(TextView titleView, Cursor cursor) {
+ String pkgName = cursor.getString(cursor.getColumnIndex(ThemesColumns.PKG_NAME));
+ int cmpntIdIndex = cursor.getColumnIndex(PreviewColumns.COMPONENT_ID);
+ long cmpntId = DEFAULT_COMPONENT_ID;
+ if (cmpntIdIndex >= 0) {
+ cmpntId = cursor.getLong(cmpntIdIndex);
+ }
+ if (Utils.getDefaultThemePackageName(mContext).equals(pkgName)) {
+ titleView.setText(mContext.getString(R.string.default_tag_text));
+ titleView.setTypeface(titleView.getTypeface(), Typeface.BOLD);
+ } else {
+ titleView.setText(cursor.getString(cursor.getColumnIndex(ThemesColumns.TITLE)));
+ }
+ boolean highlightTitle = false;
+ if (mComponentType.equals(MODIFIES_LOCKSCREEN)) {
+ Map<String, String> selectedComponents = ((ChooserActivity)mContext)
+ .getSelectedComponentsMap();
+ int isLLS = cursor.getInt(cursor.getColumnIndex(MODIFIES_LIVE_LOCK_SCREEN));
+ if ((TextUtils.equals(selectedComponents.get(MODIFIES_LOCKSCREEN), pkgName)
+ && isLLS == 0) || (TextUtils.equals(
+ selectedComponents.get(MODIFIES_LIVE_LOCK_SCREEN), pkgName) && isLLS == 1)) {
+ highlightTitle = true;
+ }
+ } else if (pkgName.equals(mSelectedComponentPkgName) && cmpntId == mSelectedComponentId) {
+ highlightTitle = true;
+ }
+ if (highlightTitle) {
+ titleView.setTextColor(getResources().getColor(
+ R.color.component_selection_current_text_color));
+ }
+ }
+
+ private OnClickListener mItemClickListener = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ long cmpntId = DEFAULT_COMPONENT_ID;
+ String pkgName = (String) v.getTag(R.id.tag_key_package_name);
+ Long cmpntIdTag = (Long) v.getTag(R.id.tag_key_component_id);
+ if (cmpntIdTag != null) {
+ cmpntId = cmpntIdTag;
+ }
+ Boolean isLiveLock = (Boolean) v.getTag(R.id.tag_key_live_lock_screen);
+ boolean isSamePkgButDifferentLockScreen = false;
+ Bundle params = null;
+ if (isLiveLock != null) {
+ params = new Bundle();
+ params.putBoolean(IS_LIVE_LOCK_SCREEN_VIEW, isLiveLock);
+
+ if (pkgName.equals(mSelectedComponentPkgName) && v != mPrevLockScreenView) {
+ isSamePkgButDifferentLockScreen = true;
+ }
+ mPrevLockScreenView = v;
+ }
+ if (DEBUG_SELECTOR) Toast.makeText(mContext, pkgName, Toast.LENGTH_SHORT).show();
+ if (mListener != null && (isSamePkgButDifferentLockScreen ||
+ !pkgName.equals(mSelectedComponentPkgName) ||
+ pkgName.equals(EXTERNAL_WALLPAPER) || cmpntId != mSelectedComponentId)) {
+ mSelectedComponentPkgName = pkgName;
+ mSelectedComponentId = cmpntId;
+ mListener.onItemClicked(pkgName, cmpntId, params);
+ final int count = mContent.getChildCount();
+ final Resources res = getResources();
+ for (int i = 0; i < count; i++) {
+ final View child = mContent.getChildAt(i);
+ final TextView tv = (TextView) child.findViewById(R.id.title);
+ if (tv != null) {
+ if (child == v) {
+ tv.setTextColor(
+ res.getColor(R.color.component_selection_current_text_color));
+ } else {
+ tv.setTextColor(res.getColor(android.R.color.white));
+ }
+ }
+ }
+ }
+ }
+ };
+
+ private class ThemesObserver extends ContentObserver {
+ public ThemesObserver() {
+ super(null);
+ }
+
+ public void register() {
+ mContext.getContentResolver().registerContentObserver(
+ ThemesColumns.CONTENT_URI, false, this);
+ }
+
+ public void unregister() {
+ mContext.getContentResolver().unregisterContentObserver(this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ // reload items by calling setComponentType()
+ if (mComponentType != null) {
+ final String componentType = mComponentType;
+ mComponentType = null;
+ mContent.post(new Runnable() {
+ @Override
+ public void run() {
+ setComponentType(componentType, mSelectedComponentPkgName);
+ }
+ });
+ }
+ }
+ }
+
+ public interface OnItemClickedListener {
+ public void onItemClicked(String pkgName, long componentId, Bundle params);
+ }
+
+ public interface OnOpenCloseListener {
+ public void onSelectorOpened();
+ public void onSelectorClosed();
+ public void onSelectorClosing();
+ }
+} \ No newline at end of file