diff options
author | Clark Scheff <clark@cyngn.com> | 2014-07-29 12:15:56 -0700 |
---|---|---|
committer | Clark Scheff <clark@cyngn.com> | 2014-07-29 13:36:38 -0700 |
commit | 89df9342c934e750c11d1402f4b5c51b34defdec (patch) | |
tree | a132efce032474022c0bac3772e96268e5a089e7 /src/org/cyanogenmod/theme | |
parent | e71e42f7304f5e6ba563a48de4ce1e70c94776ef (diff) | |
download | packages_apps_ThemeChooser-89df9342c934e750c11d1402f4b5c51b34defdec.tar.gz packages_apps_ThemeChooser-89df9342c934e750c11d1402f4b5c51b34defdec.tar.bz2 packages_apps_ThemeChooser-89df9342c934e750c11d1402f4b5c51b34defdec.zip |
Remove v1 code and resources and refactor v2 chooser.
Change-Id: Ic617365b3d26944e11c592b1508b4170ddb2871e
Diffstat (limited to 'src/org/cyanogenmod/theme')
30 files changed, 0 insertions, 8174 deletions
diff --git a/src/org/cyanogenmod/theme/chooser/AppReceiver.java b/src/org/cyanogenmod/theme/chooser/AppReceiver.java deleted file mode 100644 index f31fdbe..0000000 --- a/src/org/cyanogenmod/theme/chooser/AppReceiver.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2014 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.chooser; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager.NameNotFoundException; -import android.net.Uri; -import org.cyanogenmod.theme.util.NotificationHelper; - -public class AppReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - Uri uri = intent.getData(); - String pkgName = uri != null ? uri.getSchemeSpecificPart() : null; - String action = intent.getAction(); - boolean isReplacing = intent.getExtras().getBoolean(Intent.EXTRA_REPLACING, false); - - if (Intent.ACTION_PACKAGE_ADDED.equals(action) && !isReplacing) { - try { - if (isTheme(context, pkgName)) { - NotificationHelper.postThemeInstalledNotification(context, pkgName); - } - } catch (NameNotFoundException e) { - } - } else if (Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(action)) { - NotificationHelper.cancelNotificationForPackage(context, pkgName); - } - } - - private boolean isTheme(Context context, String pkgName) throws NameNotFoundException { - PackageInfo pi = context.getPackageManager().getPackageInfo(pkgName, 0); - if (pi == null) return false; - - if ((pi.themeInfos != null && pi.themeInfos.length > 0) || - (pi.legacyThemeInfos != null && pi.legacyThemeInfos.length > 0)) { - return true; - } - - return false; - } -} diff --git a/src/org/cyanogenmod/theme/chooser/AudiblePreviewFragment.java b/src/org/cyanogenmod/theme/chooser/AudiblePreviewFragment.java deleted file mode 100644 index f7acad3..0000000 --- a/src/org/cyanogenmod/theme/chooser/AudiblePreviewFragment.java +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (C) 2014 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.chooser; - -import android.content.Context; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.ThemeUtils; -import android.content.res.AssetFileDescriptor; -import android.content.res.AssetManager; -import android.content.res.ThemeConfig; -import android.media.MediaPlayer; -import android.media.RingtoneManager; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.util.SparseArray; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import java.io.File; -import java.io.IOException; - - -public class AudiblePreviewFragment extends Fragment { - private static final String PKG_EXTRA = "pkg_extra"; - - private static final LinearLayout.LayoutParams ITEM_LAYOUT_PARAMS = - new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT); - - private String mPkgName; - private LinearLayout mContent; - private SparseArray<MediaPlayer> mMediaPlayers; - - static AudiblePreviewFragment newInstance(String pkgName) { - final AudiblePreviewFragment f = new AudiblePreviewFragment(); - final Bundle args = new Bundle(); - args.putString(PKG_EXTRA, pkgName); - f.setArguments(args); - return f; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mPkgName = getArguments().getString(PKG_EXTRA); - mMediaPlayers = new SparseArray<MediaPlayer>(3); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.audibles_preview, container, false); - mContent = (LinearLayout) v.findViewById(R.id.audibles_layout); - return v; - } - - @Override - public void onResume() { - super.onResume(); - loadAudibles(); - } - - @Override - public void onPause() { - super.onPause(); - freeMediaPlayers(); - } - - @Override - public void setUserVisibleHint(boolean isVisibleToUser) { - super.setUserVisibleHint(isVisibleToUser); - if (!isVisibleToUser) { - stopMediaPlayers(); - } - } - - private void freeMediaPlayers() { - final int N = mMediaPlayers.size(); - for (int i = 0; i < N; i++) { - MediaPlayer mp = mMediaPlayers.get(mMediaPlayers.keyAt(i)); - if (mp != null) { - mp.stop(); - mp.release(); - } - } - mMediaPlayers.clear(); - } - - private View.OnClickListener mPlayPauseClickListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - MediaPlayer mp = (MediaPlayer) v.getTag(); - if (mp != null) { - if (mp.isPlaying()) { - ((ImageView) v).setImageResource(android.R.drawable.ic_media_play); - mp.pause(); - mp.seekTo(0); - } else { - stopMediaPlayers(); - ((ImageView) v).setImageResource(android.R.drawable.ic_media_pause); - mp.start(); - } - } - } - }; - - private MediaPlayer.OnCompletionListener mPlayCompletionListener - = new MediaPlayer.OnCompletionListener() { - @Override - public void onCompletion(MediaPlayer mp) { - final int numChildern = mContent.getChildCount(); - for (int i = 0; i < numChildern; i++) { - ((ImageView) mContent.getChildAt(i).findViewById(R.id.btn_play_pause)) - .setImageResource(android.R.drawable.ic_media_play); - } - } - }; - - private void stopMediaPlayers() { - if (mContent == null) return; - final int numChildern = mContent.getChildCount(); - for (int i = 0; i < numChildern; i++) { - ImageView iv = (ImageView) mContent.getChildAt(i).findViewById(R.id.btn_play_pause); - if (iv != null) { - iv.setImageResource(android.R.drawable.ic_media_play); - MediaPlayer mp = (MediaPlayer) iv.getTag(); - if (mp != null && mp.isPlaying()) { - mp.pause(); - mp.seekTo(0); - } - } - } - } - - private void loadAudibles() { - mContent.removeAllViews(); - if (ThemeConfig.HOLO_DEFAULT.equals(mPkgName)) { - loadSystemAudible(RingtoneManager.TYPE_ALARM); - loadSystemAudible(RingtoneManager.TYPE_NOTIFICATION); - loadSystemAudible(RingtoneManager.TYPE_RINGTONE); - } else { - try { - final Context themeCtx = getActivity().createPackageContext(mPkgName, 0); - PackageInfo pi = getActivity().getPackageManager().getPackageInfo(mPkgName, 0); - loadThemeAudible(themeCtx, RingtoneManager.TYPE_ALARM, pi); - loadThemeAudible(themeCtx, RingtoneManager.TYPE_NOTIFICATION, pi); - loadThemeAudible(themeCtx, RingtoneManager.TYPE_RINGTONE, pi); - } catch (PackageManager.NameNotFoundException e) { - return; - } - } - } - - private void loadThemeAudible(Context themeCtx, int type, PackageInfo pi) { - if (pi.isLegacyThemeApk) { - loadLegacyThemeAudible(themeCtx, type, pi); - return; - } - AssetManager assetManager = themeCtx.getAssets(); - String assetPath; - switch (type) { - case RingtoneManager.TYPE_ALARM: - assetPath = "alarms"; - break; - case RingtoneManager.TYPE_NOTIFICATION: - assetPath = "notifications"; - break; - case RingtoneManager.TYPE_RINGTONE: - assetPath = "ringtones"; - break; - default: - assetPath = null; - break; - } - if (assetPath != null) { - try { - String[] assetList = assetManager.list(assetPath); - if (assetList != null && assetList.length > 0) { - AssetFileDescriptor afd = assetManager.openFd(assetPath - + File.separator + assetList[0]); - MediaPlayer mp = initAudibleMediaPlayer(afd, type); - if (mp != null) { - addAudibleToLayout(type, mp); - } - } - } catch (IOException e) { - mMediaPlayers.put(type, null); - } - } - } - - private void loadLegacyThemeAudible(Context themeCtx, int type, PackageInfo pi) { - if (pi.legacyThemeInfos == null || pi.legacyThemeInfos.length == 0) - return; - AssetManager assetManager = themeCtx.getAssets(); - String assetPath; - switch (type) { - case RingtoneManager.TYPE_NOTIFICATION: - assetPath = pi.legacyThemeInfos[0].notificationFileName; - break; - case RingtoneManager.TYPE_RINGTONE: - assetPath = pi.legacyThemeInfos[0].ringtoneFileName; - break; - default: - assetPath = null; - break; - } - if (assetPath != null) { - try { - AssetFileDescriptor afd = assetManager.openFd(assetPath); - MediaPlayer mp = initAudibleMediaPlayer(afd, type); - if (mp != null) { - addAudibleToLayout(type, mp); - } - } catch (IOException e) { - mMediaPlayers.put(type, null); - } - } - } - - private void loadSystemAudible(int type) { - final String audiblePath = ThemeUtils.getDefaultAudiblePath(type); - if (audiblePath != null && (new File(audiblePath)).exists()) { - try { - MediaPlayer mp = initAudibleMediaPlayer(audiblePath, type); - addAudibleToLayout(type, mp); - } catch (IOException e) { - mMediaPlayers.put(type, null); - } - } - } - - private MediaPlayer initAudibleMediaPlayer(String audiblePath, int type) throws IOException { - MediaPlayer mp = mMediaPlayers.get(type); - if (mp == null) { - mp = new MediaPlayer(); - mMediaPlayers.put(type, mp); - } else { - mp.reset(); - } - mp.setDataSource(audiblePath); - mp.prepare(); - mp.setOnCompletionListener(mPlayCompletionListener); - return mp; - } - - private MediaPlayer initAudibleMediaPlayer(AssetFileDescriptor afd, int type) throws IOException { - MediaPlayer mp = mMediaPlayers.get(type); - if (mp == null) { - mp = new MediaPlayer(); - mMediaPlayers.put(type, mp); - } else { - mp.reset(); - } - mp.setDataSource(afd.getFileDescriptor(), - afd.getStartOffset(), afd.getLength()); - mp.prepare(); - mp.setOnCompletionListener(mPlayCompletionListener); - return mp; - } - - private void addAudibleToLayout(int type, MediaPlayer mp) { - View view = View.inflate(getActivity(), R.layout.audible_preview_item, null); - TextView tv = (TextView) view.findViewById(R.id.audible_name); - switch (type) { - case RingtoneManager.TYPE_ALARM: - tv.setText(R.string.alarm_label); - break; - case RingtoneManager.TYPE_NOTIFICATION: - tv.setText(R.string.notification_label); - break; - case RingtoneManager.TYPE_RINGTONE: - tv.setText(R.string.ringtone_label); - break; - } - ImageView iv = (ImageView) view.findViewById(R.id.btn_play_pause); - iv.setTag(mp); - iv.setOnClickListener(mPlayPauseClickListener); - mContent.addView(view, ITEM_LAYOUT_PARAMS); - } -} diff --git a/src/org/cyanogenmod/theme/chooser/BootAniPreviewFragment.java b/src/org/cyanogenmod/theme/chooser/BootAniPreviewFragment.java deleted file mode 100644 index f3c04e4..0000000 --- a/src/org/cyanogenmod/theme/chooser/BootAniPreviewFragment.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2014 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.chooser; - -import android.content.Context; -import android.content.res.AssetManager; -import android.content.res.ThemeConfig; -import android.os.AsyncTask; -import android.os.Bundle; -import android.os.FileUtils; -import android.support.v4.app.Fragment; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ProgressBar; -import android.widget.TextView; - -import org.cyanogenmod.theme.util.BootAnimationHelper; -import org.cyanogenmod.theme.widget.BootAniImageView; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.zip.ZipFile; - -public class BootAniPreviewFragment extends Fragment { - private static final String TAG = "ThemeChooser"; - private static final String PKG_EXTRA = "pkg_extra"; - private static final String CACHED_SUFFIX = "_bootanimation.zip"; - - private String mPkgName; - private BootAniImageView mPreview; - private ProgressBar mLoadingProgress; - private TextView mNoPreviewTextView; - private boolean mPreviewLoaded = false; - private boolean mIsVisibileToUser = false; - private boolean mAnimationStarted = false; - - public static BootAniPreviewFragment newInstance(String pkgName) { - BootAniPreviewFragment fragment = new BootAniPreviewFragment(); - Bundle args = new Bundle(); - args.putString(PKG_EXTRA, pkgName); - fragment.setArguments(args); - return fragment; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mPkgName = getArguments().getString(PKG_EXTRA); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_boot_animation_preview, container, false); - mPreview = (BootAniImageView) view.findViewById(R.id.animated_preview); - mLoadingProgress = (ProgressBar) view.findViewById(R.id.loading_progress); - mNoPreviewTextView = (TextView) view.findViewById(R.id.no_preview); - return view; - } - - @Override - public void onPause() { - super.onPause(); - mPreviewLoaded = false; - } - - @Override - public void onResume() { - super.onResume(); - new AnimationLoader(getActivity(), mPkgName).execute(); - } - - @Override - public void setUserVisibleHint(boolean isVisibleToUser) { - super.setUserVisibleHint(isVisibleToUser); - mIsVisibileToUser = isVisibleToUser; - if (isVisibleToUser) { - if (mPreviewLoaded && !mAnimationStarted) { - startAnimation(); - } - } - } - - private void startAnimation() { - if (mIsVisibileToUser) { - mPreview.start(); - mAnimationStarted = true; - } - } - - class AnimationLoader extends AsyncTask<Void, Void, Boolean> { - Context mContext; - String mPkgName; - - public AnimationLoader(Context context, String pkgName) { - mContext = context; - mPkgName = pkgName; - } - - @Override - protected void onPreExecute() { - super.onPreExecute(); - mPreview.setImageDrawable(null); - mLoadingProgress.setVisibility(View.VISIBLE); - mNoPreviewTextView.setVisibility(View.INVISIBLE); - } - - @Override - protected Boolean doInBackground(Void... params) { - if (mContext == null) { - return Boolean.FALSE; - } - ZipFile zip = null; - if (ThemeConfig.HOLO_DEFAULT.equals(mPkgName)) { - try { - zip = new ZipFile(new File(BootAnimationHelper.SYSTEM_BOOT_ANI_PATH)); - } catch (Exception e) { - Log.w(TAG, "Unable to load boot animation", e); - return Boolean.FALSE; - } - } else { - // check if the bootanimation is cached - File f = new File(mContext.getCacheDir(), mPkgName + CACHED_SUFFIX); - if (!f.exists()) { - // go easy on cache storage and clear out any previous boot animations - clearBootAnimationCache(); - try { - Context themeContext = mContext.createPackageContext(mPkgName, 0); - AssetManager am = themeContext.getAssets(); - InputStream is = am.open("bootanimation/bootanimation.zip"); - FileUtils.copyToFile(is, f); - is.close(); - } catch (Exception e) { - Log.w(TAG, "Unable to load boot animation", e); - return Boolean.FALSE; - } - } - try { - zip = new ZipFile(f); - } catch (IOException e) { - Log.w(TAG, "Unable to load boot animation", e); - return Boolean.FALSE; - } - } - if (zip != null) { - mPreview.setBootAnimation(zip); - } else { - return Boolean.FALSE; - } - return Boolean.TRUE; - } - - @Override - protected void onPostExecute(Boolean isSuccess) { - super.onPostExecute(isSuccess); - mLoadingProgress.setVisibility(View.INVISIBLE); - if (Boolean.TRUE.equals(isSuccess)) { - mPreviewLoaded = true; - startAnimation(); - } else { - mNoPreviewTextView.setVisibility(View.VISIBLE); - Log.e(TAG, "Unable to load boot animation for preview."); - } - } - } - - private void clearBootAnimationCache() { - File cache = getActivity().getCacheDir(); - if (cache.exists()) { - for(File f : cache.listFiles()) { - // volley stores stuff in cache so don't delete the volley directory - if(!f.isDirectory() && f.getName().endsWith(CACHED_SUFFIX)) f.delete(); - } - } - } -}
\ No newline at end of file diff --git a/src/org/cyanogenmod/theme/chooser/ChooserActivity.java b/src/org/cyanogenmod/theme/chooser/ChooserActivity.java deleted file mode 100644 index 115ea9e..0000000 --- a/src/org/cyanogenmod/theme/chooser/ChooserActivity.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2014 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.chooser; - -import java.util.ArrayList; -import java.util.Arrays; - -import android.app.ActionBar; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentActivity; -import android.view.MenuItem; - -public class ChooserActivity extends FragmentActivity { - public static final String TAG = ChooserActivity.class.getName(); - public static final String EXTRA_COMPONENT_FILTER = "component_filter"; - public static final String EXTRA_PKGNAME = "pkgName"; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - NotificationHijackingService.ensureEnabled(this); - - ActionBar mActionBar = getActionBar(); - if (mActionBar != null) { - mActionBar.setDisplayHomeAsUpEnabled(true); - } - - if (savedInstanceState == null) { - handleIntent(getIntent()); - } - } - - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - handleIntent(intent); - } - - private void handleIntent(final Intent intent) { - //Determine if there we need to filter by component (ex icon sets only) - Bundle extras = intent.getExtras(); - String filter = (extras == null) ? null : extras.getString(EXTRA_COMPONENT_FILTER); - - // If activity started by wallpaper chooser then filter on wallpapers - if (Intent.ACTION_SET_WALLPAPER.equals(intent.getAction())) { - filter = "mods_homescreen"; - } - - // Support filters passed in as csv. Since XML prefs do not support - // passing extras in as arrays. - ArrayList<String> filtersList = new ArrayList<String>(); - if (filter != null) { - String[] filters = filter.split(","); - filtersList.addAll(Arrays.asList(filters)); - } - - Fragment fragment = null; - if (Intent.ACTION_MAIN.equals(intent.getAction()) && intent.hasExtra(EXTRA_PKGNAME)) { - String pkgName = intent.getStringExtra(EXTRA_PKGNAME); - fragment = ChooserDetailFragment.newInstance(pkgName, filtersList); - // Handle case where Theme Store or some other app wishes to open - // a detailed theme view for a given package - try { - final PackageManager pm = getPackageManager(); - if (pm.getPackageInfo(pkgName, 0) == null) { - fragment = ChooserBrowseFragment.newInstance(filtersList); - } - } catch (PackageManager.NameNotFoundException e) { - fragment = ChooserBrowseFragment.newInstance(filtersList); - } - } else { - fragment = ChooserBrowseFragment.newInstance(filtersList); - } - getSupportFragmentManager().beginTransaction().replace(R.id.content, fragment, - "ChooserBrowseFragment").commit(); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - return false; - } -} diff --git a/src/org/cyanogenmod/theme/chooser/ChooserBrowseFragment.java b/src/org/cyanogenmod/theme/chooser/ChooserBrowseFragment.java deleted file mode 100644 index 4178e54..0000000 --- a/src/org/cyanogenmod/theme/chooser/ChooserBrowseFragment.java +++ /dev/null @@ -1,585 +0,0 @@ -/* - * Copyright (C) 2014 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.chooser; - -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.ActivityNotFoundException; -import android.graphics.Color; -import android.view.Gravity; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.res.AssetManager; -import android.content.res.ThemeConfig; -import android.content.res.Resources; -import android.database.Cursor; -import android.graphics.Bitmap; -import android.graphics.Point; -import android.graphics.Typeface; -import android.graphics.drawable.Drawable; -import android.os.AsyncTask; -import android.os.Bundle; -import android.provider.Browser; -import android.provider.ThemesContract.ThemesColumns; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentTransaction; -import android.support.v4.app.LoaderManager; -import android.support.v4.content.CursorLoader; -import android.support.v4.content.Loader; -import android.support.v4.widget.CursorAdapter; -import android.util.Log; -import android.util.TypedValue; -import android.view.Display; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewGroup.LayoutParams; -import android.webkit.URLUtil; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ListView; -import android.widget.ProgressBar; -import android.widget.TextView; - -import org.cyanogenmod.theme.chooser.WallpaperAndIconPreviewFragment.IconInfo; -import org.cyanogenmod.theme.util.BootAnimationHelper; -import org.cyanogenmod.theme.util.IconPreviewHelper; -import org.cyanogenmod.theme.util.ThemedTypefaceHelper; -import org.cyanogenmod.theme.util.Utils; - -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class ChooserBrowseFragment extends Fragment - implements LoaderManager.LoaderCallbacks<Cursor> { - public static final String TAG = ChooserBrowseFragment.class.getCanonicalName(); - public static final String DEFAULT = ThemeConfig.HOLO_DEFAULT; - - private static final String THEME_STORE_PACKAGE_NAME = "com.cyngn.theme.store"; - private static final String GET_THEMES_URL = - "http://wiki.cyanogenmod.org/w/Get_Themes?action=render"; - private static final String THEME_STORE_ACTIVITY = "com.cyngn.theme.store.StoreActivity"; - - public ListView mListView; - public LocalPagerAdapter mAdapter; - public ArrayList<String> mComponentFilters; - - private Point mMaxImageSize = new Point(); //Size of preview image in listview - - public static ChooserBrowseFragment newInstance(ArrayList<String> componentFilters) { - ChooserBrowseFragment fragment = new ChooserBrowseFragment(); - Bundle args = new Bundle(); - args.putStringArrayList(ChooserActivity.EXTRA_COMPONENT_FILTER, componentFilters); - fragment.setArguments(args); - return fragment; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.fragment_chooser_browse, container, false); - ArrayList<String> filters = getArguments().getStringArrayList(ChooserActivity.EXTRA_COMPONENT_FILTER); - mComponentFilters = (filters != null) ? filters : new ArrayList<String>(0); - mListView = (ListView) v.findViewById(R.id.list); - mAdapter = new LocalPagerAdapter(getActivity(), null, mComponentFilters); - mListView.setAdapter(mAdapter); - mListView.setOnItemClickListener(new OnItemClickListener() { - @Override - public void onItemClick(AdapterView<?> parent, View view, int position, long id) { - String pkgName = (String) mAdapter.getItem(position); - ChooserDetailFragment fragment = ChooserDetailFragment.newInstance(pkgName, mComponentFilters); - FragmentTransaction transaction = getFragmentManager().beginTransaction(); - transaction.replace(R.id.content, fragment, ChooserDetailFragment.class.toString()); - transaction.addToBackStack(null); - transaction.commit(); - } - }); - getLoaderManager().initLoader(0, null, this); - - Display display = getActivity().getWindowManager().getDefaultDisplay(); - display.getSize(mMaxImageSize); - mMaxImageSize.y = (int) getActivity().getResources().getDimension(R.dimen.item_browse_height); - - return v; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - inflater.inflate(R.menu.chooser_menu, menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch(item.getItemId()) { - case R.id.get_more_themes: - if (isThemeStoreInstalled()) { - try { - launchThemeStore(); - } catch (ActivityNotFoundException e) { - launchGetThemesWebView(); - } - } else { - launchGetThemesWebView(); - } - return true; - } - - return false; - } - - private boolean isThemeStoreInstalled() { - PackageManager pm = getActivity().getPackageManager(); - try { - pm.getPackageInfo(THEME_STORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES); - return true; - } catch (NameNotFoundException e) { - return false; - } - } - - private void launchThemeStore() { - Intent intent = new Intent(); - intent.setComponent(new ComponentName(THEME_STORE_PACKAGE_NAME, - THEME_STORE_ACTIVITY)); - getActivity().startActivity(intent); - } - - private void launchGetThemesWebView() { - Context context = getActivity(); - if (context == null) return; - - final WebView webView = new WebView(context); - String html = createGetThemesHtml(context); - webView.loadData(html.toString(), "text/html", null); - - // Setup the dialog - AlertDialog.Builder alert = new AlertDialog.Builder(getActivity()); - alert.setView(webView); - Dialog dialog = alert.create(); - dialog.show(); - } - - private String createGetThemesHtml(Context context) { - // Setup the webview with progress bar - StringBuffer sb = new StringBuffer(); - sb.append("<html><body>"); - sb.append(getActivity().getString(R.string.get_more_description)); - sb.append("<ul>"); - - String[] entryNames = context.getResources().getStringArray(R.array.get_more_entry_names); - String[] entryUrls = context.getResources().getStringArray(R.array.get_more_entry_urls); - for(int i=0; i < entryNames.length; i++) { - String name = entryNames[i]; - String url = entryUrls[i]; - appendLink(sb, name, url); - } - - sb.append("</ul>"); - sb.append("</body></html>"); - return sb.toString(); - } - - private void appendLink(StringBuffer sb, String name, String url) { - Context context = getActivity(); - sb.append("<li>"); - sb.append("<a href=\""); - sb.append(url); - sb.append("\">"); - sb.append(name); - sb.append("</a>"); - sb.append("</li>"); - } - - @Override - public void onLoadFinished(Loader<Cursor> loader, Cursor data) { - // Swap the new cursor in. (The framework will take care of closing the - // old cursor once we return.) - mAdapter.swapCursor(data); - mAdapter.notifyDataSetChanged(); - } - - @Override - public void onLoaderReset(Loader<Cursor> loader) { - mAdapter.swapCursor(null); - mAdapter.notifyDataSetChanged(); - } - - @Override - public Loader<Cursor> onCreateLoader(int id, Bundle args) { - String selection; - String selectionArgs[] = null; - if (mComponentFilters.isEmpty()) { - selection = ThemesColumns.PRESENT_AS_THEME + "=?"; - selectionArgs = new String[] {"1"}; - } else { - StringBuffer sb = new StringBuffer(); - for(int i=0; i < mComponentFilters.size(); i++) { - sb.append(mComponentFilters.get(i)); - sb.append("=1"); - if (i != mComponentFilters.size()-1) { - sb.append(" OR "); - } - } - selection = sb.toString(); - } - - // sort in ascending order but make sure the "default" theme is always first - String sortOrder = "(" + ThemesColumns.IS_DEFAULT_THEME + "=1) DESC, " - + ThemesColumns.TITLE + " ASC"; - - return new CursorLoader(getActivity(), ThemesColumns.CONTENT_URI, null, selection, - selectionArgs, sortOrder); - } - - public class LocalPagerAdapter extends CursorAdapter { - List<String> mFilters; - Context mContext; - HashMap<String, ThemedTypefaceHelper> mTypefaceHelpers = - new HashMap<String, ThemedTypefaceHelper>(); - - public LocalPagerAdapter(Context context, Cursor c, List<String> filters) { - super(context, c, 0); - mFilters = filters; - mContext = context; - } - - @Override - public Object getItem(int position) { - mCursor.moveToPosition(position); - int pkgIdx = mCursor.getColumnIndex(ThemesColumns.PKG_NAME); - String pkgName = (String) mCursor.getString(pkgIdx); - return pkgName; - } - - @Override - public void bindView(View view, Context context, Cursor cursor) { - int titleIdx = mCursor.getColumnIndex(ThemesColumns.TITLE); - int authorIdx = mCursor.getColumnIndex(ThemesColumns.AUTHOR); - int hsIdx = mCursor.getColumnIndex(ThemesColumns.HOMESCREEN_URI); - int wpIdx = mCursor.getColumnIndex(ThemesColumns.WALLPAPER_URI); - int styleIdx = mCursor.getColumnIndex(ThemesColumns.STYLE_URI); - int pkgIdx = mCursor.getColumnIndex(ThemesColumns.PKG_NAME); - int legacyIndex = mCursor.getColumnIndex(ThemesColumns.IS_LEGACY_THEME); - int defaultIndex = mCursor.getColumnIndex(ThemesColumns.IS_DEFAULT_THEME); - - String pkgName = mCursor.getString(pkgIdx); - String title = DEFAULT.equals(pkgName) ? mContext.getString(R.string.holo) - : mCursor.getString(titleIdx); - String author = mCursor.getString(authorIdx); - String hsImagePath = DEFAULT.equals(pkgName) ? mCursor.getString(hsIdx) : - mCursor.getString(wpIdx); - String styleImagePath = mCursor.getString(styleIdx); - boolean isLegacyTheme = mCursor.getInt(legacyIndex) == 1; - boolean isDefaultTheme = mCursor.getInt(defaultIndex) == 1; - - ThemeItemHolder item = (ThemeItemHolder) view.getTag(); - item.title.setText(title + (isDefaultTheme ? " " - + getString(R.string.default_tag) : "")); - item.author.setText(author); - if (mFilters.isEmpty()) { - bindDefaultView(item, pkgName, hsImagePath, isLegacyTheme); - } else if (mFilters.contains(ThemesColumns.MODIFIES_BOOT_ANIM)) { - bindBootAnimView(item, context, pkgName); - } else if (mFilters.contains(ThemesColumns.MODIFIES_LAUNCHER)) { - bindWallpaperView(item, pkgName, hsImagePath, isLegacyTheme); - } else if (mFilters.contains(ThemesColumns.MODIFIES_FONTS)) { - bindFontView(view, context, pkgName); - } else if (mFilters.contains(ThemesColumns.MODIFIES_OVERLAYS)) { - bindOverlayView(item, pkgName, styleImagePath, isLegacyTheme); - } else if (mFilters.contains(ThemesColumns.MODIFIES_ICONS)) { - bindDefaultView(item, pkgName, hsImagePath, isLegacyTheme); - bindIconView(view, context, pkgName); - } else { - bindDefaultView(item, pkgName, hsImagePath, isLegacyTheme); - } - } - - private void bindDefaultView(ThemeItemHolder item, String pkgName, - String hsImagePath, boolean isLegacyTheme) { - //Do not load wallpaper if we preview icons - if (mFilters.contains(ThemesColumns.MODIFIES_ICONS)) return; - - if (isLegacyTheme) { - item.thumbnail.setTag(pkgName); - } else { - item.thumbnail.setTag(hsImagePath); - } - item.thumbnail.setImageDrawable(null); - - if (item.thumbnail.getTag() != null) { - LoadImage loadImageTask = new LoadImage(item.thumbnail, isLegacyTheme, false, pkgName); - loadImageTask.execute(); - } - } - - private void bindOverlayView(ThemeItemHolder item, String pkgName, - String styleImgPath, boolean isLegacyTheme) { - if (isLegacyTheme) { - item.thumbnail.setTag(pkgName); - } else { - item.thumbnail.setTag(styleImgPath); - } - item.thumbnail.setImageDrawable(null); - - if (item.thumbnail.getTag() != null) { - LoadImage loadImageTask = new LoadImage(item.thumbnail, isLegacyTheme, false, pkgName); - loadImageTask.execute(); - } - } - - private void bindBootAnimView(ThemeItemHolder item, Context context, String pkgName) { - (new BootAnimationHelper.LoadBootAnimationImage(item.thumbnail, context, pkgName)).execute(); - } - - private void bindWallpaperView(ThemeItemHolder item, String pkgName, - String hsImagePath, boolean isLegacyTheme) { - if (isLegacyTheme) { - item.thumbnail.setTag(pkgName); - } else { - item.thumbnail.setTag(hsImagePath); - } - item.thumbnail.setImageDrawable(null); - - if (item.thumbnail.getTag() != null) { - LoadImage loadImageTask = new LoadImage(item.thumbnail, isLegacyTheme, true, pkgName); - loadImageTask.execute(); - } - } - - public void bindFontView(View view, Context context, String pkgName) { - FontItemHolder item = (FontItemHolder) view.getTag(); - ThemedTypefaceHelper helper; - if (!mTypefaceHelpers.containsKey(pkgName)) { - helper = new ThemedTypefaceHelper(); - helper.load(mContext, pkgName); - mTypefaceHelpers.put(pkgName, helper); - } else { - helper = mTypefaceHelpers.get(pkgName); - } - Typeface typefaceNormal = helper.getTypeface(Typeface.NORMAL); - Typeface typefaceBold = helper.getTypeface(Typeface.BOLD); - item.textView.setTypeface(typefaceNormal); - item.textViewBold.setTypeface(typefaceBold); - } - - public void bindIconView(View view, Context context, String pkgName) { - ThemeItemHolder holder = (ThemeItemHolder) view.getTag(); - LoadIconsTask loadImageTask = new LoadIconsTask(context, pkgName, holder.mIconHolders); - loadImageTask.execute(); - } - - @Override - public View newView(Context context, Cursor cursor, ViewGroup parent) { - if (mComponentFilters.isEmpty()) { - return newDefaultView(context, cursor, parent); - } else if (mComponentFilters.contains(ThemesColumns.MODIFIES_FONTS)) { - return newFontView(context, cursor, parent); - } else if (mComponentFilters.contains(ThemesColumns.MODIFIES_ICONS)) { - return newDefaultView(context, cursor, parent); - } - return newDefaultView(context, cursor, parent); - } - - private View newDefaultView(Context context, Cursor cursor, ViewGroup parent) { - LayoutInflater inflater = LayoutInflater.from(mContext); - View row = inflater.inflate(R.layout.item_store_browse, parent, false); - ThemeItemHolder item = new ThemeItemHolder(); - item.thumbnail = (ImageView) row.findViewById(R.id.image); - item.title = (TextView) row.findViewById(R.id.title); - item.author = (TextView) row.findViewById(R.id.author); - item.mIconHolders = (ViewGroup) row.findViewById(R.id.icon_container); - row.setTag(item); - return row; - } - - private View newFontView(Context context, Cursor cursor, ViewGroup parent) { - LayoutInflater inflater = LayoutInflater.from(mContext); - View row = inflater.inflate(R.layout.item_chooser_browse_font, parent, false); - FontItemHolder item = new FontItemHolder(); - item.textView = (TextView) row.findViewById(R.id.text1); - item.textViewBold = (TextView) row.findViewById(R.id.text2); - item.title = (TextView) row.findViewById(R.id.title); - item.author = (TextView) row.findViewById(R.id.author); - row.setTag(item); - return row; - } - } - - public static class ThemeItemHolder { - ImageView thumbnail; - TextView title; - TextView author; - ViewGroup mIconHolders; - } - - public static class FontItemHolder extends ThemeItemHolder { - TextView textView; - TextView textViewBold; - } - - public class LoadImage extends AsyncTask<Object, Void, Bitmap> { - private ImageView imv; - private String path; - private boolean isLegacyTheme; - private boolean showWallpaper; - private String pkgName; - - public LoadImage(ImageView imv, boolean isLegacyTheme, boolean showWallpaper, String pkgName) { - this.imv = imv; - this.path = imv.getTag().toString(); - this.isLegacyTheme = isLegacyTheme; - this.showWallpaper = showWallpaper; - this.pkgName = pkgName; - } - - @Override - protected Bitmap doInBackground(Object... params) { - Bitmap bitmap = null; - Context context = getActivity(); - if (context == null) { - Log.d(TAG, "Activity was detached, skipping loadImage"); - return null; - } - - if (!isLegacyTheme) { - if (DEFAULT.equals(pkgName)) { - Resources res = context.getResources(); - AssetManager assets = new AssetManager(); - assets.addAssetPath(WallpaperAndIconPreviewFragment.FRAMEWORK_RES); - Resources frameworkRes = new Resources(assets, res.getDisplayMetrics(), - res.getConfiguration()); - bitmap = Utils.decodeResource(frameworkRes, - com.android.internal.R.drawable.default_wallpaper, - mMaxImageSize.x, mMaxImageSize.y); - } else { - if (URLUtil.isAssetUrl(path)) { - Context ctx = context; - try { - ctx = context.createPackageContext(pkgName, 0); - } catch (PackageManager.NameNotFoundException e) { - - } - bitmap = Utils.getBitmapFromAsset(ctx, path, mMaxImageSize.x, mMaxImageSize.y); - } else if (path != null) { - bitmap = Utils.decodeFile(path, mMaxImageSize.x, mMaxImageSize.y); - } - } - } else { - try { - PackageManager pm = context.getPackageManager(); - PackageInfo pi = pm.getPackageInfo(path, 0); - final Context themeContext = context.createPackageContext(path, - Context.CONTEXT_IGNORE_SECURITY); - final Resources res = themeContext.getResources(); - final int resId = showWallpaper ? pi.legacyThemeInfos[0].wallpaperResourceId : - pi.legacyThemeInfos[0].previewResourceId; - bitmap = Utils.decodeResource(res, resId, mMaxImageSize.x, mMaxImageSize.y); - } catch (PackageManager.NameNotFoundException e) { - bitmap = null; - } - } - return bitmap; - } - - @Override - protected void onPostExecute(Bitmap result) { - if (!imv.getTag().toString().equals(path)) { - return; - } - - if (result != null && imv != null) { - imv.setVisibility(View.VISIBLE); - imv.setImageBitmap(result); - } - } - } - - - public static class LoadIconsTask extends AsyncTask<Void, Void, List<IconInfo>> { - private String mPkgName; - private Context mContext; - private ViewGroup mIconViewGroup; - - public LoadIconsTask(Context context, String pkgName, ViewGroup iconViewGroup) { - mPkgName = pkgName; - mContext = context.getApplicationContext(); - mIconViewGroup = iconViewGroup; - mIconViewGroup.setTag(pkgName); - } - - @Override - protected List<IconInfo> doInBackground(Void... arg0) { - List<IconInfo> icons = new ArrayList<IconInfo>(); - IconPreviewHelper helper = new IconPreviewHelper(mContext, mPkgName); - - for (ComponentName component - : WallpaperAndIconPreviewFragment.getIconComponents(mContext)) { - Drawable icon = helper.getIcon(component); - IconInfo info = new IconInfo(null, icon); - icons.add(info); - } - - return icons; - } - - @Override - protected void onPreExecute() { - super.onPreExecute(); - mIconViewGroup.removeAllViews(); - } - - @Override - protected void onPostExecute(List<IconInfo> icons) { - if (!mIconViewGroup.getTag().toString().equals(mPkgName) || icons == null) { - return; - } - - for (IconInfo info : icons) { - LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(0, - LayoutParams.WRAP_CONTENT, 1f); - lparams.weight = 1f / icons.size(); - - // Sizes of composed icons differ in size from other icons when using - // ImageView. Using a TextView like in WallpaperAndIconPreviewFragment - // displays the icons as the correct size. - TextView tv = new TextView(mContext); - tv.setGravity(Gravity.CENTER_HORIZONTAL); - tv.setLayoutParams(lparams); - tv.setCompoundDrawables(null, info.icon, null, null); - mIconViewGroup.addView(tv); - } - } - } -} diff --git a/src/org/cyanogenmod/theme/chooser/ChooserDetailFragment.java b/src/org/cyanogenmod/theme/chooser/ChooserDetailFragment.java deleted file mode 100644 index acc6906..0000000 --- a/src/org/cyanogenmod/theme/chooser/ChooserDetailFragment.java +++ /dev/null @@ -1,650 +0,0 @@ -/* - * Copyright (C) 2014 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.chooser; - -import android.content.Context; -import android.content.res.ThemeManager; -import android.content.res.ThemeManager.ThemeChangeListener; -import android.database.Cursor; -import android.graphics.drawable.ClipDrawable; -import android.graphics.drawable.LayerDrawable; -import android.graphics.drawable.StateListDrawable; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.provider.ThemesContract; -import android.provider.ThemesContract.MixnMatchColumns; -import android.provider.ThemesContract.ThemesColumns; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentStatePagerAdapter; -import android.support.v4.app.LoaderManager; -import android.support.v4.content.CursorLoader; -import android.support.v4.content.Loader; -import android.support.v4.view.ViewPager; -import android.util.Log; -import android.util.SparseArray; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.CompoundButton.OnCheckedChangeListener; -import android.widget.TextView; - -import com.viewpagerindicator.CirclePageIndicator; -import org.cyanogenmod.theme.util.ChooserDetailScrollView; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -public class ChooserDetailFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>, ThemeChangeListener { - public static final HashMap<String, Integer> sComponentToId = new HashMap<String, Integer>(); - - private static final String TAG = ChooserDetailFragment.class.getName(); - private static final int LOADER_ID_THEME_INFO = 0; - private static final int LOADER_ID_APPLIED_THEME = 1; - - // Drawer States - private static final int DRAWER_CLOSED = 0; - private static final int DRAWER_PARTIALLY_OPEN = 1; - private static final int DRAWER_MOSTLY_OPEN = 2; - private static final int DRAWER_OPEN = 3; - - // Threshold values in "percentage scrolled" to determine what state the drawer is in - // ex: User opens up the drawer a little bit, taking up 10% of the visible space. The - // drawer is now considered partially open - // because CLOSED_THRESHOLD < 10% < PARTIAL_OPEN_THRESHOLD - private static final int DRAWER_CLOSED_THRESHOLD = 5; - private static final int DRAWER_PARTIALLY_OPEN_THRESHOLD = 25; - private static final int DRAWER_MOSTLY_OPEN_THRESHOLD = 90; - private static final int DRAWER_OPEN_THRESHOLD = 100; - - // Where to scroll when moving to a new state - private static final int DRAWER_CLOSED_SCROLL_AMOUNT = 0; - private static final int DRAWER_PARTIALLY_OPEN_AMOUNT = 25; - private static final int DRAWER_MOSTLY_OPEN_AMOUNT = 75; - private static final int DRAWER_FULLY_OPEN_AMOUNT = 100; - - private TextView mTitle; - private TextView mAuthor; - private Button mApply; - private ViewPager mPager; - private ThemeDetailPagerAdapter mPagerAdapter; - private String mPkgName; - private ChooserDetailScrollView mSlidingPanel; - private CirclePageIndicator mIndicator; - - private Handler mHandler; - private Cursor mAppliedThemeCursor; - private HashMap<String, CheckBox> mComponentToCheckbox = new HashMap<String, CheckBox>(); - - private boolean mLoadInitialCheckboxStates = true; - private SparseArray<Boolean> mInitialCheckboxStates = new SparseArray<Boolean>(); - private SparseArray<Boolean> mCurrentCheckboxStates = new SparseArray<Boolean>(); - private SparseArray<Boolean> mSavedCheckboxStates = new SparseArray<Boolean>(); - - // allows emphasis on a particular aspect of a theme. ex "mods_icons" would - // uncheck all components but icons and sets the first preview image to be the icon pack - private ArrayList<String> mComponentFilters; - - private ThemeManager mService; - - static { - sComponentToId.put(ThemesColumns.MODIFIES_OVERLAYS, R.id.chk_overlays); - sComponentToId.put(ThemesColumns.MODIFIES_BOOT_ANIM, R.id.chk_boot_anims); - sComponentToId.put(ThemesColumns.MODIFIES_FONTS, R.id.chk_fonts); - sComponentToId.put(ThemesColumns.MODIFIES_ICONS, R.id.chk_icons); - sComponentToId.put(ThemesColumns.MODIFIES_LAUNCHER, R.id.chk_wallpaper); - sComponentToId.put(ThemesColumns.MODIFIES_LOCKSCREEN, R.id.chk_lockscreen); - sComponentToId.put(ThemesColumns.MODIFIES_RINGTONES, R.id.chk_ringtones); - sComponentToId.put(ThemesColumns.MODIFIES_NOTIFICATIONS, R.id.chk_notifications); - sComponentToId.put(ThemesColumns.MODIFIES_ALARMS, R.id.chk_alarms); - } - - public static ChooserDetailFragment newInstance(String pkgName, ArrayList<String> componentFilters) { - ChooserDetailFragment fragment = new ChooserDetailFragment(); - Bundle args = new Bundle(); - args.putString("pkgName", pkgName); - args.putStringArrayList(ChooserActivity.EXTRA_COMPONENT_FILTER, componentFilters); - fragment.setArguments(args); - return fragment; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mHandler = new Handler(); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - mPkgName = getArguments().getString("pkgName"); - ArrayList<String> filters = getArguments().getStringArrayList(ChooserActivity.EXTRA_COMPONENT_FILTER); - mComponentFilters = (filters != null) ? filters : new ArrayList<String>(0); - View v = inflater.inflate(R.layout.fragment_chooser_theme_pager_item, container, false); - mTitle = (TextView) v.findViewById(R.id.title); - mAuthor = (TextView) v.findViewById(R.id.author); - - mPager = (ViewPager) v.findViewById(R.id.pager); - mPager.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View view) { - int state = getDrawerState(); - switch(state) { - case DRAWER_CLOSED: - smoothScrollDrawerTo(DRAWER_PARTIALLY_OPEN); - break; - case DRAWER_PARTIALLY_OPEN: - case DRAWER_MOSTLY_OPEN: - smoothScrollDrawerTo(DRAWER_OPEN); - break; - case DRAWER_OPEN: - smoothScrollDrawerTo(DRAWER_CLOSED); - break; - } - } - }); - - mPagerAdapter = new ThemeDetailPagerAdapter(getChildFragmentManager()); - mPager.setAdapter(mPagerAdapter); - - - mIndicator = (CirclePageIndicator) v.findViewById(R.id.titles); - mIndicator.setViewPager(mPager); - - mApply = (Button) v.findViewById(R.id.apply); - mApply.setOnClickListener(new OnClickListener() { - public void onClick(View view) { - List<String> components = getCheckedComponents(); - mService.requestThemeChange(mPkgName, components); - mApply.setText(R.string.applying); - } - }); - - mSlidingPanel = (ChooserDetailScrollView) v.findViewById(R.id.sliding_layout); - - // Find all the checkboxes for theme components (ex wallpaper) - for (Map.Entry<String, Integer> entry : sComponentToId.entrySet()) { - CheckBox componentCheckbox = (CheckBox) v.findViewById(entry.getValue()); - mComponentToCheckbox.put(entry.getKey(), componentCheckbox); - componentCheckbox.setOnCheckedChangeListener(mComponentCheckChangedListener); - if (savedInstanceState != null) { - mSavedCheckboxStates.put(entry.getValue(), - savedInstanceState.getBoolean(entry.getKey())); - } - } - - getLoaderManager().initLoader(LOADER_ID_THEME_INFO, null, this); - getLoaderManager().initLoader(LOADER_ID_APPLIED_THEME, null, this); - mService = (ThemeManager) getActivity().getSystemService(Context.THEME_SERVICE); - return v; - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - for (Map.Entry<String, CheckBox> entry : mComponentToCheckbox.entrySet()) { - String component = entry.getKey(); - CheckBox checkBox = entry.getValue(); - outState.putBoolean(component, checkBox.isChecked()); - } - } - - private List<String> getCheckedComponents() { - // Get all checked components - List<String> components = new ArrayList<String>(); - for (Map.Entry<String, CheckBox> entry : mComponentToCheckbox.entrySet()) { - String component = entry.getKey(); - CheckBox checkbox = entry.getValue(); - if (checkbox.isEnabled() && checkbox.isChecked()) { - components.add(component); - } - } - return components; - } - - @Override - public void onResume() { - super.onResume(); - if (mService != null) { - mService.onClientResumed(this); - } - refreshApplyButton(); - } - - @Override - public void onPause() { - super.onPause(); - if (mService != null) { - mService.onClientPaused(this); - } - } - - @Override - public void onDestroy() { - super.onDestroy(); - if (mService != null) { - mService.onClientDestroyed(this); - } - } - - @Override - public void onStart() { - super.onStart(); - mSlidingPanel.post(mShowSlidingPanelRunnable); - } - - private Runnable mShowSlidingPanelRunnable = new Runnable() { - @Override - public void run() { - // Arbitrarily scroll a bit at the start - int height = mSlidingPanel.getHeight() / 4; - mSlidingPanel.smoothScrollTo(0, height); - } - }; - - private OnCheckedChangeListener mComponentCheckChangedListener = new OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - mCurrentCheckboxStates.put(buttonView.getId(), isChecked); - if (componentSelectionChanged()) { - mApply.setEnabled(true); - } else { - mApply.setEnabled(false); - } - } - }; - - private boolean componentSelectionChanged() { - if (mCurrentCheckboxStates.size() != mInitialCheckboxStates.size()) return false; - - int N = mInitialCheckboxStates.size(); - for (int i = 0; i < N; i++) { - int key = mInitialCheckboxStates.keyAt(i); - if (!mInitialCheckboxStates.get(key).equals(mCurrentCheckboxStates.get(key))) { - return true; - } - } - - return false; - } - - @Override - public Loader<Cursor> onCreateLoader(int id, Bundle args) { - Uri uri = null; - String selection = null; - String[] selectionArgs = null; - - switch (id) { - case LOADER_ID_THEME_INFO: - uri = ThemesColumns.CONTENT_URI; - selection = ThemesColumns.PKG_NAME + "= ?"; - selectionArgs = new String[] { mPkgName }; - break; - case LOADER_ID_APPLIED_THEME: - uri = MixnMatchColumns.CONTENT_URI; - break; - } - - return new CursorLoader(getActivity(), uri, null, selection, selectionArgs, null); - } - - @Override - public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) { - int id = cursorLoader.getId(); - - if (id == LOADER_ID_THEME_INFO) { - if (cursor.getCount() == 0) { - //Theme was deleted - safelyPopStack(); - } else { - loadThemeInfo(cursor); - } - } else if (id == LOADER_ID_APPLIED_THEME) { - loadAppliedInfo(cursor); - } - } - - /** - * Avoid IllegalStateException when popping the backstack - * in onLoadFinished. - */ - private void safelyPopStack() { - Runnable r = new Runnable() { - public void run() { - getFragmentManager().popBackStackImmediate(); - } - }; - mHandler.post(r); - } - - private void loadThemeInfo(Cursor cursor) { - cursor.moveToFirst(); - int titleIdx = cursor.getColumnIndex(ThemesColumns.TITLE); - int authorIdx = cursor.getColumnIndex(ThemesColumns.AUTHOR); - int hsIdx = cursor.getColumnIndex(ThemesColumns.HOMESCREEN_URI); - int legacyIdx = cursor.getColumnIndex(ThemesColumns.IS_LEGACY_THEME); - int styleIdx = cursor.getColumnIndex(ThemesColumns.STYLE_URI); - int lockIdx = cursor.getColumnIndex(ThemesColumns.LOCKSCREEN_URI); - int defaultIdx = cursor.getColumnIndex(ThemesColumns.IS_DEFAULT_THEME); - - boolean isLegacyTheme = cursor.getInt(legacyIdx) == 1; - boolean isDefaultTheme = cursor.getInt(defaultIdx) == 1; - String title = ChooserBrowseFragment.DEFAULT.equals(mPkgName) - ? getActivity().getString(R.string.holo) : cursor.getString(titleIdx); - String author = cursor.getString(authorIdx); - String hsImagePath = isLegacyTheme ? mPkgName : cursor.getString(hsIdx); - String styleImagePath = cursor.getString(styleIdx); - String lockWallpaperImagePath = cursor.getString(lockIdx); - - mTitle.setText(title + (isDefaultTheme ? " " + getString(R.string.default_tag) : "")); - mAuthor.setText(author); - - // Configure checkboxes for all the theme components - List<String> supportedComponents = new LinkedList<String>(); - for (Map.Entry<String, CheckBox> entry : mComponentToCheckbox.entrySet()) { - String componentName = entry.getKey(); - CheckBox componentCheckbox = entry.getValue(); - int idx = cursor.getColumnIndex(componentName); - boolean componentIncludedInTheme = cursor.getInt(idx) == 1; - - - if (!shouldComponentBeVisible(componentName)) { - componentCheckbox.setVisibility(View.GONE); - } - - if (shouldComponentBeEnabled(componentName, componentIncludedInTheme)) { - componentCheckbox.setEnabled(true); - } else { - componentCheckbox.setEnabled(false); - } - - if (componentIncludedInTheme) { - supportedComponents.add(componentName); - } - } - - mPagerAdapter.setPreviewImage(hsImagePath, isLegacyTheme); - mPagerAdapter.setStyleImage(styleImagePath); - mPagerAdapter.setLockScreenImage(lockWallpaperImagePath); - mPagerAdapter.update(supportedComponents); - } - - private boolean shouldComponentBeVisible(String componentName) { - // Theme pack, so it is always visible - if (mComponentFilters.isEmpty()) return true; - //Not in a theme pack - return !componentFiltered(componentName); - } - - private boolean shouldComponentBeEnabled(String componentName, boolean componentIncludedInTheme) { - return !componentFiltered(componentName) && componentIncludedInTheme; - } - - - private boolean componentFiltered(String componentName) { - if (mComponentFilters.isEmpty()) return false; - return !mComponentFilters.contains(componentName); - } - - private void loadAppliedInfo(Cursor cursor) { - mAppliedThemeCursor = cursor; - refreshChecksForCheckboxes(); - refreshApplyButton(); - } - - private void refreshChecksForCheckboxes() { - - //Determine which components are applied - List<String> appliedComponents = new ArrayList<String>(); - if (mAppliedThemeCursor != null) { - mAppliedThemeCursor.moveToPosition(-1); - while (mAppliedThemeCursor.moveToNext()) { - String mixnmatchkey = mAppliedThemeCursor.getString(mAppliedThemeCursor.getColumnIndex(MixnMatchColumns.COL_KEY)); - String component = ThemesContract.MixnMatchColumns.mixNMatchKeyToComponent(mixnmatchkey); - String pkg = mAppliedThemeCursor.getString(mAppliedThemeCursor.getColumnIndex(MixnMatchColumns.COL_VALUE)); - - if (pkg.equals(mPkgName)) { - appliedComponents.add(component); - } - } - } - - //Apply checks - for (Map.Entry<String, CheckBox> entry : mComponentToCheckbox.entrySet()) { - String componentName = entry.getKey(); - CheckBox componentCheckbox = entry.getValue(); - - if (appliedComponents.contains(componentName)) { - if (mSavedCheckboxStates.size() > 0 && - mSavedCheckboxStates.get(componentCheckbox.getId()) != null) { - componentCheckbox.setChecked(mSavedCheckboxStates.get( - componentCheckbox.getId())); - } else { - componentCheckbox.setChecked(true); - } - } - if (mLoadInitialCheckboxStates) { - mInitialCheckboxStates.put(componentCheckbox.getId(), - componentCheckbox.isChecked()); - } - mCurrentCheckboxStates.put(componentCheckbox.getId(), componentCheckbox.isChecked()); - } - } - - private void refreshApplyButton() { - //Default - mApply.setText(R.string.apply); - StateListDrawable d = (StateListDrawable) mApply.getBackground(); - LayerDrawable bg = (LayerDrawable) d.getStateDrawable( - d.getStateDrawableIndex(new int[] {android.R.attr.state_enabled})); - final ClipDrawable clip = (ClipDrawable) bg.findDrawableByLayerId(android.R.id.progress); - clip.setLevel(0); - - //Determine whether the apply button should show "apply" or "update" - if (mAppliedThemeCursor != null) { - mAppliedThemeCursor.moveToPosition(-1); - while (mAppliedThemeCursor.moveToNext()) { - String component = mAppliedThemeCursor.getString(mAppliedThemeCursor.getColumnIndex(MixnMatchColumns.COL_KEY)); - String pkg = mAppliedThemeCursor.getString(mAppliedThemeCursor.getColumnIndex(MixnMatchColumns.COL_VALUE)); - - // At least one component is set here for this theme - if (pkg != null && mPkgName.equals(pkg)) { - mApply.setText(R.string.update); - break; - } - } - } - - //Determine if the apply button's progress - int progress = (mService == null) ? 0 : mService.getProgress(); - if (progress != 0) { - clip.setLevel(progress * 100); - mApply.setText(R.string.applying); - mApply.setClickable(false); - } else { - mApply.setClickable(true); - } - } - - @Override - public void onLoaderReset(Loader<Cursor> cursor) { - mAppliedThemeCursor = null; - } - - @Override - public void onProgress(int progress) { - refreshApplyButton(); - } - - @Override - public void onFinish(boolean isSuccess) { - Log.d(TAG, "Finished Applying Theme success=" + isSuccess); - refreshApplyButton(); - } - - public class ThemeDetailPagerAdapter extends FragmentStatePagerAdapter { - private List<String> mPreviewList = new LinkedList<String>(); - private List<String> mSupportedComponents = Collections.emptyList(); - private String mPreviewImagePath; - private boolean mIsLegacyTheme; - private String mLockScreenImagePath; - private String mStyleImagePath; - - public ThemeDetailPagerAdapter(FragmentManager fm) { - super(fm); - } - - public void setPreviewImage(String imagePath, boolean isLegacyTheme) { - mPreviewImagePath = imagePath; - mIsLegacyTheme = isLegacyTheme; - } - - public void setStyleImage(String imagePath) { - mStyleImagePath = imagePath; - } - - public void setLockScreenImage(String lockPath) { - mLockScreenImagePath = lockPath; - } - - private void update(List<String> supportedComponents) { - mSupportedComponents = supportedComponents; - mPreviewList.clear(); - mPreviewList.addAll(supportedComponents); - - // If a particular component is being emphasized - // then the preview image should reflect that by showing it first - for (String component : mComponentFilters) { - mPreviewList.remove(component); - mPreviewList.add(0, component); - } - - // Wallpaper and Icons are previewed together so two fragments are not needed - if (mSupportedComponents.contains(ThemesColumns.MODIFIES_LAUNCHER) && - mSupportedComponents.contains(ThemesColumns.MODIFIES_ICONS)) { - mPreviewList.remove(ThemesColumns.MODIFIES_ICONS); - } - - // The AudiblePreviewFragment will take care of loading all available - // audibles so remove all but one so only one fragment instance is created - if (mSupportedComponents.contains(ThemesColumns.MODIFIES_ALARMS)) { - mPreviewList.remove(ThemesColumns.MODIFIES_NOTIFICATIONS); - mPreviewList.remove(ThemesColumns.MODIFIES_RINGTONES); - } else if (mSupportedComponents.contains(ThemesColumns.MODIFIES_NOTIFICATIONS)) { - mPreviewList.remove(ThemesColumns.MODIFIES_RINGTONES); - } - - notifyDataSetChanged(); - } - - @Override - public int getCount() { - return mPreviewList.size(); - } - - @Override - public Fragment getItem(int position) { - String component = mPreviewList.get(position); - Fragment fragment = null; - - if (component.equals(ThemesColumns.MODIFIES_LAUNCHER)) { - boolean showIcons = mSupportedComponents.contains(ThemesColumns.MODIFIES_ICONS); - fragment = WallpaperAndIconPreviewFragment.newInstance(mPreviewImagePath, mPkgName, - mIsLegacyTheme, showIcons); - } else if (component.equals(ThemesColumns.MODIFIES_OVERLAYS)) { - fragment = WallpaperAndIconPreviewFragment.newInstance(mStyleImagePath, mPkgName, - mIsLegacyTheme, false); - } else if (component.equals(ThemesColumns.MODIFIES_BOOT_ANIM)) { - fragment = BootAniPreviewFragment.newInstance(mPkgName); - } else if (component.equals(ThemesColumns.MODIFIES_FONTS)) { - fragment = FontPreviewFragment.newInstance(mPkgName); - } else if (component.equals(ThemesColumns.MODIFIES_LOCKSCREEN)) { - fragment = WallpaperAndIconPreviewFragment.newInstance(mLockScreenImagePath, - mPkgName, mIsLegacyTheme, false); - } else if (component.equals(ThemesColumns.MODIFIES_LAUNCHER)) { - throw new UnsupportedOperationException("Not implemented yet!"); - } else if (component.equals(ThemesColumns.MODIFIES_ICONS)) { - fragment = WallpaperAndIconPreviewFragment.newInstance(mPreviewImagePath, mPkgName, - mIsLegacyTheme, mSupportedComponents.contains(ThemesColumns.MODIFIES_ICONS)); - } else if (component.equals(ThemesColumns.MODIFIES_ALARMS) - || component.equals(ThemesColumns.MODIFIES_NOTIFICATIONS) - || component.equals(ThemesColumns.MODIFIES_RINGTONES)) { - fragment = AudiblePreviewFragment.newInstance(mPkgName); - } else { - throw new UnsupportedOperationException("Cannot preview " + component); - } - return fragment; - } - } - - private void smoothScrollDrawerTo(int drawerState) { - int scrollPercentage = 0; - switch(drawerState) { - case DRAWER_CLOSED: - scrollPercentage = DRAWER_CLOSED_SCROLL_AMOUNT; - break; - case DRAWER_PARTIALLY_OPEN: - scrollPercentage = DRAWER_PARTIALLY_OPEN_AMOUNT; - break; - case DRAWER_MOSTLY_OPEN: - scrollPercentage = DRAWER_MOSTLY_OPEN_AMOUNT; - break; - case DRAWER_OPEN: - scrollPercentage = DRAWER_FULLY_OPEN_AMOUNT; - break; - default: - throw new IllegalArgumentException("Bad drawer state: " + drawerState); - } - - int visibleHeight = mSlidingPanel.getHeight(); - View handle = mSlidingPanel.getHandle(); - visibleHeight -= handle.getHeight(); - - int scrollY = scrollPercentage * visibleHeight / 100; - mSlidingPanel.smoothScrollTo(0, scrollY); - } - - private int getDrawerState() { - // Scroll between 3 different heights when pager is clicked - int visibleHeight = mSlidingPanel.getHeight(); - View handle = mSlidingPanel.getHandle(); - visibleHeight -= handle.getHeight(); - int scrollY = mSlidingPanel.getScrollY(); - int percentageScrolled = (scrollY * 100) / (visibleHeight); - - //Check if we are bottom of scroll - View view = (View) mSlidingPanel.getChildAt(0); - boolean isAtBottom = (view.getBottom() - (mSlidingPanel.getHeight() + scrollY)) == 0; - - if (percentageScrolled < DRAWER_CLOSED_THRESHOLD && !isAtBottom) { - return DRAWER_CLOSED; - } else if (percentageScrolled < DRAWER_PARTIALLY_OPEN_THRESHOLD && !isAtBottom) { - return DRAWER_PARTIALLY_OPEN; - } else if (percentageScrolled < DRAWER_MOSTLY_OPEN_THRESHOLD && !isAtBottom) { - return DRAWER_MOSTLY_OPEN; - } - - return DRAWER_OPEN; - } -} diff --git a/src/org/cyanogenmod/theme/chooser/FontPreviewFragment.java b/src/org/cyanogenmod/theme/chooser/FontPreviewFragment.java deleted file mode 100644 index fdde292..0000000 --- a/src/org/cyanogenmod/theme/chooser/FontPreviewFragment.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2014 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.chooser; - -import android.graphics.Typeface; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import org.cyanogenmod.theme.util.ThemedTypefaceHelper; - - -public class FontPreviewFragment extends Fragment { - private static final String PKG_EXTRA = "pkg_extra"; - private String mPkgName; - - private Typeface mTypefaceNormal; - private Typeface mTypefaceBold; - private Typeface mTypefaceItalic; - private Typeface mTypefaceBoldItalic; - - private TextView mTv1; - private TextView mTv2; - private TextView mTv3; - private TextView mTv4; - - static FontPreviewFragment newInstance(String pkgName) { - final FontPreviewFragment f = new FontPreviewFragment(); - final Bundle args = new Bundle(); - args.putString(PKG_EXTRA, pkgName); - f.setArguments(args); - return f; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mPkgName = getArguments().getString(PKG_EXTRA); - - ThemedTypefaceHelper helper = new ThemedTypefaceHelper(); - helper.load(getActivity(), mPkgName); - mTypefaceNormal = helper.getTypeface(Typeface.NORMAL); - mTypefaceBold = helper.getTypeface(Typeface.BOLD); - mTypefaceItalic = helper.getTypeface(Typeface.ITALIC); - mTypefaceBoldItalic = helper.getTypeface(Typeface.BOLD_ITALIC); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.font_preview_item, container, false); - mTv1 = (TextView) view.findViewById(R.id.text1); - mTv2 = (TextView) view.findViewById(R.id.text2); - mTv3 = (TextView) view.findViewById(R.id.text3); - mTv4 = (TextView) view.findViewById(R.id.text4); - - mTv1.setTypeface(mTypefaceNormal); - mTv3.setTypeface(mTypefaceItalic); - mTv2.setTypeface(mTypefaceBold); - mTv4.setTypeface(mTypefaceBoldItalic); - - return view; - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - } -} diff --git a/src/org/cyanogenmod/theme/chooser/NotificationHijackingService.java b/src/org/cyanogenmod/theme/chooser/NotificationHijackingService.java deleted file mode 100644 index 41c3a46..0000000 --- a/src/org/cyanogenmod/theme/chooser/NotificationHijackingService.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2014 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.chooser; - -import android.app.PendingIntent; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.provider.Settings; -import android.service.notification.NotificationListenerService; -import android.service.notification.StatusBarNotification; -import android.text.TextUtils; - -public class NotificationHijackingService extends NotificationListenerService { - private static final String TAG = NotificationHijackingService.class.getName(); - private static final String GOOGLE_PLAY_PACKAGE_NAME = "com.android.vending"; - private static final String ACTION_INSTALLED = - "com.android.vending.SUCCESSFULLY_INSTALLED_CLICKED"; - private static final String EXTRA_PACKAGE_NAME = "package_name"; - - @Override - public void onNotificationPosted(StatusBarNotification sbn) { - if (GOOGLE_PLAY_PACKAGE_NAME.equals(sbn.getPackageName())) { - PendingIntent contentIntent = sbn.getNotification().contentIntent; - if (contentIntent == null) return; - Intent intent = contentIntent.getIntent(); - if (intent == null) return; - String action = intent.getAction(); - if (ACTION_INSTALLED.equals(action)) { - String pkgName = intent.getStringExtra(EXTRA_PACKAGE_NAME); - try { - PackageInfo pi = getPackageManager().getPackageInfo(pkgName, 0); - if (pi != null) { - if ((pi.themeInfos != null && pi.themeInfos.length > 0) || - (pi.legacyThemeInfos != null && pi.legacyThemeInfos.length > 0)) { - cancelNotification(GOOGLE_PLAY_PACKAGE_NAME, sbn.getTag(), sbn.getId()); - } - } - } catch (PackageManager.NameNotFoundException e) { - } - } - } - } - - @Override - public void onNotificationRemoved(StatusBarNotification sbn) { - } - - // ensure that this notification listener is enabled. - // the service watches for google play notifications - public static void ensureEnabled(Context context) { - ComponentName me = new ComponentName(context, NotificationHijackingService.class); - String meFlattened = me.flattenToString(); - - String existingListeners = Settings.Secure.getString(context.getContentResolver(), - Settings.Secure.ENABLED_NOTIFICATION_LISTENERS); - - if (!TextUtils.isEmpty(existingListeners)) { - if (existingListeners.contains(meFlattened)) { - return; - } else { - existingListeners += ":" + meFlattened; - } - } else { - existingListeners = meFlattened; - } - - Settings.Secure.putString(context.getContentResolver(), - Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, - existingListeners); - } -}
\ No newline at end of file diff --git a/src/org/cyanogenmod/theme/chooser/WallpaperAndIconPreviewFragment.java b/src/org/cyanogenmod/theme/chooser/WallpaperAndIconPreviewFragment.java deleted file mode 100644 index 510a8a6..0000000 --- a/src/org/cyanogenmod/theme/chooser/WallpaperAndIconPreviewFragment.java +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (C) 2014 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.chooser; - -import java.util.ArrayList; -import java.util.List; - -import android.content.ComponentName; -import android.content.Context; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.res.AssetManager; -import android.content.res.ThemeConfig; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Color; -import android.graphics.Point; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.support.v4.app.LoaderManager.LoaderCallbacks; -import android.support.v4.content.AsyncTaskLoader; -import android.support.v4.content.Loader; -import android.view.Display; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewGroup.LayoutParams; -import android.view.WindowManager; -import android.webkit.URLUtil; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import org.cyanogenmod.theme.util.IconPreviewHelper; -import org.cyanogenmod.theme.util.Utils; - -public class WallpaperAndIconPreviewFragment extends Fragment -{ - private static final int LOADER_ID_IMAGE = 0; - private static final int LOADER_ID_ICONS = 1; - - private static final ComponentName COMPONENT_DIALER = - new ComponentName("com.android.dialer", "com.android.dialer.DialtactsActivity"); - private static final ComponentName COMPONENT_MESSAGING = - new ComponentName("com.android.mms", "com.android.mms.ui.ConversationList"); - private static final ComponentName COMPONENT_CAMERANEXT = - new ComponentName("com.cyngn.cameranext", "com.android.camera.CameraLauncher"); - private static final ComponentName COMPONENT_CAMERA = - new ComponentName("com.android.camera2", "com.android.camera.CameraActivity"); - private static final ComponentName COMPONENT_BROWSER = - new ComponentName("com.android.browser", "com.android.browser.BrowserActivity"); - private static final ComponentName COMPONENT_SETTINGS = - new ComponentName("com.android.settings", "com.android.settings.Settings"); - private static final ComponentName COMPONENT_CALENDAR = - new ComponentName("com.android.calendar", "com.android.calendar.AllInOneActivity"); - private static final ComponentName COMPONENT_GALERY = - new ComponentName("com.android.gallery3d", "com.android.gallery3d.app.GalleryActivity"); - - private static final String CAMERA_NEXT_PACKAGE = "com.cyngn.cameranext"; - - private static ComponentName[] sIconComponents; - - private static final String PKGNAME_EXTRA = "pkgname"; - private static final String IMAGE_DATA_EXTRA = "url"; - private static final String LEGACY_THEME_EXTRA = "isLegacyTheme"; - private static final String HAS_ICONS_EXTRA = "hasIcons"; - - public static final String FRAMEWORK_RES = "/system/framework/framework-res.apk"; - - private String mPkgName; - private String mImageUrl; - private boolean mIsLegacyTheme; - private boolean mHasIcons; - - private ImageView mImageView; - private LinearLayout mIconContainer; - private TextView mNoPreview; - - static WallpaperAndIconPreviewFragment newInstance(String imageUrl, String pkgName, boolean isLegacyTheme, boolean hasIcons) { - final WallpaperAndIconPreviewFragment f = new WallpaperAndIconPreviewFragment(); - final Bundle args = new Bundle(); - args.putString(IMAGE_DATA_EXTRA, imageUrl); - args.putString(PKGNAME_EXTRA, pkgName); - args.putBoolean(LEGACY_THEME_EXTRA, isLegacyTheme); - args.putBoolean(HAS_ICONS_EXTRA, hasIcons); - f.setArguments(args); - return f; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mImageUrl = getArguments().getString(IMAGE_DATA_EXTRA); - mIsLegacyTheme = getArguments().getBoolean(LEGACY_THEME_EXTRA); - mHasIcons = getArguments().getBoolean(HAS_ICONS_EXTRA); - mPkgName = getArguments().getString(PKGNAME_EXTRA); - - getIconComponents(getActivity()); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.image_preview_item, container, false); - mImageView = (ImageView) view.findViewById(R.id.image); - mIconContainer = (LinearLayout) view.findViewById(R.id.icon_container); - mNoPreview = (TextView) view.findViewById(R.id.no_preview); - return view; - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - getLoaderManager().initLoader(LOADER_ID_IMAGE, null, mImageCallbacks); - if (mHasIcons) { - getLoaderManager().initLoader(LOADER_ID_ICONS, null, mIconCallbacks); - } - } - - @Override - public void onStart() { - super.onStart(); - - } - - public static ComponentName[] getIconComponents(Context context) { - - if (sIconComponents == null || sIconComponents.length == 0) { - sIconComponents = new ComponentName[]{COMPONENT_DIALER, COMPONENT_MESSAGING, - COMPONENT_CAMERA, COMPONENT_BROWSER}; - - PackageManager pm = context.getPackageManager(); - - // if device does not have telephony replace dialer and mms - if (!pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { - sIconComponents[0] = COMPONENT_CALENDAR; - sIconComponents[1] = COMPONENT_GALERY; - } - - if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) { - sIconComponents[2] = COMPONENT_SETTINGS; - } else { - // decide on which camera icon to use - try { - if (pm.getPackageInfo(CAMERA_NEXT_PACKAGE, 0) != null) { - sIconComponents[2] = COMPONENT_CAMERANEXT; - } - } catch (NameNotFoundException e) { - // default to COMPONENT_CAMERA - } - } - - } - - return sIconComponents; - } - - private final LoaderCallbacks<Bitmap> mImageCallbacks = new LoaderCallbacks<Bitmap>() { - - @Override - public Loader<Bitmap> onCreateLoader(int id, Bundle args) { - return new ImageLoader(getActivity(), mIsLegacyTheme, mPkgName, mImageUrl); - } - - @Override - public void onLoadFinished(Loader<Bitmap> loader, Bitmap result) { - mImageView.setImageBitmap(result); - if (result == null && !mHasIcons) { - mNoPreview.setVisibility(View.VISIBLE); - } - } - - @Override - public void onLoaderReset(Loader<Bitmap> loader) { - } - }; - - private final LoaderCallbacks<List<IconInfo>> mIconCallbacks = new LoaderCallbacks<List<IconInfo>>() { - @Override - public Loader<List<IconInfo>> onCreateLoader(int id, Bundle args) { - return new IconsLoader(getActivity(), mPkgName); - } - - @Override - public void onLoadFinished(Loader<List<IconInfo>> loader, List<IconInfo> infos) { - final float SHADOW_LARGE_RADIUS = 4.0f; - final float SHADOW_Y_OFFSET = 2.0f; - final int SHADOW_LARGE_COLOUR = 0xDD000000; - - mIconContainer.removeAllViews(); - for (IconInfo info : infos) { - LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(0, - LayoutParams.WRAP_CONTENT, 1f); - lparams.weight = 1f / infos.size(); - TextView tv = new TextView(loader.getContext()); - tv.setShadowLayer(SHADOW_LARGE_RADIUS, 0.0f, SHADOW_Y_OFFSET, SHADOW_LARGE_COLOUR); - tv.setTextColor(Color.WHITE); - tv.setGravity(Gravity.CENTER_HORIZONTAL); - tv.setLayoutParams(lparams); - tv.setCompoundDrawables(null, info.icon, null, null); - tv.setText(info.name); - - mIconContainer.addView(tv); - } - } - - @Override - public void onLoaderReset(Loader<List<IconInfo>> loader) { - } - - }; - - public static class ImageLoader extends AsyncTaskLoader<Bitmap> { - private String mPkgName; - private boolean mIsLegacyTheme; - private String mImageUrl; - private Point mDisplaySize = new Point(); - - public ImageLoader(Context context, boolean isLegacyTheme, String pkgName, String imageUrl) { - super(context); - mIsLegacyTheme = isLegacyTheme; - mPkgName = pkgName; - mImageUrl = imageUrl; - WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); - Display display = wm.getDefaultDisplay(); - display.getSize(mDisplaySize); - onContentChanged(); - } - - @Override - protected void onStartLoading() { - if (takeContentChanged()) { - forceLoad(); - } - } - - @Override - public Bitmap loadInBackground() { - Bitmap bitmap = null; - - if (mIsLegacyTheme) { - return loadLegacyImage(); - } - - if (ThemeConfig.HOLO_DEFAULT.equals(mPkgName)) { - Resources res = getContext().getResources(); - AssetManager assets = new AssetManager(); - assets.addAssetPath(FRAMEWORK_RES); - Resources frameworkRes = new Resources(assets, res.getDisplayMetrics(), - res.getConfiguration()); - bitmap = BitmapFactory.decodeResource(frameworkRes, - com.android.internal.R.drawable.default_wallpaper); - } else { - if (URLUtil.isAssetUrl(mImageUrl)) { - bitmap = Utils.getBitmapFromAsset(getContext(), mImageUrl, mDisplaySize.x, - mDisplaySize.y); - } else { - bitmap = BitmapFactory.decodeFile(mImageUrl); - } - } - return bitmap; - } - - private Bitmap loadLegacyImage() { - Bitmap bitmap; - try { - PackageManager pm = getContext().getPackageManager(); - PackageInfo pi = pm.getPackageInfo(mPkgName, 0); - final Context themeContext = getContext().createPackageContext(mPkgName, - Context.CONTEXT_IGNORE_SECURITY); - final Resources res = themeContext.getResources(); - bitmap = BitmapFactory.decodeResource(res, pi.legacyThemeInfos[0].previewResourceId); - } catch (PackageManager.NameNotFoundException e) { - bitmap = null; - } - return bitmap; - } - } - - public static class IconsLoader extends AsyncTaskLoader<List<IconInfo>> { - private String mPkgName; - - public IconsLoader(Context context, String pkgName) { - super(context); - mPkgName = pkgName; - onContentChanged(); - } - - @Override - protected void onStartLoading() { - if (takeContentChanged()) { - forceLoad(); - } - } - - @Override - public List<IconInfo> loadInBackground() { - List<IconInfo> icons = new ArrayList<IconInfo>(); - IconPreviewHelper helper = new IconPreviewHelper(getContext(), mPkgName); - - for (ComponentName component : sIconComponents) { - Drawable icon = helper.getIcon(component); - String label = helper.getLabel(component); - IconInfo info = new IconInfo(label, icon); - icons.add(info); - } - return icons; - } - } - - public static class IconInfo { - public String name; - public Drawable icon; - public IconInfo(String name, Drawable drawable) { - this.name = name; - this.icon = drawable; - } - } -} diff --git a/src/org/cyanogenmod/theme/chooserv2/ChooserActivity.java b/src/org/cyanogenmod/theme/chooserv2/ChooserActivity.java deleted file mode 100644 index 8f94739..0000000 --- a/src/org/cyanogenmod/theme/chooserv2/ChooserActivity.java +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Copyright (C) 2014 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.chooserv2; - -import android.content.Context; -import android.content.res.Resources; -import android.content.res.ThemeConfig; -import android.content.res.ThemeManager; -import android.database.Cursor; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Bundle; -import android.os.Handler; -import android.provider.ThemesContract; -import android.provider.ThemesContract.ThemesColumns; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentActivity; -import android.support.v4.app.FragmentStatePagerAdapter; -import android.support.v4.app.LoaderManager; -import android.support.v4.content.CursorLoader; -import android.support.v4.content.Loader; -import android.support.v4.view.ThemeViewPager; -import android.support.v4.view.ViewPager; -import android.util.DisplayMetrics; -import android.util.TypedValue; -import android.view.View; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.widget.Button; - -import org.cyanogenmod.theme.chooser.R; -import org.cyanogenmod.theme.chooserv2.ComponentSelector.OnOpenCloseListener; -import org.cyanogenmod.theme.util.TypefaceHelperCache; -import org.cyanogenmod.theme.util.Utils; - -import java.util.HashMap; -import java.util.Map; - -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_ALARMS; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_BOOT_ANIM; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_NOTIFICATIONS; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_RINGTONES; - -public class ChooserActivity extends FragmentActivity - implements LoaderManager.LoaderCallbacks<Cursor>, ThemeManager.ThemeChangeListener { - public static final String DEFAULT = ThemeConfig.HOLO_DEFAULT; - public static final int REQUEST_UNINSTALL = 1; // Request code - - private static final long SLIDE_CONTENT_ANIM_DURATION = 300L; - private static final long MOVE_TO_MY_THEME_DELAY = 750L; - - private static final int OFFSCREEN_PAGE_LIMIT = 3; - - private static final int LOADER_ID_INSTALLED_THEMES = 1000; - private static final int LOADER_ID_APPLIED = 1001; - - private PagerContainer mContainer; - private ThemeViewPager mPager; - private Button mEdit; - - private ThemesAdapter mAdapter; - private ThemeManager mService; - private boolean mExpanded = false; - private ComponentSelector mSelector; - private View mSaveApplyLayout; - private int mContainerYOffset = 0; - private TypefaceHelperCache mTypefaceHelperCache; - private boolean mIsAnimating; - private Handler mHandler; - - // Current system theme configuration as component -> pkgName - private Map<String, String> mCurrentTheme = new HashMap<String, String>(); - - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.v2_activity_main); - - mContainer = (PagerContainer) findViewById(R.id.pager_container); - mPager = (ThemeViewPager) findViewById(R.id.viewpager); - mEdit = (Button) findViewById(R.id.edit); - - mPager.setOnClickListener(mPagerClickListener); - mAdapter = new ThemesAdapter(this); - mPager.setAdapter(mAdapter); - - DisplayMetrics dm = getResources().getDisplayMetrics(); - int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48, dm); - mPager.setPageMargin(-margin / 2); - mPager.setOffscreenPageLimit(OFFSCREEN_PAGE_LIMIT); - - mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { - public void onPageSelected(int position) { - } - - public void onPageScrolled(int position, - float positionOffset, - int positionOffsetPixels) { - } - - public void onPageScrollStateChanged(int state) { - } - }); - - mEdit.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - mExpanded = true; - mContainer.setClickable(false); - mContainer.expand(); - ThemeFragment f = getCurrentFragment(); - f.expand(); - setAnimatingStateAndScheduleFinish(); - } - }); - - mSelector = (ComponentSelector) findViewById(R.id.component_selector); - mSelector.setOnOpenCloseListener(mOpenCloseListener); - - mService = (ThemeManager) getSystemService(Context.THEME_SERVICE); - getSupportLoaderManager().restartLoader(LOADER_ID_APPLIED, null, this); - - mSaveApplyLayout = findViewById(R.id.save_apply_layout); - if (!Utils.hasNavigationBar(this)) { - mSaveApplyLayout.findViewById(R.id.navbar_padding).setVisibility(View.GONE); - } - mSaveApplyLayout.findViewById(R.id.save_apply_button).setOnClickListener( - new View.OnClickListener() { - @Override - public void onClick(View v) { - if (mIsAnimating) return; - hideSaveApplyButton(); - mExpanded = false; - mContainer.setClickable(false); - final ThemeFragment f = getCurrentFragment(); - f.fadeOutCards(new Runnable() { - public void run() { - mContainer.collapse(); - f.collapse(true); - } - }); - setAnimatingStateAndScheduleFinish(); - } - }); - mTypefaceHelperCache = TypefaceHelperCache.getInstance(); - mHandler = new Handler(); - } - - public void hideSaveApplyButton() { - Animation anim = AnimationUtils.loadAnimation(this, R.anim.component_selection_animate_out); - mSaveApplyLayout.startAnimation(anim); - anim.setAnimationListener(new Animation.AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - } - - @Override - public void onAnimationEnd(Animation animation) { - mSaveApplyLayout.setVisibility(View.GONE); - } - - @Override - public void onAnimationRepeat(Animation animation) { - } - }); - } - - private void setAnimatingStateAndScheduleFinish() { - mIsAnimating = true; - mContainer.setIsAnimating(true); - mHandler.postDelayed(new Runnable() { - public void run() { - mIsAnimating = false; - mContainer.setIsAnimating(false); - } - }, ThemeFragment.ANIMATE_START_DELAY + ThemeFragment.ANIMATE_DURATION); - } - - /** - * Disable the ViewPager while a theme change is occuring - */ - public void themeChangeStarted() { - mPager.setEnabled(false); - } - - /** - * Re-enable the ViewPager and update the "My theme" fragment if available - */ - public void themeChangeEnded() { - if (mPager.getCurrentItem() != 0) { - ThemeFragment f; - if (mPager.getCurrentItem() <= OFFSCREEN_PAGE_LIMIT) { - // Clear the "My theme" card so it loads the newly applied changes - f = (ThemeFragment) mAdapter.instantiateItem(mPager, 0); - if (f != null) f.clearChanges(); - } - - // clear the current card so it returns to it's previous state - f = getCurrentFragment(); - if (f != null) f.clearChanges(); - mPager.postDelayed(new Runnable() { - @Override - public void run() { - mPager.setCurrentItem(0, true); - } - }, MOVE_TO_MY_THEME_DELAY); - } - mPager.setEnabled(true); - } - - public ComponentSelector getComponentSelector() { - return mSelector; - } - - public void showComponentSelector(String component, View v) { - if (component != null) { - final Resources res = getResources(); - int itemsPerPage = res.getInteger(R.integer.default_items_per_page); - int height = res.getDimensionPixelSize(R.dimen.component_selection_cell_height); - if (MODIFIES_BOOT_ANIM.equals(component)) { - itemsPerPage = res.getInteger(R.integer.bootani_items_per_page); - height = res.getDimensionPixelSize( - R.dimen.component_selection_cell_height_boot_anim); - } else if (MODIFIES_ALARMS.equals(component) || - MODIFIES_NOTIFICATIONS.equals(component) || - MODIFIES_RINGTONES.equals(component)) { - itemsPerPage = 2; - height = res.getDimensionPixelSize( - R.dimen.component_selection_cell_height_sounds); - } - if (mSaveApplyLayout.getVisibility() == View.VISIBLE) hideSaveApplyButton(); - mSelector.show(component, itemsPerPage, height); - - // determine if we need to shift the cards up - int[] coordinates = new int[2]; - v.getLocationOnScreen(coordinates); - coordinates[1] += v.getHeight(); - int top = getWindowManager().getDefaultDisplay().getHeight() - height; - if (coordinates[1] > top) { - slideContentUp(top - coordinates[1]); - } - } - } - - private void slideContentUp(int yDelta) { - yDelta -= getResources().getDimensionPixelSize(R.dimen.content_offset_padding); - mContainerYOffset = yDelta; - mContainer.animate().translationYBy(yDelta).setDuration(SLIDE_CONTENT_ANIM_DURATION); - } - - private void slideContentDown(final int yDelta) { - mContainer.animate().translationYBy(-yDelta).setDuration(SLIDE_CONTENT_ANIM_DURATION); - } - - @Override - protected void onResume() { - super.onResume(); - mService.onClientResumed(this); - getSupportLoaderManager().restartLoader(LOADER_ID_APPLIED, null, this); - } - - @Override - public void onBackPressed() { - if (mSelector.isEnabled()) { - mSelector.hide(); - if (mContainerYOffset != 0) { - slideContentDown(mContainerYOffset); - mContainerYOffset = 0; - } - final ThemeFragment f = getCurrentFragment(); - f.fadeInCards(); - } else if (mExpanded) { - if (mIsAnimating) { - return; - } - - if (mSaveApplyLayout.getVisibility() == View.VISIBLE) { - hideSaveApplyButton(); - getCurrentFragment().clearChanges(); - } - mExpanded = false; - final ThemeFragment f = getCurrentFragment(); - f.fadeOutCards(new Runnable() { - public void run() { - mContainer.collapse(); - f.collapse(false); - } - }); - setAnimatingStateAndScheduleFinish(); - } else { - super.onBackPressed(); - } - } - - @Override - public void onPause() { - super.onPause(); - mService.onClientPaused(this); - } - - @Override - public void onDestroy() { - super.onDestroy(); - mService.onClientDestroyed(this); - } - - @Override - protected void onStart() { - super.onStart(); - if (mTypefaceHelperCache.getTypefaceCount() <= 0) { - new TypefacePreloadTask().execute(); - } - } - - private View.OnClickListener mPagerClickListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - if (!mExpanded && !mIsAnimating) { - mExpanded = true; - mContainer.setClickable(false); - mContainer.expand(); - ThemeFragment f = getCurrentFragment(); - f.expand(); - setAnimatingStateAndScheduleFinish(); - } - } - }; - - private OnOpenCloseListener mOpenCloseListener = new OnOpenCloseListener() { - @Override - public void onSelectorOpened() { - } - - @Override - public void onSelectorClosed() { - ThemeFragment f = getCurrentFragment(); - if (f.componentsChanged()) { - mSaveApplyLayout.setVisibility(View.VISIBLE); - mSaveApplyLayout.startAnimation(AnimationUtils.loadAnimation(ChooserActivity.this, - R.anim.component_selection_animate_in)); - } - } - }; - - private ThemeFragment getCurrentFragment() { - // instantiateItem will return the fragment if it already exists and not instantiate it, - // which should be the case for the current fragment. - return (ThemeFragment) mAdapter.instantiateItem(mPager, mPager.getCurrentItem()); - } - - private void populateCurrentTheme(Cursor c) { - c.moveToPosition(-1); - while(c.moveToNext()) { - int mixkeyIdx = c.getColumnIndex(ThemesContract.MixnMatchColumns.COL_KEY); - int pkgIdx = c.getColumnIndex(ThemesContract.MixnMatchColumns.COL_VALUE); - String mixkey = c.getString(mixkeyIdx); - String component = ThemesContract.MixnMatchColumns.mixNMatchKeyToComponent(mixkey); - String pkg = c.getString(pkgIdx); - mCurrentTheme.put(component, pkg); - } - } - - @Override - public void onLoadFinished(Loader<Cursor> loader, Cursor data) { - switch (loader.getId()) { - case LOADER_ID_INSTALLED_THEMES: - // Swap the new cursor in. (The framework will take care of closing the - // old cursor once we return.) - mAdapter.swapCursor(data); - mAdapter.notifyDataSetChanged(); - break; - case LOADER_ID_APPLIED: - getSupportLoaderManager().restartLoader(LOADER_ID_INSTALLED_THEMES, null, this); - populateCurrentTheme(data); - break; - } - } - - @Override - public void onLoaderReset(Loader<Cursor> loader) { - switch (loader.getId()) { - case LOADER_ID_INSTALLED_THEMES: - mAdapter.swapCursor(null); - mAdapter.notifyDataSetChanged(); - break; - } - } - - @Override - public Loader<Cursor> onCreateLoader(int id, Bundle args) { - String selection = null; - String selectionArgs[] = null; - String sortOrder = null; - Uri contentUri = null; - - switch (id) { - case LOADER_ID_INSTALLED_THEMES: - selection = ThemesColumns.PRESENT_AS_THEME + "=?"; - selectionArgs = new String[] { "1" }; - // sort in ascending order but make sure the "default" theme is always first - sortOrder = "(" + ThemesColumns.IS_DEFAULT_THEME + "=1) DESC, " - + ThemesColumns.TITLE + " ASC"; - contentUri = ThemesColumns.CONTENT_URI; - break; - case LOADER_ID_APPLIED: - //TODO: Mix n match query should only be done once - contentUri = ThemesContract.MixnMatchColumns.CONTENT_URI; - selection = null; - selectionArgs = null; - break; - } - - - return new CursorLoader(this, contentUri, null, selection, - selectionArgs, sortOrder); - } - - @Override - public void onProgress(int progress) { - - } - - @Override - public void onFinish(boolean isSuccess) { - - } - - public class ThemesAdapter extends FragmentStatePagerAdapter { - private Cursor mCursor; - private Context mContext; - - public ThemesAdapter(Context context) { - super(getSupportFragmentManager()); - mContext = context; - } - - @Override - public Fragment getItem(int position) { - String pkgName; - if (position == 0) { - pkgName = ThemeFragment.CURRENTLY_APPLIED_THEME; - } else { - mCursor.moveToPosition(position - 1); - int pkgIdx = mCursor.getColumnIndex(ThemesColumns.PKG_NAME); - pkgName = mCursor.getString(pkgIdx); - } - ThemeFragment f = ThemeFragment.newInstance(pkgName); - f.setCurrentTheme(mCurrentTheme); - return f; - } - - @Override - public int getItemPosition(Object object) { - ThemeFragment fragment = (ThemeFragment) object; - if (fragment.isUninstalled()) { - return POSITION_NONE; - } - return super.getItemPosition(object); - } - - /** - * The first card should be the user's currently applied theme components so we - * will always return at least 1 or mCursor.getCount() + 1 - * @return - */ - public int getCount() { - return mCursor == null ? 1 : mCursor.getCount() + 1; - } - - public void swapCursor(Cursor c) { - mCursor = c; - } - } - - private class TypefacePreloadTask extends AsyncTask { - - @Override - protected Object doInBackground(Object[] params) { - String[] projection = { ThemesColumns.PKG_NAME }; - String selection = ThemesColumns.MODIFIES_FONTS + "=?"; - String[] selectionArgs = { "1" }; - Cursor c = getContentResolver().query(ThemesColumns.CONTENT_URI, projection, selection, - selectionArgs, null); - if (c != null) { - while (c.moveToNext()) { - mTypefaceHelperCache.getHelperForTheme(ChooserActivity.this, c.getString(0)); - } - c.close(); - } - return null; - } - } -} diff --git a/src/org/cyanogenmod/theme/chooserv2/ComponentCardView.java b/src/org/cyanogenmod/theme/chooserv2/ComponentCardView.java deleted file mode 100644 index 5e24c95..0000000 --- a/src/org/cyanogenmod/theme/chooserv2/ComponentCardView.java +++ /dev/null @@ -1,204 +0,0 @@ -package org.cyanogenmod.theme.chooserv2; - -import android.animation.Animator; -import android.animation.AnimatorSet; -import android.animation.IntEvaluator; -import android.animation.ObjectAnimator; -import android.animation.ValueAnimator; -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.TransitionDrawable; -import android.util.AttributeSet; -import android.view.View; -import android.view.ViewOverlay; -import android.widget.LinearLayout; -import android.widget.TextView; - -import org.cyanogenmod.theme.chooser.R; - -public class ComponentCardView extends LinearLayout { - public static final int CARD_FADE_DURATION = 300; - - private static final float SEMI_OPAQUE_ALPHA = 0.2f; - private static final int BACKGROUND_SEMI_OPAQUE_ALPHA = (int) (256.0f * SEMI_OPAQUE_ALPHA); - - protected TextView mLabel; - - // Expanded Padding - int mExpandPadLeft; - int mExpandPadTop; - int mExpandPadRight; - int mExpandPadBottom; - - public ComponentCardView(Context context) { - this(context, null); - } - - public ComponentCardView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public ComponentCardView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - @Override - protected void onFinishInflate() { - mLabel = (TextView) findViewById(R.id.label); - - Resources r = getContext().getResources(); - mExpandPadLeft = - (int) r.getDimension(R.dimen.card_padding_left_right) + getPaddingLeft(); - mExpandPadTop = - (int) r.getDimension(R.dimen.card_padding_top) + getPaddingTop(); - mExpandPadRight = - (int) r.getDimension(R.dimen.card_padding_left_right) + getPaddingRight(); - mExpandPadBottom = - (int) r.getDimension(R.dimen.card_padding_bottom) + getPaddingBottom(); - } - - public void expand(boolean showLabel) { - TransitionDrawable bg = null; - if (getBackground() instanceof TransitionDrawable) { - bg = (TransitionDrawable) getBackground(); - } - if (bg != null) { - Rect paddingRect = new Rect(); - bg.getPadding(paddingRect); - } - - setPadding(mExpandPadLeft, mExpandPadTop, mExpandPadRight, mExpandPadBottom); - - if (mLabel != null) { - mLabel.setAlpha(showLabel ? 1f : 0f); - mLabel.setVisibility(View.VISIBLE); - } - } - - public void animateExpand() { - if (getBackground() instanceof TransitionDrawable) { - TransitionDrawable background = (TransitionDrawable) getBackground(); - if (mLabel != null) { - mLabel.setVisibility(View.VISIBLE); - mLabel.setAlpha(0f); - mLabel.animate().alpha(1f).setDuration(CARD_FADE_DURATION).start(); - } - background.startTransition(CARD_FADE_DURATION); - } - } - - public void collapse() { - if (mLabel != null) { - mLabel.setVisibility(View.GONE); - } - setPadding(0, 0, 0, 0); - } - - public void animateFadeOut() { - if (mLabel != null) { - mLabel.animate().alpha(0f).setDuration(CARD_FADE_DURATION); - } - - if (getBackground() instanceof TransitionDrawable) { - TransitionDrawable background = (TransitionDrawable) getBackground(); - background.reverseTransition(CARD_FADE_DURATION); - } - } - - /** - * Animates the card background and the title to 20% opacity. - */ - public void animateCardFadeOut() { - if (mLabel != null) { - mLabel.animate().alpha(SEMI_OPAQUE_ALPHA).setDuration(CARD_FADE_DURATION); - } - final ValueAnimator bgAlphaAnimator = ValueAnimator.ofObject(new IntEvaluator(), 255, - BACKGROUND_SEMI_OPAQUE_ALPHA); - bgAlphaAnimator.setDuration(CARD_FADE_DURATION); - bgAlphaAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - getBackground().setAlpha((Integer) animation.getAnimatedValue()); - } - }); - bgAlphaAnimator.start(); - } - - /** - * Animates the card background and the title back to full opacity. - */ - public void animateCardFadeIn() { - if (getBackground().getAlpha() > 51) return; - if (mLabel != null) { - mLabel.animate().alpha(1f).setDuration(CARD_FADE_DURATION); - } - final ValueAnimator bgAlphaAnimator = ValueAnimator.ofObject(new IntEvaluator(), - BACKGROUND_SEMI_OPAQUE_ALPHA, 255); - bgAlphaAnimator.setDuration(CARD_FADE_DURATION); - bgAlphaAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - getBackground().setAlpha((Integer) animation.getAnimatedValue()); - } - }); - bgAlphaAnimator.start(); - } - - /** - * Animates a change in the content of the card - * @param v View in card to animate - * @param overlay Drawable to animate as a ViewOverlay - * @param duration Duration of animation - */ - public void animateContentChange(View v, final Drawable overlay, long duration) { - final ViewOverlay viewOverlay = this.getOverlay(); - viewOverlay.add(overlay); - final int x = (int) v.getX(); - final int y = (int) v.getY(); - final int width = v.getWidth(); - final int height = v.getHeight(); - overlay.setBounds(x, y, x + v.getWidth(), y + v.getHeight()); - - final ValueAnimator overlayAnimator = ValueAnimator.ofFloat(1f, 0f); - overlayAnimator.setDuration(duration); - overlayAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float value = (Float) animation.getAnimatedValue(); - overlay.setAlpha((int) (255 * value)); - int newWidth = (int) (value * width); - int newHeight = (int) (value * height); - int dw = (width - newWidth) / 2; - int dh = (height - newHeight) / 2; - overlay.setBounds(x + dw, y + dh, x + dw + newWidth, y + dh + newHeight); - } - }); - overlayAnimator.addListener(new Animator.AnimatorListener() { - @Override - public void onAnimationStart(Animator animation) {} - - @Override - public void onAnimationEnd(Animator animation) { - // Clear out the ViewOverlay now that we are done animating - viewOverlay.clear(); - } - - @Override - public void onAnimationCancel(Animator animation) {} - - @Override - public void onAnimationRepeat(Animator animation) {} - }); - - AnimatorSet set = new AnimatorSet(); - set.play(ObjectAnimator.ofFloat(v, "alpha", 0f, 1f)) - .with(ObjectAnimator.ofFloat(v, "scaleX", 0f, 1f)) - .with(ObjectAnimator.ofFloat(v, "scaleY", 0f, 1f)); - set.setDuration(duration); - - set.start(); - overlayAnimator.start(); - } -} diff --git a/src/org/cyanogenmod/theme/chooserv2/ComponentSelector.java b/src/org/cyanogenmod/theme/chooserv2/ComponentSelector.java deleted file mode 100644 index 0985c9b..0000000 --- a/src/org/cyanogenmod/theme/chooserv2/ComponentSelector.java +++ /dev/null @@ -1,769 +0,0 @@ -/* - * Copyright (C) 2014 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.chooserv2; - -import android.content.Context; -import android.content.pm.PackageManager; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.database.Cursor; -import android.graphics.Rect; -import android.graphics.Typeface; -import android.graphics.drawable.BitmapDrawable; -import android.media.MediaPlayer; -import android.media.RingtoneManager; -import android.os.Bundle; -import android.provider.Settings; -import android.provider.ThemesContract; -import android.provider.ThemesContract.MixnMatchColumns; -import android.provider.ThemesContract.PreviewColumns; -import android.provider.ThemesContract.ThemesColumns; -import android.support.v4.app.FragmentActivity; -import android.support.v4.app.LoaderManager; -import android.support.v4.content.CursorLoader; -import android.support.v4.content.Loader; -import android.support.v4.view.PagerAdapter; -import android.support.v4.view.ViewPager; -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.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; -import android.widget.Toast; - -import com.viewpagerindicator.PageIndicator; -import org.cyanogenmod.theme.chooser.R; -import org.cyanogenmod.theme.util.AudioUtils; -import org.cyanogenmod.theme.util.ThemedTypefaceHelper; -import org.cyanogenmod.theme.util.TypefaceHelperCache; -import org.cyanogenmod.theme.util.Utils; - -import java.util.HashMap; - -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_ALARMS; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_BOOT_ANIM; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_LAUNCHER; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_LOCKSCREEN; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_NOTIFICATIONS; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_OVERLAYS; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_RINGTONES; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_STATUS_BAR; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_NAVIGATION_BAR; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_ICONS; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_FONTS; - -public class ComponentSelector extends LinearLayout - implements LoaderManager.LoaderCallbacks<Cursor> { - private static final String TAG = ComponentSelector.class.getSimpleName(); - - public static final boolean DEBUG_SELECTOR = false; - - private static final int LOADER_ID_STATUS_BAR = 100; - private static final int LOADER_ID_NAVIGATION_BAR = 101; - private static final int LOADER_ID_FONT = 102; - private static final int LOADER_ID_ICON = 103; - private static final int LOADER_ID_STYLE = 104; - private static final int LOADER_ID_WALLPAPER = 105; - private static final int LOADER_ID_BOOTANIMATIONS = 106; - private static final int LOADER_ID_RINGTONE = 107; - private static final int LOADER_ID_NOTIFICATION = 108; - private static final int LOADER_ID_ALARM = 109; - private static final int LOADER_ID_LOCKSCREEN = 110; - - private Context mContext; - private LayoutInflater mInflater; - private ViewPager mPager; - - private String mComponentType; - private CursorPagerAdapter mAdapter; - private int mBatteryStyle; - private int mItemsPerPage; - private String mAppliedComponentPkgName; - - // 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; - - 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); - mBatteryStyle = Settings.System.getInt(context.getContentResolver(), - Settings.System.STATUS_BAR_BATTERY, 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) { - } - - @Override - public void onAnimationEnd(Animation animation) { - setVisibility(View.GONE); - if (mOpenCloseListener != null) mOpenCloseListener.onSelectorClosed(); - } - - @Override - public void onAnimationRepeat(Animation animation) { - } - }); - mMediaPlayer = new MediaPlayer(); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - mPager = (ViewPager) findViewById(R.id.pager); - mAdapter = new CursorPagerAdapter<View>(null, mItemsPerPage); - mPager.setAdapter(mAdapter); - PageIndicator indicator = (PageIndicator) findViewById(R.id.page_indicator); - indicator.setViewPager(mPager); - - // set navbar_padding to GONE if no on screen navigation bar is available - if (!Utils.hasNavigationBar(mContext)) { - findViewById(R.id.navbar_padding).setVisibility(View.GONE); - } - setEnabled(false); - } - - public void setComponentType(String component) { - // Find out which theme is currently applied for this component - String selection = MixnMatchColumns.COL_KEY + "=?"; - String[] selectionArgs = {MixnMatchColumns.componentToMixNMatchKey(component)}; - Cursor c = mContext.getContentResolver().query(MixnMatchColumns.CONTENT_URI, - null, selection, selectionArgs, null); - if (c != null) { - if (c.moveToFirst()) { - mAppliedComponentPkgName = c.getString( - c.getColumnIndex(MixnMatchColumns.COL_VALUE)); - } - c.close(); - } else { - mAppliedComponentPkgName = null; - } - if (mComponentType == null || !mComponentType.equals(component)){ - mAdapter.swapCursor(null); - } - mComponentType = component; - ((FragmentActivity) mContext).getSupportLoaderManager().restartLoader( - getLoaderIdFromComponent(component), null, this); - } - - public String getComponentType() { - return mComponentType; - } - - public void setNumItemsPerPage(int itemsPerPage) { - if (mItemsPerPage != itemsPerPage) { - mItemsPerPage = itemsPerPage; - mAdapter.setNumItemsPerPage(mItemsPerPage); - } - } - - public void setHeight(int height) { - ViewGroup.LayoutParams params = mPager.getLayoutParams(); - if (params.height != height) { - params.height = height; - mPager.setLayoutParams(params); - requestLayout(); - } - } - - public void show(String componentType, int itemsPerPage, int height) { - setNumItemsPerPage(itemsPerPage); - setHeight(height); - setComponentType(componentType); - 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_ICON; - } - 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_BOOTANIMATIONS; - } - 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) { - String selection; - String[] selectionArgs = { "1" }; - String[] projection = { ThemesColumns.TITLE, ThemesColumns.PKG_NAME }; - switch(id) { - case LOADER_ID_STATUS_BAR: - selection = MODIFIES_STATUS_BAR + "=?"; - projection = new String[] { - PreviewColumns.STATUSBAR_WIFI_ICON, - PreviewColumns.STATUSBAR_SIGNAL_ICON, - PreviewColumns.STATUSBAR_BLUETOOTH_ICON, - PreviewColumns.STATUSBAR_BACKGROUND, - PreviewColumns.STATUSBAR_BATTERY_CIRCLE, - PreviewColumns.STATUSBAR_BATTERY_LANDSCAPE, - PreviewColumns.STATUSBAR_BATTERY_PORTRAIT, - ThemesColumns.TITLE, - ThemesColumns.PKG_NAME - }; - break; - case LOADER_ID_NAVIGATION_BAR: - selection = MODIFIES_NAVIGATION_BAR + "=?"; - projection = new String[] { - PreviewColumns.NAVBAR_BACK_BUTTON, - PreviewColumns.STATUSBAR_BACKGROUND, - ThemesColumns.TITLE, - ThemesColumns.PKG_NAME, - }; - break; - case LOADER_ID_FONT: - selection = MODIFIES_FONTS + "=?"; - break; - case LOADER_ID_ICON: - selection = MODIFIES_ICONS + "=?"; - projection = new String[] { - PreviewColumns.ICON_PREVIEW_1, - ThemesColumns.TITLE, - ThemesColumns.PKG_NAME - }; - break; - case LOADER_ID_STYLE: - selection = MODIFIES_OVERLAYS + "=?"; - projection = new String[] { - PreviewColumns.STYLE_THUMBNAIL, - ThemesColumns.TITLE, - ThemesColumns.PKG_NAME - }; - break; - case LOADER_ID_WALLPAPER: - selection = MODIFIES_LAUNCHER + "=?"; - projection = new String[] { - PreviewColumns.WALLPAPER_THUMBNAIL, - ThemesColumns.TITLE, - ThemesColumns.PKG_NAME - }; - break; - case LOADER_ID_BOOTANIMATIONS: - selection = MODIFIES_BOOT_ANIM + "=?"; - projection = new String[] { - PreviewColumns.BOOTANIMATION_THUMBNAIL, - ThemesColumns.TITLE, - ThemesColumns.PKG_NAME - }; - break; - case LOADER_ID_RINGTONE: - selection = MODIFIES_RINGTONES + "=?"; - break; - case LOADER_ID_NOTIFICATION: - selection = MODIFIES_NOTIFICATIONS + "=?"; - break; - case LOADER_ID_ALARM: - selection = MODIFIES_ALARMS + "=?"; - break; - case LOADER_ID_LOCKSCREEN: - selection = MODIFIES_LOCKSCREEN + "=?"; - projection = new String[] { - PreviewColumns.LOCK_WALLPAPER_THUMBNAIL, - ThemesColumns.TITLE, - ThemesColumns.PKG_NAME - }; - break; - default: - return null; - } - // sort in ascending order but make sure the "default" theme is always first - String sortOrder = "(" + ThemesContract.ThemesColumns.IS_DEFAULT_THEME + "=1) DESC, " - + ThemesContract.ThemesColumns.TITLE + " ASC"; - return new CursorLoader(mContext, PreviewColumns.CONTENT_URI, - projection, selection, selectionArgs, sortOrder); - } - - @Override - public void onLoadFinished(Loader<Cursor> loader, final Cursor data) { - mAdapter.swapCursor(data); - } - - @Override - public void onLoaderReset(Loader<Cursor> loader) { - mAdapter.swapCursor(null); - } - - public void setOnItemClickedListener(OnItemClickedListener listener) { - mListener = listener; - } - - public void setOnOpenCloseListener(OnOpenCloseListener listener) { - mOpenCloseListener = listener; - } - - public class CursorPagerAdapter<T extends View> extends PagerAdapter { - LinearLayout.LayoutParams mItemParams = - new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f); - LinearLayout.LayoutParams mSoundItemParams = - new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0, 1.0f); - private Cursor mCursor; - private int mItemsPerPage; - private TypefaceHelperCache mTypefaceCache; - - public CursorPagerAdapter(Cursor cursor, int itemsPerPage) { - super(); - mCursor = cursor; - mItemsPerPage = itemsPerPage; - mTypefaceCache = TypefaceHelperCache.getInstance(); - } - - public void setNumItemsPerPage(int itemsPerPage) { - mItemsPerPage = itemsPerPage; - } - - @Override - public Object instantiateItem(ViewGroup container, int position) { - ViewGroup v = (ViewGroup) mInflater.inflate(R.layout.component_selection_pager_item, - container, false); - if (v instanceof LinearLayout) { - ((LinearLayout) v).setWeightSum(mItemsPerPage); - } - if (MODIFIES_STATUS_BAR.equals(mComponentType)) { - newStatusBarView(mCursor, v, position); - } - if (MODIFIES_NAVIGATION_BAR.equals(mComponentType)) { - newNavBarView(mCursor, v, position); - } - if (MODIFIES_FONTS.equals(mComponentType)) { - newFontView(mCursor, v, position); - } - if (MODIFIES_ICONS.equals(mComponentType)) { - newIconView(mCursor, v, position); - } - if (MODIFIES_OVERLAYS.equals(mComponentType)) { - newStyleView(mCursor, v, position); - } - if (MODIFIES_LAUNCHER.equals(mComponentType)) { - newWallpapersView(mCursor, v, position); - } - if (MODIFIES_BOOT_ANIM.equals(mComponentType)) { - newBootanimationView(mCursor, v, position); - } - if (MODIFIES_RINGTONES.equals(mComponentType) || - MODIFIES_NOTIFICATIONS.equals(mComponentType) || - MODIFIES_ALARMS.equals(mComponentType)) { - v = (ViewGroup) mInflater.inflate(R.layout.component_selection_sounds_pager_item, - container, false); - if (v instanceof LinearLayout) { - ((LinearLayout) v).setWeightSum(mItemsPerPage); - } - newSoundView(mCursor, v, position, mComponentType); - } - if (MODIFIES_LOCKSCREEN.equals(mComponentType)) { - newLockScreenView(mCursor, v, position); - } - container.addView(v); - return v; - } - - @Override - public void destroyItem(ViewGroup container, int position, Object object) { - if (object instanceof View) { - container.removeView((View) object); - } - } - - @Override - public int getCount() { - return mCursor == null ? 0 : (int) Math.ceil((float)mCursor.getCount() / mItemsPerPage); - } - - @Override - public boolean isViewFromObject(View view, Object object) { - return view == object; - } - - @Override - public int getItemPosition(Object object) { - return POSITION_NONE; - } - - public void swapCursor(Cursor c) { - mCursor = c; - notifyDataSetChanged(); - mPager.setCurrentItem(0, false); - } - - public Cursor getCursor() { - return mCursor; - } - - private OnClickListener mItemClickListener = new OnClickListener() { - @Override - public void onClick(View v) { - String pkgName = (String) v.getTag(); - if (DEBUG_SELECTOR) Toast.makeText(mContext, pkgName, Toast.LENGTH_SHORT).show(); - if (mListener != null) { - mListener.onItemClicked(pkgName); - } - } - }; - - private void newStatusBarView(Cursor cursor, ViewGroup parent, int position) { - 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.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(cursor.getString(pkgNameIndex)); - v.setOnClickListener(mItemClickListener); - parent.addView(v, mItemParams); - addDividerIfNeeded(parent, i, index, cursor); - } - } - - private void newNavBarView(Cursor cursor, ViewGroup parent, int position) { - 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.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(cursor.getString(pkgNameIndex)); - v.setOnClickListener(mItemClickListener); - parent.addView(v, mItemParams); - addDividerIfNeeded(parent, i, index, cursor); - } - } - - private void newFontView(Cursor cursor, ViewGroup parent, int position) { - 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.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(cursor.getString(pkgNameIndex)); - v.setOnClickListener(mItemClickListener); - parent.addView(v, mItemParams); - addDividerIfNeeded(parent, i, index, cursor); - } - } - - private void newIconView(Cursor cursor, ViewGroup parent, int position) { - 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.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(cursor.getString(pkgNameIndex)); - v.setOnClickListener(mItemClickListener); - parent.addView(v, mItemParams); - addDividerIfNeeded(parent, i, index, cursor); - } - } - - private void newStyleView(Cursor cursor, ViewGroup parent, int position) { - 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.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(cursor.getString(pkgNameIndex)); - v.setOnClickListener(mItemClickListener); - parent.addView(v, mItemParams); - addDividerIfNeeded(parent, i, index, cursor); - } - } - - private void newWallpapersView(Cursor cursor, ViewGroup parent, int position) { - 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.wallpaper_component_selection_item, parent, - false); - int wallpaperIndex = cursor.getColumnIndex(PreviewColumns.WALLPAPER_THUMBNAIL); - int pkgNameIndex = cursor.getColumnIndex(ThemesContract.ThemesColumns.PKG_NAME); - - ((ImageView) v.findViewById(R.id.icon)).setImageBitmap( - Utils.loadBitmapBlob(cursor, wallpaperIndex)); - setTitle(((TextView) v.findViewById(R.id.title)), cursor); - v.setTag(cursor.getString(pkgNameIndex)); - v.setOnClickListener(mItemClickListener); - parent.addView(v, mItemParams); - addDividerIfNeeded(parent, i, index, cursor); - } - } - - private void newLockScreenView(Cursor cursor, ViewGroup parent, int position) { - 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.wallpaper_component_selection_item, parent, - false); - int wallpaperIndex = cursor.getColumnIndex(PreviewColumns.LOCK_WALLPAPER_THUMBNAIL); - int pkgNameIndex = cursor.getColumnIndex(ThemesContract.ThemesColumns.PKG_NAME); - - ((ImageView) v.findViewById(R.id.icon)).setImageBitmap( - Utils.loadBitmapBlob(cursor, wallpaperIndex)); - setTitle(((TextView) v.findViewById(R.id.title)), cursor); - v.setTag(cursor.getString(pkgNameIndex)); - v.setOnClickListener(mItemClickListener); - parent.addView(v, mItemParams); - addDividerIfNeeded(parent, i, index, cursor); - } - } - - private void newBootanimationView(Cursor cursor, ViewGroup parent, int position) { - 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.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(cursor.getString(pkgNameIndex)); - v.setOnClickListener(mItemClickListener); - parent.addView(v, mItemParams); - addDividerIfNeeded(parent, i, index, cursor); - } - } - - private void newSoundView(Cursor cursor, ViewGroup parent, int position, String component) { - 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(cursor.getString(pkgNameIndex)); - v.setOnClickListener(mItemClickListener); - parent.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 (mComponentType.equals(MODIFIES_RINGTONES)) { - type = RingtoneManager.TYPE_RINGTONE; - } else if (mComponentType.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); - } - } - }); - } - } - - private void addDivider(ViewGroup parent) { - final Resources res = getResources(); - View v = mInflater.inflate(R.layout.component_divider, parent, false); - LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) v.getLayoutParams(); - // Boot animations require a taller divider so adjust accordingly - if (ThemesColumns.MODIFIES_BOOT_ANIM.equals(mComponentType)) { - params.topMargin = res.getDimensionPixelSize( - R.dimen.component_divider_margin_top_bootani); - params.height = res.getDimensionPixelSize(R.dimen.component_divider_height_bootani); - } - v.setLayoutParams(params); - parent.addView(v); - } - - private void addDividerIfNeeded(ViewGroup parent, int position, int cursorIndex, - Cursor cursor) { - if (position < mItemsPerPage - 1 && cursorIndex < cursor.getCount() - 1) { - addDivider(parent); - } - } - - private void setTitle(TextView titleView, Cursor cursor) { - String pkgName = cursor.getString(cursor.getColumnIndex(ThemesColumns.PKG_NAME)); - titleView.setText(cursor.getString(cursor.getColumnIndex(ThemesColumns.TITLE))); - if (pkgName.equals(mAppliedComponentPkgName)) { - titleView.setTextColor(getResources().getColor( - R.color.component_selection_current_text_color)); - } - } - } - - public interface OnItemClickedListener { - public void onItemClicked(String pkgName); - } - - public interface OnOpenCloseListener { - public void onSelectorOpened(); - public void onSelectorClosed(); - } -}
\ No newline at end of file diff --git a/src/org/cyanogenmod/theme/chooserv2/IconTransitionDrawable.java b/src/org/cyanogenmod/theme/chooserv2/IconTransitionDrawable.java deleted file mode 100644 index c0138a1..0000000 --- a/src/org/cyanogenmod/theme/chooserv2/IconTransitionDrawable.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * Copyright (C) 2014 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.chooserv2; - -import android.graphics.Canvas; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.LayerDrawable; -import android.os.SystemClock; - -/** - * An extension of LayerDrawables that is intended to cross-fade between - * the first and second layer. To start the transition, call {@link #startTransition(int)}. To - * display just the first layer, call {@link #resetTransition()}. - * <p> - * It can be defined in an XML file with the <code><transition></code> element. - * Each Drawable in the transition is defined in a nested <code><item></code>. For more - * information, see the guide to <a - * href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.</p> - * - * @attr ref android.R.styleable#LayerDrawableItem_left - * @attr ref android.R.styleable#LayerDrawableItem_top - * @attr ref android.R.styleable#LayerDrawableItem_right - * @attr ref android.R.styleable#LayerDrawableItem_bottom - * @attr ref android.R.styleable#LayerDrawableItem_drawable - * @attr ref android.R.styleable#LayerDrawableItem_id - * - */ -public class IconTransitionDrawable extends LayerDrawable { - - /** - * A transition is about to start. - */ - private static final int TRANSITION_STARTING = 0; - - /** - * The transition has started and the animation is in progress - */ - private static final int TRANSITION_RUNNING = 1; - - /** - * No transition will be applied - */ - private static final int TRANSITION_NONE = 2; - - /** - * The current state of the transition. One of {@link #TRANSITION_STARTING}, - * {@link #TRANSITION_RUNNING} and {@link #TRANSITION_NONE} - */ - private int mTransitionState = TRANSITION_NONE; - - private long mStartTimeMillis; - private int mFrom; - private int mTo; - private int mDuration; - private int mAlpha = 0; - private float mFromScale; - private float mToScale; - - /** - * Create a new transition drawable with the specified list of layers. At least - * 2 layers are required for this drawable to work properly. - */ - public IconTransitionDrawable(Drawable[] layers) { - super(layers); - } - - /** - * Begin the second layer on top of the first layer. - * - * @param durationMillis The length of the transition in milliseconds - */ - public void startTransition(int durationMillis) { - mFrom = 0; - mTo = 255; - mAlpha = 0; - mFromScale = 0f; - mToScale = 1.0f; - mDuration = durationMillis; - mTransitionState = TRANSITION_STARTING; - invalidateSelf(); - } - - /** - * Show only the first layer. - */ - public void resetTransition() { - mAlpha = 0; - mTransitionState = TRANSITION_NONE; - invalidateSelf(); - } - - @Override - public void draw(Canvas canvas) { - boolean done = true; - float scale = 0f; - - switch (mTransitionState) { - case TRANSITION_STARTING: - mStartTimeMillis = SystemClock.uptimeMillis(); - done = false; - mTransitionState = TRANSITION_RUNNING; - break; - - case TRANSITION_RUNNING: - if (mStartTimeMillis >= 0) { - float normalized = (float) - (SystemClock.uptimeMillis() - mStartTimeMillis) / mDuration; - done = normalized >= 1.0f; - normalized = Math.min(normalized, 1.0f); - mAlpha = (int) (mFrom + (mTo - mFrom) * normalized); - scale = mFromScale + (mToScale - mFromScale) * normalized; - } - break; - } - - final int alpha = mAlpha; - - if (done) { - // the setAlpha() calls below trigger invalidation and redraw. If we're done, just draw - // the appropriate drawable[s] and return - if (alpha == 0) { - getDrawable(0).draw(canvas); - } - if (alpha == 0xFF) { - getDrawable(1).draw(canvas); - - } - return; - } - - Drawable d; - d = getDrawable(0); - d.setAlpha(255 - alpha); - int cx = getIntrinsicWidth() / 2; - int cy = getIntrinsicHeight() / 2; - canvas.save(); - canvas.scale(1.0f - scale, 1.0f - scale, cx, cy); - d.draw(canvas); - canvas.restore(); - d.setAlpha(0xFF); - - if (alpha > 0) { - d = getDrawable(1); - d.setAlpha(alpha); - canvas.save(); - canvas.scale(scale, scale, cx, cy); - d.draw(canvas); - canvas.restore(); - d.setAlpha(0xFF); - } - - if (!done) { - invalidateSelf(); - } - } -} diff --git a/src/org/cyanogenmod/theme/chooserv2/PagerContainer.java b/src/org/cyanogenmod/theme/chooserv2/PagerContainer.java deleted file mode 100644 index a76b324..0000000 --- a/src/org/cyanogenmod/theme/chooserv2/PagerContainer.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2012 Wireless Designs, LLC - * Portions copyright (C) 2014, The CyanogenMod Project - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package org.cyanogenmod.theme.chooserv2; - -import android.content.Context; -import android.graphics.Point; -import android.support.v4.view.ThemeViewPager; -import android.support.v4.view.ViewPager; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewTreeObserver; -import android.view.animation.AccelerateInterpolator; -import android.view.animation.DecelerateInterpolator; -import android.widget.FrameLayout; -import android.widget.LinearLayout; - -/** - * PagerContainer: A layout that displays a ViewPager with its children that are outside - * the typical pager bounds. - */ -public class PagerContainer extends FrameLayout implements ViewPager.OnPageChangeListener { - private static final int ANIMATE_OUT_DURATION = 300; - private static final int ANIMATE_OUT_INTERPOLATE_FACTOR = 1; - private static final int ANIMATE_IN_DURATION = 300; - private static final int ANIMATE_IN_INTERPOLATE_FACTOR = 2; - - private ThemeViewPager mPager; - private Point mCenter = new Point(); - private Point mInitialTouch = new Point(); - private int mCollapsedHeight; - private boolean mIsAnimating = false; - - boolean mNeedsRedraw = false; - - public PagerContainer(Context context) { - this(context, null, 0); - } - - public PagerContainer(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public PagerContainer(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - mCollapsedHeight = generateLayoutParams(attrs).height; - - //Disable clipping of children so non-selected pages are visible - setClipChildren(false); - } - - @Override - protected void onFinishInflate() { - try { - mPager = (ThemeViewPager) getChildAt(0); - mPager.setOnPageChangeListener(this); - } catch (Exception e) { - throw new IllegalStateException("The root child of PagerContainer must be a ViewPager"); - } - } - - public ThemeViewPager getViewPager() { - return mPager; - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - mCenter.x = w / 2; - mCenter.y = h / 2; - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { - if (mIsAnimating) return true; - return super.onInterceptTouchEvent(ev); - } - - @Override - public boolean onTouchEvent(MotionEvent ev) { - // Do not allow touch events to propagate if we are animating - if (mIsAnimating) return true; - - //We capture any touches not already handled by the ViewPager - // to implement scrolling from a touch outside the pager bounds. - switch (ev.getAction()) { - case MotionEvent.ACTION_DOWN: - mInitialTouch.x = (int)ev.getX(); - mInitialTouch.y = (int)ev.getY(); - default: - ev.offsetLocation(mCenter.x - mInitialTouch.x, mCenter.y - mInitialTouch.y); - break; - } - - return mPager.dispatchTouchEvent(ev); - } - - @Override - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - //Force the container to redraw on scrolling. - //Without this the outer pages render initially and then stay static - if (mNeedsRedraw) invalidate(); - } - - @Override - public void onPageSelected(int position) { } - - @Override - public void onPageScrollStateChanged(int state) { - mNeedsRedraw = (state != ThemeViewPager.SCROLL_STATE_IDLE); - } - - public void setIsAnimating(boolean isAnimating) { - mIsAnimating = isAnimating; - } - - public void expand() { - LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(getLayoutParams()); - params.height = LinearLayout.LayoutParams.MATCH_PARENT; - setLayoutParams(params); - - mPager.setExpanded(true); - - final int current = mPager.getCurrentItem(); - final int prevY = (int) getY(); - - //Since our viewpager's width is changing to fill the screen - //we must start the left/right children of the current page inwards on first draw - final int lChildPrevXf; - final int rChildPrevXf; - - if (current != 0) { - final View lchild = mPager.getViewForPosition(current - 1); - lChildPrevXf = (int) lchild.getX(); - } else { - lChildPrevXf = 0; - } - - if (current < mPager.getAdapter().getCount() - 1) { - View rchild = mPager.getViewForPosition(current + 1); - rChildPrevXf = (int) rchild.getX(); - } else { - rChildPrevXf = 0; - } - - - final ViewTreeObserver observer = mPager.getViewTreeObserver(); - observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - public boolean onPreDraw() { - observer.removeOnPreDrawListener(this); - if (current != 0) { - View lchild = mPager.getViewForPosition(current - 1); - lchild.setTranslationY(prevY - getY()); - lchild.setX(lChildPrevXf); - animateChildOut(lchild, -getWidth()); - } - - if (current < mPager.getAdapter().getCount() - 1) { - View rchild = mPager.getViewForPosition(current + 1); - rchild.setX(rChildPrevXf); - rchild.setTranslationY(prevY - getY()); - animateChildOut(rchild, getWidth()); - } - return false; - } - }); - } - - public void collapse() { - LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(getLayoutParams()); - params.height = mCollapsedHeight; - setLayoutParams(params); - - mPager.setExpanded(false); - int current = mPager.getCurrentItem(); - final int prevY = (int) getY(); - - if (current != 0) { - View lchild = mPager.getViewForPosition(current - 1); - lchild.setTranslationY(0); - animateChildIn(lchild); - } - - if (current < mPager.getAdapter().getCount() - 1) { - View rchild = mPager.getViewForPosition(current + 1); - rchild.setTranslationY(0); - animateChildIn(rchild); - } - } - - private void animateChildOut(final View v, float endX) { - v.animate() - .translationX(endX) - .setDuration(ANIMATE_OUT_DURATION) - .setInterpolator(new AccelerateInterpolator(ANIMATE_OUT_INTERPOLATE_FACTOR)); - } - - private void animateChildIn(final View v) { - v.animate() - .translationX(0) - .setDuration(ANIMATE_IN_DURATION) - .setInterpolator(new DecelerateInterpolator(ANIMATE_IN_INTERPOLATE_FACTOR)); - } -}
\ No newline at end of file diff --git a/src/org/cyanogenmod/theme/chooserv2/ThemeFragment.java b/src/org/cyanogenmod/theme/chooserv2/ThemeFragment.java deleted file mode 100644 index df9cb03..0000000 --- a/src/org/cyanogenmod/theme/chooserv2/ThemeFragment.java +++ /dev/null @@ -1,1904 +0,0 @@ -/* - * Copyright (C) 2014 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.chooserv2; - -import android.animation.Animator; -import android.animation.AnimatorSet; -import android.animation.IntEvaluator; -import android.animation.ObjectAnimator; -import android.animation.ValueAnimator; -import android.app.WallpaperManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.ThemeUtils; -import android.content.res.AssetManager; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.content.res.ThemeConfig; -import android.content.res.ThemeManager; -import android.database.Cursor; -import android.graphics.Bitmap; -import android.graphics.Bitmap.Config; -import android.graphics.Point; -import android.graphics.Rect; -import android.graphics.Typeface; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.NinePatchDrawable; -import android.media.MediaPlayer; -import android.media.RingtoneManager; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Bundle; -import android.os.FileUtils; -import android.os.Handler; -import android.provider.Settings; -import android.provider.ThemesContract; -import android.provider.ThemesContract.PreviewColumns; -import android.provider.ThemesContract.ThemesColumns; -import android.support.v4.app.Fragment; -import android.support.v4.app.LoaderManager; -import android.support.v4.content.CursorLoader; -import android.support.v4.content.Loader; -import android.util.Log; -import android.util.SparseArray; -import android.view.Display; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewTreeObserver; -import android.view.animation.AccelerateInterpolator; -import android.view.animation.Animation; -import android.view.animation.DecelerateInterpolator; -import android.view.animation.ScaleAnimation; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.PopupMenu; -import android.widget.ProgressBar; -import android.widget.RelativeLayout; -import android.widget.ScrollView; -import android.widget.TextView; -import android.widget.Toast; - -import org.cyanogenmod.theme.chooser.R; -import org.cyanogenmod.theme.chooserv2.ComponentSelector.OnItemClickedListener; -import org.cyanogenmod.theme.util.AudioUtils; -import org.cyanogenmod.theme.util.BootAnimationHelper; -import org.cyanogenmod.theme.util.IconPreviewHelper; -import org.cyanogenmod.theme.util.ThemedTypefaceHelper; -import org.cyanogenmod.theme.util.TypefaceHelperCache; -import org.cyanogenmod.theme.util.Utils; -import org.cyanogenmod.theme.widget.BootAniImageView; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.zip.ZipFile; - -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_ALARMS; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_BOOT_ANIM; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_LAUNCHER; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_LOCKSCREEN; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_NOTIFICATIONS; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_OVERLAYS; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_RINGTONES; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_STATUS_BAR; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_NAVIGATION_BAR; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_ICONS; -import static android.provider.ThemesContract.ThemesColumns.MODIFIES_FONTS; - -public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>, - ThemeManager.ThemeChangeListener { - private static final String TAG = ThemeFragment.class.getSimpleName(); - - public static final int ANIMATE_START_DELAY = 200; - public static final int ANIMATE_DURATION = 300; - public static final int ANIMATE_INTERPOLATE_FACTOR = 3; - public static final int ANIMATE_COMPONENT_CHANGE_DURATION = 200; - public static final int ANIMATE_COMPONENT_ICON_DELAY = 50; - public static final int ANIMATE_PROGRESS_IN_DURATION = 500; - public static final int ANIMATE_TITLE_OUT_DURATION = 400; - public static final int ANIMATE_PROGRESS_OUT_DURATION = 400; - public static final int ANIMATE_TITLE_IN_DURATION = 500; - public static final int REQUEST_UNINSTALL = 1; // Request code - - private static final String NAVIGATION_BAR_BACKGROUND = "navbar_background"; - - public static final String CURRENTLY_APPLIED_THEME = "currently_applied_theme"; - - private static final ComponentName COMPONENT_DIALER = - new ComponentName("com.android.dialer", "com.android.dialer.DialtactsActivity"); - private static final ComponentName COMPONENT_MESSAGING = - new ComponentName("com.android.mms", "com.android.mms.ui.ConversationList"); - private static final ComponentName COMPONENT_CAMERANEXT = - new ComponentName("com.cyngn.cameranext", "com.android.camera.CameraLauncher"); - private static final ComponentName COMPONENT_CAMERA = - new ComponentName("com.android.camera2", "com.android.camera.CameraActivity"); - private static final ComponentName COMPONENT_BROWSER = - new ComponentName("com.android.browser", "com.android.browser.BrowserActivity"); - private static final ComponentName COMPONENT_SETTINGS = - new ComponentName("com.android.settings", "com.android.settings.Settings"); - private static final ComponentName COMPONENT_CALENDAR = - new ComponentName("com.android.calendar", "com.android.calendar.AllInOneActivity"); - private static final ComponentName COMPONENT_GALERY = - new ComponentName("com.android.gallery3d", "com.android.gallery3d.app.GalleryActivity"); - private static final String CAMERA_NEXT_PACKAGE = "com.cyngn.cameranext"; - - private static final int LOADER_ID_ALL = 0; - private static final int LOADER_ID_STATUS_BAR = 1; - private static final int LOADER_ID_FONT = 2; - private static final int LOADER_ID_ICONS = 3; - private static final int LOADER_ID_WALLPAPER = 4; - private static final int LOADER_ID_NAVIGATION_BAR = 5; - private static final int LOADER_ID_LOCKSCREEN = 6; - private static final int LOADER_ID_STYLE = 7; - private static final int LOADER_ID_BOOT_ANIMATION = 8; - private static final int LOADER_ID_RINGTONE = 9; - private static final int LOADER_ID_NOTIFICATION = 10; - private static final int LOADER_ID_ALARM = 11; - - private static ComponentName[] sIconComponents; - - private static TypefaceHelperCache sTypefaceHelperCache; - - /** - * Maps the card's resource ID to a theme component - */ - private final SparseArray<String> mCardIdsToComponentTypes = new SparseArray<String>(); - - private String mPkgName; - private Typeface mTypefaceNormal; - private int mBatteryStyle; - - private ScrollView mScrollView; - private ViewGroup mScrollContent; - private ViewGroup mPreviewContent; // Contains icons, font, nav/status etc. Not wallpaper - private View mLoadingView; - - //Status Bar Views - private ImageView mBluetooth; - private ImageView mWifi; - private ImageView mSignal; - private ImageView mBattery; - private TextView mClock; - - // Other Misc Preview Views - private FrameLayout mShadowFrame; - private ImageView mWallpaper; - private ViewGroup mStatusBar; - private TextView mFontPreview; - private ViewGroup mIconContainer; - private ViewGroup mStyleContainer; - private ViewGroup mBootAnimationContainer; - private BootAniImageView mBootAnimation; - - // Nav Bar Views - private ViewGroup mNavBar; - private ImageView mBackButton; - private ImageView mHomeButton; - private ImageView mRecentButton; - - // Title Card Views - private ViewGroup mTitleCard; - private ViewGroup mTitleLayout; - private TextView mTitle; - private ImageView mApply; - private ImageView mOverflow; - private ProgressBar mProgress; - - // Additional Card Views - private LinearLayout mAdditionalCards; - private WallpaperCardView mWallpaperCard; - private WallpaperCardView mLockScreenCard; - - // Style views - private ImageView mStylePreview; - - // Sound cards - private ViewGroup mRingtoneContainer; - private ImageView mRingtonePlayPause; - private ViewGroup mNotificationContainer; - private ImageView mNotificationPlayPause; - private ViewGroup mAlarmContainer; - private ImageView mAlarmPlayPause; - private Map<ImageView, MediaPlayer> mMediaPlayers; - - private Handler mHandler; - - private boolean mIsUninstalled; - private int mActiveCardId = -1; - private ComponentSelector mSelector; - // Supported components for the theme this fragment represents - private Map<String, String> mSelectedComponentsMap = new HashMap<String, String>(); - // Current system theme configuration as component -> pkgName - private Map<String, String> mCurrentTheme = new HashMap<String, String>(); - - static ThemeFragment newInstance(String pkgName) { - if (sTypefaceHelperCache == null) { - sTypefaceHelperCache = TypefaceHelperCache.getInstance(); - } - ThemeFragment f = new ThemeFragment(); - Bundle args = new Bundle(); - args.putString("pkgName", pkgName); - f.setArguments(args); - return f; - } - - /** - * When creating, retrieve this instance's number from its arguments. - */ - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - final Context context = getActivity(); - mPkgName = getArguments().getString("pkgName"); - mBatteryStyle = Settings.System.getInt(context.getContentResolver(), - Settings.System.STATUS_BAR_BATTERY, 0); - - getIconComponents(context); - ThemedTypefaceHelper helper = sTypefaceHelperCache.getHelperForTheme(context, - CURRENTLY_APPLIED_THEME.equals(mPkgName) ? getAppliedFontPackageName() : mPkgName); - mTypefaceNormal = helper.getTypeface(Typeface.NORMAL); - - mHandler = new Handler(); - - mCardIdsToComponentTypes.put(R.id.status_bar_container, MODIFIES_STATUS_BAR); - mCardIdsToComponentTypes.put(R.id.font_preview_container, MODIFIES_FONTS); - mCardIdsToComponentTypes.put(R.id.icon_container, MODIFIES_ICONS); - mCardIdsToComponentTypes.put(R.id.navigation_bar_container, MODIFIES_NAVIGATION_BAR); - mCardIdsToComponentTypes.put(R.id.wallpaper_card, MODIFIES_LAUNCHER); - mCardIdsToComponentTypes.put(R.id.lockscreen_card, MODIFIES_LOCKSCREEN); - mCardIdsToComponentTypes.put(R.id.style_card, MODIFIES_OVERLAYS); - mCardIdsToComponentTypes.put(R.id.bootani_preview_container, MODIFIES_BOOT_ANIM); - mCardIdsToComponentTypes.put(R.id.ringtone_preview_container, MODIFIES_RINGTONES); - mCardIdsToComponentTypes.put(R.id.notification_preview_container, MODIFIES_NOTIFICATIONS); - mCardIdsToComponentTypes.put(R.id.alarm_preview_container, MODIFIES_ALARMS); - - mMediaPlayers = new HashMap<ImageView, MediaPlayer>(3); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.v2_fragment_pager_list, container, false); - - mScrollView = (ScrollView) v.findViewById(android.R.id.list); - mScrollContent = (ViewGroup) mScrollView.getChildAt(0); - mPreviewContent = (ViewGroup) v.findViewById(R.id.preview_container); - mLoadingView = v.findViewById(R.id.loading_view); - - // Status Bar - mStatusBar = (ViewGroup) v.findViewById(R.id.status_bar); - mBluetooth = (ImageView) v.findViewById(R.id.bluetooth_icon); - mWifi = (ImageView) v.findViewById(R.id.wifi_icon); - mSignal = (ImageView) v.findViewById(R.id.signal_icon); - mBattery = (ImageView) v.findViewById(R.id.battery); - mClock = (TextView) v.findViewById(R.id.clock); - - // Wallpaper / Font / Icons / etc - mWallpaper = (ImageView) v.findViewById(R.id.wallpaper); - mFontPreview = (TextView) v.findViewById(R.id.font_preview); - mFontPreview.setTypeface(mTypefaceNormal); - mIconContainer = (ViewGroup) v.findViewById(R.id.icon_container); - mShadowFrame = (FrameLayout) v.findViewById(R.id.shadow_frame); - mStyleContainer = (ViewGroup) v.findViewById(R.id.style_card); - mStylePreview = (ImageView) v.findViewById(R.id.style_preview); - mBootAnimationContainer = (ViewGroup) v.findViewById(R.id.bootani_preview_container); - mBootAnimation = - (BootAniImageView) mBootAnimationContainer.findViewById(R.id.bootani_preview); - mRingtoneContainer = (ViewGroup) v.findViewById(R.id.ringtone_preview_container); - mRingtonePlayPause = (ImageView) mRingtoneContainer.findViewById(R.id.play_pause); - mNotificationContainer = (ViewGroup) v.findViewById(R.id.notification_preview_container); - mNotificationPlayPause = (ImageView) mNotificationContainer.findViewById(R.id.play_pause); - mAlarmContainer = (ViewGroup) v.findViewById(R.id.alarm_preview_container); - mAlarmPlayPause = (ImageView) mAlarmContainer.findViewById(R.id.play_pause); - - // Nav Bar - mNavBar = (ViewGroup) v.findViewById(R.id.navigation_bar); - mBackButton = (ImageView) v.findViewById(R.id.back_button); - mHomeButton = (ImageView) v.findViewById(R.id.home_button); - mRecentButton = (ImageView) v.findViewById(R.id.recent_button); - - // Title Card - mTitleCard = (ViewGroup)v.findViewById(R.id.title_card); - mTitleLayout = (ViewGroup) v.findViewById(R.id.title_layout); - mTitle = (TextView) v.findViewById(R.id.title); - mProgress = (ProgressBar) v.findViewById(R.id.apply_progress); - mOverflow = (ImageView) v.findViewById(R.id.overflow); - mOverflow.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - PopupMenu popupmenu = new PopupMenu(getActivity(), mTitleCard, Gravity.END); - popupmenu.getMenuInflater().inflate(R.menu.overflow, popupmenu.getMenu()); - - if (CURRENTLY_APPLIED_THEME.equals(mPkgName) || - mPkgName.equals(ThemeUtils.getDefaultThemePackageName(getActivity())) || - mPkgName.equals(ThemeConfig.HOLO_DEFAULT)) { - Menu menu = popupmenu.getMenu(); - menu.findItem(R.id.menu_delete).setEnabled(false); - } - - popupmenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - switch(item.getItemId()) { - case R.id.menu_author: - Toast.makeText(getActivity(), - "Not supported", - Toast.LENGTH_LONG).show(); - break; - case R.id.menu_delete: - uninstallTheme(); - break; - } - - return true; - } - }); - popupmenu.show(); - } - }); - mApply = (ImageView) v.findViewById(R.id.apply); - mApply.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - applyTheme(); - } - }); - if (CURRENTLY_APPLIED_THEME.equals(mPkgName)) { - mApply.setVisibility(View.GONE); - } - - // Additional cards which should hang out offscreen until expanded - mAdditionalCards = (LinearLayout) v.findViewById(R.id.additional_cards); - - - mWallpaperCard = (WallpaperCardView) v.findViewById(R.id.wallpaper_card); - mLockScreenCard = (WallpaperCardView) v.findViewById(R.id.lockscreen_card); - int translationY = getDistanceToMoveBelowScreen(mAdditionalCards); - mAdditionalCards.setTranslationY(translationY); - - getLoaderManager().initLoader(LOADER_ID_ALL, null, this); - - initCards(v); - - return v; - } - - @Override - public void onResume() { - super.onResume(); - if (CURRENTLY_APPLIED_THEME.equals(mPkgName)) { - if (getLoaderManager().getLoader(0) != null) { - getLoaderManager().restartLoader(0, null, this); - } - } - } - - @Override - public void onPause() { - super.onPause(); - stopMediaPlayers(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - freeMediaPlayers(); - } - - @Override - public void onProgress(int progress) { - mProgress.setProgress(progress); - } - - @Override - public void onFinish(boolean isSuccess) { - // We post a runnable to mHandler so the client is removed from the same thread - mHandler.post(new Runnable() { - @Override - public void run() { - ThemeManager tm = getThemeManager(); - if (tm != null) tm.removeClient(ThemeFragment.this); - } - }); - if (isSuccess) { - mProgress.setProgress(100); - animateProgressOut(); - ((ChooserActivity) getActivity()).themeChangeEnded(); - } - } - - public void expand() { - // Full width and height! - ViewGroup content = (ViewGroup) mScrollView.getParent(); - content.setPadding(0, 0, 0, 0); - ViewGroup.LayoutParams layoutParams = mPreviewContent.getLayoutParams(); - layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT; - mPreviewContent.setLayoutParams(layoutParams); - mScrollView.setPadding(0,0,0,0); - - // The parent of the wallpaper squishes the wp slightly because of padding from the 9 patch - // When the parent expands, the wallpaper returns to regular size which creates an - // undesireable effect. - Rect padding = new Rect(); - NinePatchDrawable bg = (NinePatchDrawable) mShadowFrame.getBackground(); - bg.getPadding(padding); - mIconContainer.setPadding(padding.left, padding.top, padding.right, padding.bottom); - mShadowFrame.setBackground(null); - mShadowFrame.setPadding(0, 0, 0, 0); - mAdditionalCards.setPadding(padding.left, padding.top, padding.right, padding.bottom); - - // Off screen cards will become visible and then be animated in - mWallpaperCard.setVisibility(View.VISIBLE); - - // Expand the children - int top = (int) getResources() - .getDimension(R.dimen.expanded_card_margin_top); - for (int i = 0; i < mPreviewContent.getChildCount(); i++) { - ComponentCardView child = (ComponentCardView) mPreviewContent.getChildAt(i); - - LinearLayout.LayoutParams lparams = - (LinearLayout.LayoutParams) child.getLayoutParams(); - lparams.setMargins(0, top, 0, 0); - - child.setLayoutParams(lparams); - child.expand(false); - } - - // Expand the additional children. - mAdditionalCards.setVisibility(View.VISIBLE); - for (int i = 0; i < mAdditionalCards.getChildCount(); i++) { - View v = mAdditionalCards.getChildAt(i); - if (v instanceof ComponentCardView) { - ComponentCardView card = (ComponentCardView) v; - card.setVisibility(View.VISIBLE); - card.expand(true); - } - } - - // Collect the present position of all the children. The next layout/draw cycle will - // change these bounds since we just expanded them. Then we can animate from prev location - // to the new location. Note that the order of these calls matter as they all - // add themselves to the root layout as overlays - mScrollView.requestLayout(); - animateWallpaperOut(); - animateTitleCard(true, false); - animateChildren(true, getChildrensGlobalBounds(mPreviewContent)); - animateExtras(true); - mSelector = ((ChooserActivity) getActivity()).getComponentSelector(); - mSelector.setOnItemClickedListener(mOnComponentItemClicked); - if (mBootAnimation != null) mBootAnimation.start(); - } - - - - // Returns the boundaries for all the children of parent relative to the app window - private List<Rect> getChildrensGlobalBounds(ViewGroup parent) { - List<Rect> bounds = new ArrayList<Rect>(); - for (int i = 0; i < parent.getChildCount(); i++) { - final View v = parent.getChildAt(i); - int[] pos = new int[2]; - v.getLocationInWindow(pos); - Rect boundary = new Rect(pos[0], pos[1], pos[0] + v.getWidth(), pos[1]+v.getHeight()); - bounds.add(boundary); - } - return bounds; - } - - public void fadeOutCards(Runnable endAction) { - for (int i = 0; i < mPreviewContent.getChildCount(); i++) { - ComponentCardView v = (ComponentCardView) mPreviewContent.getChildAt(i); - v.animateFadeOut(); - } - mHandler.postDelayed(endAction, ComponentCardView.CARD_FADE_DURATION); - } - - public void collapse(final boolean applyTheme) { - // Pad the view so it appears thinner - ViewGroup content = (ViewGroup) mScrollView.getParent(); - Resources r = mScrollView.getContext().getResources(); - int leftRightPadding = (int) r.getDimension(R.dimen.collapsed_theme_page_padding); - content.setPadding(leftRightPadding, 0, leftRightPadding, 0); - - //Move the theme preview so that it is near the center of page per spec - int paddingTop = (int) r.getDimension(R.dimen.collapsed_theme_page_padding_top); - mScrollView.setPadding(0, paddingTop, 0, 0); - - // During expand the wallpaper size decreases slightly to makeup for 9patch padding - // so when we collapse we should increase it again. - mShadowFrame.setBackgroundResource(R.drawable.bg_themepreview_shadow); - Rect padding = new Rect(); - final NinePatchDrawable bg = (NinePatchDrawable) mShadowFrame.getBackground(); - bg.getPadding(padding); - mShadowFrame.setPadding(padding.left, padding.top, padding.right, padding.bottom); - - // Gradually fade the drop shadow back in or else it will be out of place - ValueAnimator shadowAnimation = ValueAnimator.ofObject(new IntEvaluator(), 0, 255); - shadowAnimation.setDuration(ANIMATE_DURATION); - shadowAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animator) { - bg.setAlpha((Integer) animator.getAnimatedValue()); - } - - }); - shadowAnimation.start(); - - //Move the title card back in - mTitleCard.setVisibility(View.VISIBLE); - mTitleCard.setTranslationY(0); - - // Shrink the height - ViewGroup.LayoutParams layoutParams = mPreviewContent.getLayoutParams(); - Resources resources = mPreviewContent.getResources(); - layoutParams.height = (int) resources.getDimension(R.dimen.theme_preview_height); - - for (int i = 0; i < mPreviewContent.getChildCount(); i++) { - ComponentCardView child = (ComponentCardView) mPreviewContent.getChildAt(i); - LinearLayout.LayoutParams lparams = - (LinearLayout.LayoutParams) child.getLayoutParams(); - lparams.setMargins(0, 0, 0, 0); - - if (child.getId() == R.id.icon_container) { - int top = (int) child.getResources() - .getDimension(R.dimen.collapsed_icon_card_margin_top); - lparams.setMargins(0, top, 0, 0); - } else if (child.getId() == R.id.font_preview_container) { - int top = (int) child.getResources() - .getDimension(R.dimen.collapsed_font_card_margin_top); - lparams.setMargins(0, top, 0, 0); - } else if (child.getId() == R.id.navigation_bar_container) { - int top = (int) child.getResources() - .getDimension(R.dimen.collapsed_navbar_card_margin_top); - lparams.setMargins(0, top, 0, 0); - } - - child.getLayoutParams(); - child.collapse(); - } - - // Collapse additional cards - for (int i = 0; i < mAdditionalCards.getChildCount(); i++) { - View v = mAdditionalCards.getChildAt(i); - if (v instanceof ComponentCardView) { - ComponentCardView card = (ComponentCardView) v; - card.setVisibility(View.VISIBLE); - card.collapse(); - } - } - - mScrollView.requestLayout(); - animateChildren(false, getChildrensGlobalBounds(mPreviewContent)); - animateExtras(false); - animateWallpaperIn(); - animateTitleCard(false, applyTheme); - if (mBootAnimation != null) mBootAnimation.stop(); - stopMediaPlayers(); - } - - // This will animate the children's vertical positions between the previous bounds and the - // new bounds which occur on the next draw - private void animateChildren(final boolean isExpanding, final List<Rect> prevBounds) { - final ViewGroup root = (ViewGroup) getActivity().getWindow() - .getDecorView().findViewById(android.R.id.content); - - // Grab the child's new location and animate from prev to current loc. - final ViewTreeObserver observer = mScrollContent.getViewTreeObserver(); - observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - public boolean onPreDraw() { - observer.removeOnPreDrawListener(this); - - for (int i = mPreviewContent.getChildCount() - 1; i >= 0; i--) { - final ComponentCardView v = (ComponentCardView) mPreviewContent.getChildAt(i); - - float prevY; - float endY; - float prevHeight; - float endHeight; - if (i >= prevBounds.size()) { - // View is being created - prevY = mPreviewContent.getTop() + mPreviewContent.getHeight(); - endY = v.getY(); - prevHeight = v.getHeight(); - endHeight = v.getHeight(); - } else { - Rect boundary = prevBounds.get(i); - prevY = boundary.top; - prevHeight = boundary.height(); - - int[] endPos = new int[2]; - v.getLocationInWindow(endPos); - endY = endPos[1]; - endHeight = v.getHeight(); - } - - int paddingTop = v.getPaddingTop() / 2; - v.setTranslationY((prevY - endY - paddingTop) + (prevHeight - endHeight) / 2); - root.getOverlay().add(v); - - // Expanding has a delay while the wallpaper begins to fade out - // Collapsing is opposite of this so wallpaper will have the delay instead - int startDelay = isExpanding ? ANIMATE_START_DELAY : 0; - - v.animate() - .setStartDelay(startDelay) - .translationY(0) - .setDuration(ANIMATE_DURATION) - .setInterpolator( - new DecelerateInterpolator(ANIMATE_INTERPOLATE_FACTOR)) - .withEndAction(new Runnable() { - public void run() { - root.getOverlay().remove(v); - mPreviewContent.addView(v, 0); - } - }); - v.postDelayed(new Runnable() { - public void run() { - if (isExpanding) { - v.animateExpand(); - } - } - }, ANIMATE_DURATION / 2); - } - return true; - } - }); - } - - private void animateExtras(final boolean isExpanding) { - int[] pos = new int[2]; - mAdditionalCards.getLocationInWindow(pos); - final ViewGroup parent = (ViewGroup) mAdditionalCards.getParent(); - final ViewGroup root = (ViewGroup) getActivity().getWindow() - .getDecorView().findViewById(android.R.id.content); - - // During a collapse we don't want the card to shrink so add it to the overlay now - // During an expand we want the card to expand so add it to the overlay post-layout - if (!isExpanding) { - root.getOverlay().add(mAdditionalCards); - } - - // Expanding has a delay while the wallpaper begins to fade out - // Collapsing is opposite of this so wallpaper will have the delay instead - final int startDelay = isExpanding ? ANIMATE_START_DELAY : 0; - final ViewTreeObserver observer = mScrollContent.getViewTreeObserver(); - observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - public boolean onPreDraw() { - observer.removeOnPreDrawListener(this); - - int translationY = 0; - if (isExpanding) { - root.getOverlay().add(mAdditionalCards); - } else { - translationY = getDistanceToMoveBelowScreen(mAdditionalCards); - } - - int duration = isExpanding ? ANIMATE_DURATION + 100 : ANIMATE_DURATION; - mAdditionalCards.animate() - .setStartDelay(startDelay) - .translationY(translationY) - .setDuration(duration) - .setInterpolator( - new DecelerateInterpolator(ANIMATE_INTERPOLATE_FACTOR)) - .withEndAction(new Runnable() { - public void run() { - if (!isExpanding) { - mAdditionalCards.setVisibility(View.INVISIBLE); - } - root.getOverlay().remove(mAdditionalCards); - parent.addView(mAdditionalCards); - } - }); - return false; - } - }); - } - - private int getDistanceToMoveBelowScreen(View v) { - Display display = getActivity().getWindowManager().getDefaultDisplay(); - Point p = new Point(); - display.getSize(p); - int heightId = getResources() - .getIdentifier("system_bar_height", "dimen", "android"); - int navbar_height = getResources().getDimensionPixelSize(heightId); - int[] pos = new int[2]; - v.getLocationInWindow(pos); - return p.y + navbar_height - pos[1]; - } - - private void animateTitleCard(final boolean expand, final boolean applyTheme) { - final ViewGroup parent = (ViewGroup) mTitleCard.getParent(); - // Get current location of the title card - int[] location = new int[2]; - mTitleCard.getLocationOnScreen(location); - final int prevY = location[1]; - - final ViewTreeObserver observer = mScrollContent.getViewTreeObserver(); - observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - public boolean onPreDraw() { - observer.removeOnPreDrawListener(this); - - final ViewGroup root = (ViewGroup) getActivity().getWindow() - .getDecorView().findViewById(android.R.id.content); - - root.getOverlay().add(mTitleCard); - - //Move title card back where it was before the relayout - float alpha = 1f; - if (expand) { - int[] endPos = new int[2]; - mTitleCard.getLocationInWindow(endPos); - int endY = endPos[1]; - mTitleCard.setTranslationY(prevY - endY); - alpha = 0; - } else { - } - - // Fade the title card and move it out of the way - mTitleCard.animate() - .alpha(alpha) - .setDuration(ANIMATE_DURATION) - .withEndAction(new Runnable() { - public void run() { - root.getOverlay().remove(mTitleCard); - parent.addView(mTitleCard); - if (expand) { - mTitleCard.setVisibility(View.GONE); - } else if (applyTheme) { - // since the title card is the last animation when collapsing - // we will handle applying the theme, if applicable, here - applyTheme(); - } - } - }); - return true; - } - }); - } - - private void animateWallpaperOut() { - final ViewGroup root = (ViewGroup) getActivity().getWindow() - .getDecorView().findViewById(android.R.id.content); - - int[] location = new int[2]; - mWallpaper.getLocationOnScreen(location); - - final int prevY = location[1]; - - final ViewTreeObserver observer = mScrollContent.getViewTreeObserver(); - observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - public boolean onPreDraw() { - observer.removeOnPreDrawListener(this); - root.getOverlay().add(mWallpaper); - - int[] location = new int[2]; - mWallpaper.getLocationOnScreen(location); - final int newY = location[1]; - - mWallpaper.setTranslationY(prevY - newY); - mWallpaper.animate() - .alpha(0f) - .setDuration(300) - .withEndAction(new Runnable() { - public void run() { - root.getOverlay().remove(mWallpaper); - mShadowFrame.addView(mWallpaper, 0); - mWallpaper.setVisibility(View.GONE); - } - }); - return true; - - } - }); - } - - private void animateWallpaperIn() { - mWallpaper.setVisibility(View.VISIBLE); - mWallpaper.setTranslationY(0); - mWallpaper.animate() - .alpha(1f) - .setDuration(300); - } - - private String getAppliedFontPackageName() { - final Configuration config = getActivity().getResources().getConfiguration(); - final ThemeConfig themeConfig = config != null ? config.themeConfig : null; - return themeConfig != null ? themeConfig.getFontPkgName() : - ThemeConfig.getSystemTheme().getFontPkgName(); - } - - private ThemeManager getThemeManager() { - final Context context = getActivity(); - if (context != null) { - return (ThemeManager) context.getSystemService(Context.THEME_SERVICE); - } - return null; - } - - private void freeMediaPlayers() { - for (MediaPlayer mp : mMediaPlayers.values()) { - if (mp != null) { - mp.stop(); - mp.release(); - } - } - mMediaPlayers.clear(); - } - - private View.OnClickListener mPlayPauseClickListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - MediaPlayer mp = (MediaPlayer) v.getTag(); - if (mp != null) { - if (mp.isPlaying()) { - ((ImageView) v).setImageResource(R.drawable.media_sound_preview); - mp.pause(); - mp.seekTo(0); - } else { - stopMediaPlayers(); - ((ImageView) v).setImageResource(R.drawable.media_sound_stop); - mp.start(); - } - } - } - }; - - private MediaPlayer.OnCompletionListener mPlayCompletionListener - = new MediaPlayer.OnCompletionListener() { - @Override - public void onCompletion(MediaPlayer mp) { - for (ImageView v : mMediaPlayers.keySet()) { - if (mp == mMediaPlayers.get(v)) { - if (v != null) { - v.setImageResource(R.drawable.media_sound_preview); - } - } - } - } - }; - - private void stopMediaPlayers() { - for (ImageView v : mMediaPlayers.keySet()) { - if (v != null) { - v.setImageResource(R.drawable.media_sound_preview); - } - MediaPlayer mp = mMediaPlayers.get(v); - if (mp != null && mp.isPlaying()) { - mp.pause(); - mp.seekTo(0); - } - } - } - - @Override - public Loader<Cursor> onCreateLoader(int id, Bundle args) { - String pkgName = mPkgName; - if (args != null) { - pkgName = args.getString("pkgName"); - } - Uri uri = ThemesContract.PreviewColumns.CONTENT_URI; - String selection = ThemesContract.ThemesColumns.PKG_NAME + "= ?"; - String[] selectionArgs = new String[] { pkgName }; - String[] projection = null; - switch (id) { - case LOADER_ID_ALL: - if (!CURRENTLY_APPLIED_THEME.equals(pkgName)) { - projection = new String[] { - ThemesColumns.PKG_NAME, - ThemesColumns.TITLE, - ThemesColumns.WALLPAPER_URI, - ThemesColumns.HOMESCREEN_URI, - // Theme abilities - ThemesColumns.MODIFIES_LAUNCHER, - ThemesColumns.MODIFIES_LOCKSCREEN, - ThemesColumns.MODIFIES_ALARMS, - ThemesColumns.MODIFIES_BOOT_ANIM, - ThemesColumns.MODIFIES_FONTS, - ThemesColumns.MODIFIES_ICONS, - ThemesColumns.MODIFIES_NAVIGATION_BAR, - ThemesColumns.MODIFIES_OVERLAYS, - ThemesColumns.MODIFIES_RINGTONES, - ThemesColumns.MODIFIES_STATUS_BAR, - ThemesColumns.MODIFIES_NOTIFICATIONS, - //Previews - PreviewColumns.WALLPAPER_PREVIEW, - PreviewColumns.STATUSBAR_BACKGROUND, - PreviewColumns.STATUSBAR_WIFI_ICON, - PreviewColumns.STATUSBAR_WIFI_COMBO_MARGIN_END, - PreviewColumns.STATUSBAR_BLUETOOTH_ICON, - PreviewColumns.STATUSBAR_SIGNAL_ICON, - PreviewColumns.STATUSBAR_CLOCK_TEXT_COLOR, - PreviewColumns.STATUSBAR_BATTERY_CIRCLE, - PreviewColumns.STATUSBAR_BATTERY_LANDSCAPE, - PreviewColumns.STATUSBAR_BATTERY_PORTRAIT, - PreviewColumns.NAVBAR_BACK_BUTTON, - PreviewColumns.NAVBAR_HOME_BUTTON, - PreviewColumns.NAVBAR_RECENT_BUTTON, - PreviewColumns.ICON_PREVIEW_1, - PreviewColumns.ICON_PREVIEW_2, - PreviewColumns.ICON_PREVIEW_3, - PreviewColumns.LOCK_WALLPAPER_PREVIEW, - PreviewColumns.STYLE_PREVIEW - }; - } else { - projection = new String[] { - PreviewColumns.WALLPAPER_PREVIEW, - PreviewColumns.STATUSBAR_BACKGROUND, - PreviewColumns.STATUSBAR_WIFI_ICON, - PreviewColumns.STATUSBAR_WIFI_COMBO_MARGIN_END, - PreviewColumns.STATUSBAR_BLUETOOTH_ICON, - PreviewColumns.STATUSBAR_SIGNAL_ICON, - PreviewColumns.STATUSBAR_CLOCK_TEXT_COLOR, - PreviewColumns.STATUSBAR_BATTERY_CIRCLE, - PreviewColumns.STATUSBAR_BATTERY_LANDSCAPE, - PreviewColumns.STATUSBAR_BATTERY_PORTRAIT, - PreviewColumns.NAVBAR_BACK_BUTTON, - PreviewColumns.NAVBAR_HOME_BUTTON, - PreviewColumns.NAVBAR_RECENT_BUTTON, - PreviewColumns.ICON_PREVIEW_1, - PreviewColumns.ICON_PREVIEW_2, - PreviewColumns.ICON_PREVIEW_3, - PreviewColumns.LOCK_WALLPAPER_PREVIEW, - PreviewColumns.STYLE_PREVIEW, - // TODO: add this to the ThemesContract if this - // design moves beyond prototype - NAVIGATION_BAR_BACKGROUND - }; - uri = PreviewColumns.APPLIED_URI; - selection = null; - selectionArgs = null; - } - break; - case LOADER_ID_STATUS_BAR: - projection = new String[] { - ThemesColumns.PKG_NAME, - ThemesColumns.TITLE, - PreviewColumns.STATUSBAR_BACKGROUND, - PreviewColumns.STATUSBAR_WIFI_ICON, - PreviewColumns.STATUSBAR_WIFI_COMBO_MARGIN_END, - PreviewColumns.STATUSBAR_BLUETOOTH_ICON, - PreviewColumns.STATUSBAR_SIGNAL_ICON, - PreviewColumns.STATUSBAR_CLOCK_TEXT_COLOR, - PreviewColumns.STATUSBAR_BATTERY_CIRCLE, - PreviewColumns.STATUSBAR_BATTERY_LANDSCAPE, - PreviewColumns.STATUSBAR_BATTERY_PORTRAIT - }; - break; - case LOADER_ID_FONT: - projection = new String[] { - ThemesColumns.PKG_NAME, - ThemesColumns.TITLE - }; - break; - case LOADER_ID_ICONS: - projection = new String[] { - ThemesColumns.PKG_NAME, - ThemesColumns.TITLE, - PreviewColumns.ICON_PREVIEW_1, - PreviewColumns.ICON_PREVIEW_2, - PreviewColumns.ICON_PREVIEW_3, - PreviewColumns.ICON_PREVIEW_4 - }; - break; - case LOADER_ID_WALLPAPER: - projection = new String[] { - ThemesColumns.PKG_NAME, - ThemesColumns.TITLE, - PreviewColumns.WALLPAPER_PREVIEW - }; - break; - case LOADER_ID_NAVIGATION_BAR: - projection = new String[] { - ThemesColumns.PKG_NAME, - ThemesColumns.TITLE, - PreviewColumns.STATUSBAR_BACKGROUND, - PreviewColumns.NAVBAR_BACK_BUTTON, - PreviewColumns.NAVBAR_HOME_BUTTON, - PreviewColumns.NAVBAR_RECENT_BUTTON - }; - break; - case LOADER_ID_LOCKSCREEN: - projection = new String[]{ - ThemesColumns.PKG_NAME, - ThemesColumns.TITLE, - PreviewColumns.LOCK_WALLPAPER_PREVIEW - }; - break; - case LOADER_ID_STYLE: - projection = new String[] { - ThemesColumns.PKG_NAME, - ThemesColumns.TITLE, - PreviewColumns.STYLE_PREVIEW - }; - break; - case LOADER_ID_BOOT_ANIMATION: - projection = new String[] { - ThemesColumns.PKG_NAME, - ThemesColumns.TITLE - }; - break; - case LOADER_ID_RINGTONE: - case LOADER_ID_NOTIFICATION: - case LOADER_ID_ALARM: - projection = new String[] { - ThemesColumns.PKG_NAME, - ThemesColumns.TITLE - }; - break; - } - return new CursorLoader(getActivity(), uri, projection, selection, selectionArgs, null); - } - - @Override - public void onLoadFinished(Loader<Cursor> loader, Cursor c) { - c.moveToFirst(); - if (c.getCount() == 0) return; - switch (loader.getId()) { - case LOADER_ID_ALL: - populateSupportedComponents(c); - loadStatusBar(c, false); - loadIcons(c, false); - loadNavBar(c, false); - loadTitle(c); - loadFont(c, false); - loadAndRemoveAdditionalCards(c); - mHandler.post(new Runnable() { - @Override - public void run() { - animateContentIn(); - } - }); - break; - case LOADER_ID_STATUS_BAR: - loadStatusBar(c, true); - break; - case LOADER_ID_FONT: - loadFont(c, true); - break; - case LOADER_ID_ICONS: - loadIcons(c, true); - break; - case LOADER_ID_WALLPAPER: - loadWallpaper(c, true); - break; - case LOADER_ID_NAVIGATION_BAR: - loadNavBar(c, true); - break; - case LOADER_ID_LOCKSCREEN: - loadLockScreen(c, true); - break; - case LOADER_ID_STYLE: - loadStyle(c, true); - break; - case LOADER_ID_BOOT_ANIMATION: - loadBootAnimation(c, true); - break; - case LOADER_ID_RINGTONE: - loadAudible(RingtoneManager.TYPE_RINGTONE, c, true); - break; - case LOADER_ID_NOTIFICATION: - loadAudible(RingtoneManager.TYPE_NOTIFICATION, c, true); - break; - case LOADER_ID_ALARM: - loadAudible(RingtoneManager.TYPE_ALARM, c, true); - break; - } - } - - @Override - public void onLoaderReset(Loader<Cursor> loader) {} - - private void loadAndRemoveAdditionalCards(Cursor c) { - LinkedList<View> removeList = new LinkedList<View>(); - for(int i=0; i < mAdditionalCards.getChildCount(); i++) { - View v = mAdditionalCards.getChildAt(i); - if (v instanceof ComponentCardView) { - String component = mCardIdsToComponentTypes.get(v.getId()); - if (shouldShowComponentCard(component)) { - loadAdditionalCard(c, component); - } else { - removeList.add(v); - // remove the Space below this card - removeList.add(mAdditionalCards.getChildAt(i+1)); - - if (component != null && !shouldShowComponentCard(component)) { - mCardIdsToComponentTypes.remove(v.getId()); - } - } - } - } - - // TODO: It might make more sense to not inflate so many views if we do not - // plan to actually use them. But it is nice to be able to declare them in the - // xml layout under additionalCards - for(View v : removeList) { - mAdditionalCards.removeView(v); - } - - if (shouldShowComponentCard(MODIFIES_LOCKSCREEN)) { - loadLockScreen(c, false); - } else { - mAdditionalCards.removeView(mLockScreenCard); - } - } - - private void loadAdditionalCard(Cursor c, String component) { - if (MODIFIES_LOCKSCREEN.equals(component)) { - loadLockScreen(c, false); - } else if (MODIFIES_LAUNCHER.equals(component)) { - loadWallpaper(c, false); - } else if (MODIFIES_OVERLAYS.equals(component)) { - loadStyle(c, false); - } else if (MODIFIES_BOOT_ANIM.equals(component)) { - loadBootAnimation(c, false); - } else if (MODIFIES_RINGTONES.equals(component)) { - loadAudible(RingtoneManager.TYPE_RINGTONE, c, false); - } else if (MODIFIES_NOTIFICATIONS.equals(component)) { - loadAudible(RingtoneManager.TYPE_NOTIFICATION, c, false); - } else if (MODIFIES_ALARMS.equals(component)) { - loadAudible(RingtoneManager.TYPE_ALARM, c, false); - } else { - throw new IllegalArgumentException("Don't know how to load: " + component); - } - } - - private void populateSupportedComponents(Cursor c) { - // Currently applied theme doesn't return the columns we expect and - // it doesn't matter because currently applied theme shows everything anyhow - if (CURRENTLY_APPLIED_THEME.equals(mPkgName)) { - return; - } - - List<String> components = ThemeUtils.getAllComponents(); - for(String component : components) { - int pkgIdx = c.getColumnIndex(ThemesColumns.PKG_NAME); - int modifiesCompIdx = c.getColumnIndex(component); - - String pkg = c.getString(pkgIdx); - boolean supported = c.getInt(modifiesCompIdx) == 1; - if (supported) { - mSelectedComponentsMap.put(component, pkg); - } - } - if (!mSelectedComponentsMap.containsKey(MODIFIES_BOOT_ANIM)) { - mBootAnimation = null; - } - } - - /** - * Determines whether a card should be shown or not. - * UX Rules: - * 1) "My Theme" always shows all cards - * 2) Other themes only show what has been implemented in the theme - * - */ - private Boolean shouldShowComponentCard(String component) { - if (CURRENTLY_APPLIED_THEME.equals(mPkgName)) { - return true; - } - String pkg = mSelectedComponentsMap.get(component); - return pkg != null && pkg.equals(mPkgName); - } - - private void loadTitle(Cursor c) { - if (CURRENTLY_APPLIED_THEME.equals(mPkgName)) { - mTitle.setText(R.string.my_theme); - } else { - int titleIdx = c.getColumnIndex(ThemesColumns.TITLE); - String title = c.getString(titleIdx); - mTitle.setText(title); - } - } - - private void loadWallpaper(Cursor c, boolean animate) { - Drawable overlay = null; - if (animate) { - overlay = getOverlayDrawable(mWallpaperCard, true); - } - - int pkgNameIdx = c.getColumnIndex(ThemesColumns.PKG_NAME); - int wpIdx = c.getColumnIndex(PreviewColumns.WALLPAPER_PREVIEW); - final Resources res = getResources(); - if (pkgNameIdx > -1) { - Bitmap bitmap = Utils.loadBitmapBlob(c, wpIdx); - mWallpaper.setImageBitmap(bitmap); - mWallpaperCard.setWallpaper(new BitmapDrawable(res, bitmap)); - String pkgName = c.getString(pkgNameIdx); - mSelectedComponentsMap.put(MODIFIES_LAUNCHER, pkgName); - } else { - final Context context = getActivity(); - Drawable wp = context == null ? null : - WallpaperManager.getInstance(context).getDrawable(); - if (wp == null) { - wp = new BitmapDrawable(res, Utils.loadBitmapBlob(c, wpIdx)); - } - mWallpaper.setImageDrawable(wp); - mWallpaperCard.setWallpaper(wp); - } - - if (animate) { - animateContentChange(R.id.wallpaper_card, mWallpaperCard, overlay); - } - } - - public void loadLockScreen(Cursor c, boolean animate) { - Drawable overlay = null; - if (animate) { - overlay = getOverlayDrawable(mLockScreenCard, true); - } - - int pkgNameIdx = c.getColumnIndex(ThemesColumns.PKG_NAME); - int wpIdx = c.getColumnIndex(PreviewColumns.LOCK_WALLPAPER_PREVIEW); - final Resources res = getResources(); - if (pkgNameIdx > -1) { - Bitmap bitmap = Utils.loadBitmapBlob(c, wpIdx); - mLockScreenCard.setWallpaper(new BitmapDrawable(res, bitmap)); - String pkgName = c.getString(pkgNameIdx); - mSelectedComponentsMap.put(MODIFIES_LOCKSCREEN, pkgName); - } else { - final Context context = getActivity(); - Drawable wp = context == null ? null : - WallpaperManager.getInstance(context).getFastKeyguardDrawable(); - if (wp == null) { - wp = new BitmapDrawable(res, Utils.loadBitmapBlob(c, wpIdx)); - } - mLockScreenCard.setWallpaper(wp); - } - - if (animate) { - animateContentChange(R.id.lockscreen_card, mLockScreenCard, overlay); - } - } - - private void loadStatusBar(Cursor c, boolean animate) { - int backgroundIdx = c.getColumnIndex(PreviewColumns.STATUSBAR_BACKGROUND); - int wifiIdx = c.getColumnIndex(PreviewColumns.STATUSBAR_WIFI_ICON); - int wifiMarginIdx = c.getColumnIndex(PreviewColumns.STATUSBAR_WIFI_COMBO_MARGIN_END); - int bluetoothIdx = c.getColumnIndex(PreviewColumns.STATUSBAR_BLUETOOTH_ICON); - int signalIdx = c.getColumnIndex(PreviewColumns.STATUSBAR_SIGNAL_ICON); - int batteryIdx = c.getColumnIndex(Utils.getBatteryIndex(mBatteryStyle)); - int clockColorIdx = c.getColumnIndex(PreviewColumns.STATUSBAR_CLOCK_TEXT_COLOR); - int pkgNameIdx = c.getColumnIndex(ThemesColumns.PKG_NAME); - - Bitmap background = Utils.loadBitmapBlob(c, backgroundIdx); - Bitmap bluetoothIcon = Utils.loadBitmapBlob(c, bluetoothIdx); - Bitmap wifiIcon = Utils.loadBitmapBlob(c, wifiIdx); - Bitmap signalIcon = Utils.loadBitmapBlob(c, signalIdx); - Bitmap batteryIcon = Utils.loadBitmapBlob(c, batteryIdx); - int wifiMargin = c.getInt(wifiMarginIdx); - int clockTextColor = c.getInt(clockColorIdx); - - Drawable overlay = null; - if (animate) { - overlay = getOverlayDrawable(mStatusBar, false); - } - - mStatusBar.setBackground(new BitmapDrawable(getActivity().getResources(), background)); - mBluetooth.setImageBitmap(bluetoothIcon); - mWifi.setImageBitmap(wifiIcon); - mSignal.setImageBitmap(signalIcon); - mBattery.setImageBitmap(batteryIcon); - mClock.setTextColor(clockTextColor); - - ViewGroup.MarginLayoutParams params = - (ViewGroup.MarginLayoutParams) mWifi.getLayoutParams(); - params.setMarginEnd(wifiMargin); - mWifi.setLayoutParams(params); - - if (mBatteryStyle == 4) { - mBattery.setVisibility(View.GONE); - } else { - mBattery.setVisibility(View.VISIBLE); - } - mStatusBar.post(new Runnable() { - @Override - public void run() { - mStatusBar.invalidate(); - } - }); - if (pkgNameIdx > -1) { - String pkgName = c.getString(pkgNameIdx); - mSelectedComponentsMap.put(MODIFIES_STATUS_BAR, pkgName); - } - if (animate) { - animateContentChange(R.id.status_bar_container, mStatusBar, overlay); - } - } - - private void loadIcons(Cursor c, boolean animate) { - int[] iconIdx = new int[4]; - iconIdx[0] = c.getColumnIndex(PreviewColumns.ICON_PREVIEW_1); - iconIdx[1] = c.getColumnIndex(PreviewColumns.ICON_PREVIEW_2); - iconIdx[2] = c.getColumnIndex(PreviewColumns.ICON_PREVIEW_3); - iconIdx[3] = c.getColumnIndex(PreviewColumns.ICON_PREVIEW_4); - int pkgNameIdx = c.getColumnIndex(ThemesColumns.PKG_NAME); - - // Set the icons. If the provider does not have an icon preview then - // fall back to the default icon set - IconPreviewHelper helper = new IconPreviewHelper(getActivity(), ""); - int numOfChildren = ((ViewGroup)mIconContainer.getChildAt(1)).getChildCount(); - - List<ImageView> iconViews = new ArrayList<ImageView>(numOfChildren); - for(int i=0; i < numOfChildren; i++) { - final View view = (View) ((ViewGroup)mIconContainer.getChildAt(1)).getChildAt(i); - if (!(view instanceof ImageView)) continue; - iconViews.add((ImageView) view); - } - - for(int i=0; i < iconViews.size() && i < iconIdx.length; i++) { - final ImageView v = iconViews.get(i); - Bitmap bitmap = Utils.loadBitmapBlob(c, iconIdx[i]); - Drawable oldIcon = v.getDrawable(); - Drawable newIcon; - if (bitmap == null) { - ComponentName component = sIconComponents[i]; - newIcon = helper.getDefaultIcon(component.getPackageName(), - component.getClassName()); - } else { - newIcon = new BitmapDrawable(getResources(), bitmap); - } - if (animate) { - Drawable[] layers = new Drawable[2]; - layers[0] = oldIcon instanceof IconTransitionDrawable ? - ((IconTransitionDrawable) oldIcon).getDrawable(1) : oldIcon; - layers[1] = newIcon; - final IconTransitionDrawable itd = new IconTransitionDrawable(layers); - v.postDelayed(new Runnable() { - @Override - public void run() { - itd.startTransition(ANIMATE_COMPONENT_CHANGE_DURATION); - v.setImageDrawable(itd); - } - }, ANIMATE_COMPONENT_ICON_DELAY * i); - } else { - v.setImageDrawable(newIcon); - } - } - if (pkgNameIdx > -1) { - String pkgName = c.getString(pkgNameIdx); - mSelectedComponentsMap.put(MODIFIES_ICONS, pkgName); - } - } - - private void loadNavBar(Cursor c, boolean animate) { - int backButtonIdx = c.getColumnIndex(PreviewColumns.NAVBAR_BACK_BUTTON); - int homeButtonIdx = c.getColumnIndex(PreviewColumns.NAVBAR_HOME_BUTTON); - int recentButtonIdx = c.getColumnIndex(PreviewColumns.NAVBAR_RECENT_BUTTON); - int backgroundIdx = c.getColumnIndex(NAVIGATION_BAR_BACKGROUND); - if (backgroundIdx == -1) { - backgroundIdx = c.getColumnIndex(PreviewColumns.STATUSBAR_BACKGROUND); - } - int pkgNameIdx = c.getColumnIndex(ThemesColumns.PKG_NAME); - - Bitmap background = Utils.loadBitmapBlob(c, backgroundIdx); - Bitmap backButton = Utils.loadBitmapBlob(c, backButtonIdx); - Bitmap homeButton = Utils.loadBitmapBlob(c, homeButtonIdx); - Bitmap recentButton = Utils.loadBitmapBlob(c, recentButtonIdx); - - Drawable overlay = null; - if (animate) { - overlay = getOverlayDrawable(mNavBar, false); - } - - mNavBar.setBackground(new BitmapDrawable(getActivity().getResources(), background)); - mBackButton.setImageBitmap(backButton); - mHomeButton.setImageBitmap(homeButton); - mRecentButton.setImageBitmap(recentButton); - - if (pkgNameIdx > -1) { - String pkgName = c.getString(pkgNameIdx); - mSelectedComponentsMap.put(MODIFIES_NAVIGATION_BAR, pkgName); - } - if (animate) { - animateContentChange(R.id.navigation_bar_container, mNavBar, overlay); - } - } - - private void loadFont(Cursor c, boolean animate) { - Drawable overlay = null; - if (animate) { - overlay = getOverlayDrawable(mFontPreview, true); - } - - int pkgNameIdx = c.getColumnIndex(ThemesColumns.PKG_NAME); - String pkgName = pkgNameIdx >= 0 ? c.getString(pkgNameIdx) : mPkgName; - TypefaceHelperCache cache = TypefaceHelperCache.getInstance(); - ThemedTypefaceHelper helper = cache.getHelperForTheme(getActivity(), - CURRENTLY_APPLIED_THEME.equals(pkgName) ? getAppliedFontPackageName() : pkgName); - mTypefaceNormal = helper.getTypeface(Typeface.NORMAL); - mFontPreview.setTypeface(mTypefaceNormal); - if (pkgNameIdx > -1) { - mSelectedComponentsMap.put(MODIFIES_FONTS, pkgName); - } - if (animate) { - animateContentChange(R.id.font_preview_container, mFontPreview, overlay); - } - } - - private void loadStyle(Cursor c, boolean animate) { - Drawable overlay = null; - if (animate) { - overlay = getOverlayDrawable(mStylePreview, true); - } - - int pkgNameIdx = c.getColumnIndex(ThemesColumns.PKG_NAME); - int styleIdx = c.getColumnIndex(PreviewColumns.STYLE_PREVIEW); - mStylePreview.setImageBitmap(Utils.loadBitmapBlob(c, styleIdx)); - if (pkgNameIdx > -1) { - String pkgName = c.getString(pkgNameIdx); - mSelectedComponentsMap.put(MODIFIES_OVERLAYS, pkgName); - } - if (animate) { - animateContentChange(R.id.style_card, mStylePreview, overlay); - } - } - - private void loadBootAnimation(Cursor c, boolean autoStart) { - int pkgNameIdx = c.getColumnIndex(ThemesColumns.PKG_NAME); - if (mBootAnimation != null) { - String pkgName; - if (pkgNameIdx > -1) { - pkgName = c.getString(pkgNameIdx); - mSelectedComponentsMap.put(MODIFIES_BOOT_ANIM, pkgName); - } else { - pkgName = mCurrentTheme.get(MODIFIES_BOOT_ANIM); - } - mBootAnimation.stop(); - new AnimationLoader(getActivity(), pkgName, mBootAnimation, autoStart).execute(); - } - } - - private void loadAudible(int type, Cursor c, boolean animate) { - View audibleContainer = null; - ImageView playPause = null; - String component = null; - switch (type) { - case RingtoneManager.TYPE_RINGTONE: - audibleContainer = mRingtoneContainer; - playPause = mRingtonePlayPause; - component = MODIFIES_RINGTONES; - break; - case RingtoneManager.TYPE_NOTIFICATION: - audibleContainer = mNotificationContainer; - playPause = mNotificationPlayPause; - component = MODIFIES_NOTIFICATIONS; - break; - case RingtoneManager.TYPE_ALARM: - audibleContainer = mAlarmContainer; - playPause = mAlarmPlayPause; - component = MODIFIES_ALARMS; - break; - } - if (audibleContainer == null) return; - TextView label = (TextView) audibleContainer.findViewById(R.id.label); - label.setText(getAudibleLabel(type)); - - int pkgNameIdx = c.getColumnIndex(ThemesColumns.PKG_NAME); - int titleIdx = c.getColumnIndex(ThemesColumns.TITLE); - if (playPause == null) { - playPause = - (ImageView) audibleContainer.findViewById(R.id.play_pause); - } - TextView title = (TextView) audibleContainer.findViewById(R.id.audible_name); - MediaPlayer mp = mMediaPlayers.get(playPause); - if (mp == null) { - mp = new MediaPlayer(); - } - if (pkgNameIdx > -1) { - String pkgName = c.getString(pkgNameIdx); - try { - AudioUtils.loadThemeAudible(getActivity(), type, pkgName, mp); - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, "Unable to load sound for " + pkgName, e); - return; - } - title.setText(c.getString(titleIdx)); - mSelectedComponentsMap.put(component, pkgName); - } else { - final Context context = getActivity(); - Uri ringtoneUri; - try { - ringtoneUri = AudioUtils.loadDefaultAudible(context, type, mp); - } catch (IOException e) { - Log.w(TAG, "Unable to load default sound ", e); - return; - } - title.setText(RingtoneManager.getRingtone(context, ringtoneUri).getTitle(context)); - } - - playPause.setTag(mp); - mMediaPlayers.put(playPause, mp); - playPause.setOnClickListener(mPlayPauseClickListener); - mp.setOnCompletionListener(mPlayCompletionListener); - } - - private Drawable getOverlayDrawable(View v, boolean requiresTransparency) { - if (!v.isDrawingCacheEnabled()) v.setDrawingCacheEnabled(true); - Bitmap cache = v.getDrawingCache(true).copy( - requiresTransparency ? Config.ARGB_8888 : Config.RGB_565, false); - Drawable d = cache != null ? new BitmapDrawable(getResources(), cache) : null; - v.destroyDrawingCache(); - - return d; - } - - private String getAudibleLabel(int type) { - switch (type) { - case RingtoneManager.TYPE_RINGTONE: - return getString(R.string.ringtone_label); - case RingtoneManager.TYPE_NOTIFICATION: - return getString(R.string.notification_label); - case RingtoneManager.TYPE_ALARM: - return getString(R.string.alarm_label); - } - return null; - } - - public static ComponentName[] getIconComponents(Context context) { - if (sIconComponents == null || sIconComponents.length == 0) { - sIconComponents = new ComponentName[]{COMPONENT_DIALER, COMPONENT_MESSAGING, - COMPONENT_CAMERA, COMPONENT_BROWSER}; - - PackageManager pm = context.getPackageManager(); - - // if device does not have telephony replace dialer and mms - if (!pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { - sIconComponents[0] = COMPONENT_CALENDAR; - sIconComponents[1] = COMPONENT_GALERY; - } - - if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) { - sIconComponents[2] = COMPONENT_SETTINGS; - } else { - // decide on which camera icon to use - try { - if (pm.getPackageInfo(CAMERA_NEXT_PACKAGE, 0) != null) { - sIconComponents[2] = COMPONENT_CAMERANEXT; - } - } catch (PackageManager.NameNotFoundException e) { - // default to COMPONENT_CAMERA - } - } - - } - return sIconComponents; - } - - private void initCards(View parent) { - for (int i = 0; i < mCardIdsToComponentTypes.size(); i++) { - parent.findViewById(mCardIdsToComponentTypes.keyAt(i)) - .setOnClickListener(mCardClickListener); - } - } - - private View.OnClickListener mCardClickListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - if (mActiveCardId > 0) { - mActiveCardId = -1; - getActivity().onBackPressed(); - return; - } - mActiveCardId = v.getId(); - String component = mCardIdsToComponentTypes.get(mActiveCardId); - ((ChooserActivity) getActivity()).showComponentSelector(component, v); - fadeOutNonSelectedCards(mActiveCardId); - stopMediaPlayers(); - } - }; - - private OnItemClickedListener mOnComponentItemClicked = new OnItemClickedListener() { - @Override - public void onItemClicked(String pkgName) { - Bundle args = new Bundle(); - args.putString("pkgName", pkgName); - int loaderId = -1; - String component = mSelector.getComponentType(); - if (MODIFIES_STATUS_BAR.equals(component)) { - loaderId = LOADER_ID_STATUS_BAR; - } else if (MODIFIES_FONTS.equals(component)) { - loaderId = LOADER_ID_FONT; - } else if (MODIFIES_ICONS.equals(component)) { - loaderId = LOADER_ID_ICONS; - } else if (MODIFIES_NAVIGATION_BAR.equals(component)) { - loaderId = LOADER_ID_NAVIGATION_BAR; - } else if (MODIFIES_LAUNCHER.equals(component)) { - loaderId = LOADER_ID_WALLPAPER; - } else if (MODIFIES_LOCKSCREEN.equals(component)) { - loaderId = LOADER_ID_LOCKSCREEN; - } else if (MODIFIES_OVERLAYS.equals(component)) { - loaderId = LOADER_ID_STYLE; - } else if (MODIFIES_BOOT_ANIM.equals(component)) { - loaderId = LOADER_ID_BOOT_ANIMATION; - } else if (MODIFIES_RINGTONES.equals(component)) { - loaderId = LOADER_ID_RINGTONE; - } else if (MODIFIES_NOTIFICATIONS.equals(component)) { - loaderId = LOADER_ID_NOTIFICATION; - } else if (MODIFIES_ALARMS.equals(component)) { - loaderId = LOADER_ID_ALARM; - } else { - return; - } - getLoaderManager().restartLoader(loaderId, args, ThemeFragment.this); - } - }; - - private void fadeOutNonSelectedCards(int selectedCardId) { - for (int i = 0; i < mCardIdsToComponentTypes.size(); i++) { - if (mCardIdsToComponentTypes.keyAt(i) != selectedCardId) { - ComponentCardView card = (ComponentCardView) getView().findViewById( - mCardIdsToComponentTypes.keyAt(i)); - card.animateCardFadeOut(); - } - } - } - - private void animateContentChange(int parentId, View viewToAnimate, Drawable overlay) { - ((ComponentCardView) getView().findViewById(parentId)) - .animateContentChange(viewToAnimate, overlay, ANIMATE_COMPONENT_CHANGE_DURATION); - } - - private Runnable mApplyThemeRunnable = new Runnable() { - @Override - public void run() { - final Context context = getActivity(); - if (context != null) { - if (mSelectedComponentsMap != null && mSelectedComponentsMap.size() > 0) { - if (!CURRENTLY_APPLIED_THEME.equals(mPkgName)) { - ThemeUtils.completeComponentMap(getActivity(), - mSelectedComponentsMap); - } - // Post this on mHandler so the client is added and removed from the same - // thread - mHandler.post(new Runnable() { - @Override - public void run() { - ThemeManager tm = getThemeManager(); - if (tm != null) { - // if this is not the "my theme" card, add missing components - // from defaults - tm.addClient(ThemeFragment.this); - tm.requestThemeChange(mSelectedComponentsMap); - } - } - }); - } - } - } - }; - - private void applyTheme() { - if (mSelectedComponentsMap == null || mSelectedComponentsMap.size() <= 0) return; - ((ChooserActivity) getActivity()).themeChangeStarted(); - animateProgressIn(mApplyThemeRunnable); - } - - private void animateProgressIn(Runnable endAction) { - mProgress.setVisibility(View.VISIBLE); - mProgress.setProgress(0); - float pivotX = mTitleLayout.getWidth() - - getResources().getDimensionPixelSize(R.dimen.apply_progress_padding); - ScaleAnimation scaleAnim = new ScaleAnimation(0f, 1f, 1f, 1f, - pivotX, 0f); - scaleAnim.setDuration(ANIMATE_PROGRESS_IN_DURATION); - - mTitleLayout.animate() - .translationXBy(-(pivotX / 4)) - .alpha(0f) - .setDuration(ANIMATE_TITLE_OUT_DURATION) - .setInterpolator(new AccelerateInterpolator()) - .withEndAction(endAction).start(); - mProgress.startAnimation(scaleAnim); - } - - private void animateProgressOut() { - mProgress.setVisibility(View.VISIBLE); - float pivotX = mTitleLayout.getWidth() - - getResources().getDimensionPixelSize(R.dimen.apply_progress_padding); - ScaleAnimation scaleAnim = new ScaleAnimation(1f, 0f, 1f, 1f, - pivotX, 0f); - scaleAnim.setDuration(ANIMATE_PROGRESS_OUT_DURATION); - scaleAnim.setFillAfter(false); - scaleAnim.setAnimationListener(new Animation.AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - } - - @Override - public void onAnimationEnd(Animation animation) { - mProgress.setVisibility(View.GONE); - } - - @Override - public void onAnimationRepeat(Animation animation) { - } - }); - - mTitleLayout.animate() - .translationXBy((pivotX / 4)) - .alpha(1f) - .setDuration(ANIMATE_TITLE_IN_DURATION) - .setInterpolator(new AccelerateInterpolator()) - .start(); - mProgress.startAnimation(scaleAnim); - } - - private void animateContentIn() { - AnimatorSet set = new AnimatorSet(); - set.setDuration(ANIMATE_TITLE_IN_DURATION); - set.play(ObjectAnimator.ofFloat(mLoadingView, "alpha", 1f, 0f)) - .with(ObjectAnimator.ofFloat(mTitleLayout, "alpha", 0f, 1f)); - set.addListener(new Animator.AnimatorListener() { - @Override - public void onAnimationStart(Animator animation) { - } - - @Override - public void onAnimationEnd(Animator animation) { - mLoadingView.setVisibility(View.GONE); - } - - @Override - public void onAnimationCancel(Animator animation) { - } - - @Override - public void onAnimationRepeat(Animator animation) { - } - }); - set.start(); - } - - public void fadeInCards() { - mActiveCardId = -1; - for (int i = 0; i < mCardIdsToComponentTypes.size(); i++) { - ComponentCardView card = (ComponentCardView) getView().findViewById( - mCardIdsToComponentTypes.keyAt(i)); - card.animateCardFadeIn(); - } - } - - public boolean componentsChanged() { - for (String key : mSelectedComponentsMap.keySet()) { - if (!mPkgName.equals(mSelectedComponentsMap.get(key))) { - return true; - } - } - return false; - } - - public void clearChanges() { - mSelectedComponentsMap.clear(); - getLoaderManager().restartLoader(LOADER_ID_ALL, null, ThemeFragment.this); - } - - private void uninstallTheme() { - Uri packageURI = Uri.parse("package:" + mPkgName); - Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageURI); - uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, true); - startActivityForResult(uninstallIntent, - ChooserActivity.REQUEST_UNINSTALL); - } - - public void onActivityResult (int requestCode, int resultCode, Intent data) { - if (requestCode == REQUEST_UNINSTALL) { - try { - ApplicationInfo ainfo = getActivity() - .getPackageManager().getApplicationInfo(mPkgName, 0); - } catch (PackageManager.NameNotFoundException e) { - mIsUninstalled = true; - } - } - } - - public boolean isUninstalled() { - return mIsUninstalled; - } - - public void setCurrentTheme(Map<String, String> currentTheme) { - mCurrentTheme = currentTheme; - } - - class AnimationLoader extends AsyncTask<Void, Void, Boolean> { - Context mContext; - String mPkgName; - BootAniImageView mBootAnim; - boolean mAutoStart; - - public AnimationLoader(Context context, String pkgName, BootAniImageView bootAnim) { - this(context, pkgName, bootAnim, false); - } - - public AnimationLoader(Context context, String pkgName, BootAniImageView bootAnim, - boolean autoStart) { - mContext = context; - mPkgName = pkgName; - mBootAnim = bootAnim; - mAutoStart = autoStart; - } - - @Override - protected void onPreExecute() { - super.onPreExecute(); - } - - @Override - protected Boolean doInBackground(Void... params) { - if (mContext == null) { - return Boolean.FALSE; - } - ZipFile zip = null; - if (ThemeConfig.HOLO_DEFAULT.equals(mPkgName)) { - try { - zip = new ZipFile(new File(BootAnimationHelper.SYSTEM_BOOT_ANI_PATH)); - } catch (Exception e) { - Log.w(TAG, "Unable to load boot animation", e); - return Boolean.FALSE; - } - } else { - // check if the bootanimation is cached - File f = new File(mContext.getCacheDir(), - mPkgName + BootAnimationHelper.CACHED_SUFFIX); - if (!f.exists()) { - // go easy on cache storage and clear out any previous boot animations - BootAnimationHelper.clearBootAnimationCache(mContext); - try { - Context themeContext = mContext.createPackageContext(mPkgName, 0); - AssetManager am = themeContext.getAssets(); - InputStream is = am.open("bootanimation/bootanimation.zip"); - FileUtils.copyToFile(is, f); - is.close(); - } catch (Exception e) { - Log.w(TAG, "Unable to load boot animation", e); - return Boolean.FALSE; - } - } - try { - zip = new ZipFile(f); - } catch (IOException e) { - Log.w(TAG, "Unable to load boot animation", e); - return Boolean.FALSE; - } - } - if (zip != null) { - mBootAnim.setBootAnimation(zip); - } else { - return Boolean.FALSE; - } - return Boolean.TRUE; - } - - @Override - protected void onPostExecute(Boolean isSuccess) { - super.onPostExecute(isSuccess); - if (isSuccess && mAutoStart) { - mBootAnim.start(); - } - } - } -} diff --git a/src/org/cyanogenmod/theme/chooserv2/WallpaperCardView.java b/src/org/cyanogenmod/theme/chooserv2/WallpaperCardView.java deleted file mode 100644 index 41c87f8..0000000 --- a/src/org/cyanogenmod/theme/chooserv2/WallpaperCardView.java +++ /dev/null @@ -1,118 +0,0 @@ -package org.cyanogenmod.theme.chooserv2; - -import android.animation.Animator; -import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; -import android.animation.ValueAnimator; -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewOverlay; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import org.cyanogenmod.theme.chooser.R; - -public class WallpaperCardView extends ComponentCardView { - protected ImageView mImage; - protected TextView mLabel; - - public WallpaperCardView(Context context) { - this(context, null); - } - - public WallpaperCardView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public WallpaperCardView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.WallpaperCardView); - String labelText = a.getString(R.styleable.WallpaperCardView_labelText); - a.recycle(); - - setOrientation(LinearLayout.VERTICAL); - - setBackgroundResource(R.drawable.card_bg); - - LayoutInflater inflater = LayoutInflater.from(mContext); - FrameLayout frameLayout = - (FrameLayout) inflater.inflate(R.layout.v2wallpaper_card, this, false); - addView(frameLayout); - mLabel = (TextView) frameLayout.findViewById(R.id.label); - mImage = (ImageView) frameLayout.findViewById(R.id.image); - - mLabel.setText(labelText); - } - - public void setWallpaper(Drawable drawable) { - mImage.setImageDrawable(drawable); - } - - @Override - public void expand(boolean showLabel) { - // Do nothing - } - - @Override - public void collapse() { - // Do nothing - } - - /** - * Animates a change in the content of the card - * @param v View in card to animate - * @param overlay Drawable to animate as a ViewOverlay - * @param duration Duration of animation - */ - @Override - public void animateContentChange(View v, final Drawable overlay, long duration) { - // Since the wallpaper IS the content, we will ignore the view passed in and animate - // the entire card - final ViewOverlay viewOverlay = this.getOverlay(); - viewOverlay.add(overlay); - final int x = 0; - final int y = 0; - final int width = v.getWidth(); - final int height = v.getHeight(); - overlay.setBounds(x, y, x + width, y + height); - - final ValueAnimator overlayAnimator = ValueAnimator.ofFloat(1f, 0f); - overlayAnimator.setDuration(duration); - overlayAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float value = (Float) animation.getAnimatedValue(); - overlay.setAlpha((int) (255 * value)); - } - - }); - overlayAnimator.addListener(new Animator.AnimatorListener() { - @Override - public void onAnimationStart(Animator animation) {} - - @Override - public void onAnimationEnd(Animator animation) { - // Clear out the ViewOverlay now that we are done animating - viewOverlay.clear(); - } - - @Override - public void onAnimationCancel(Animator animation) {} - - @Override - public void onAnimationRepeat(Animator animation) {} - }); - - AnimatorSet set = new AnimatorSet(); - set.play(ObjectAnimator.ofFloat(overlay, "alpha", 0f, 1f)) - .with(overlayAnimator); - set.start(); - } -} diff --git a/src/org/cyanogenmod/theme/util/AudioUtils.java b/src/org/cyanogenmod/theme/util/AudioUtils.java deleted file mode 100644 index bfbf674..0000000 --- a/src/org/cyanogenmod/theme/util/AudioUtils.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2014 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.util; - -import android.content.Context; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.ThemeUtils; -import android.content.res.AssetFileDescriptor; -import android.content.res.AssetManager; -import android.content.res.ThemeConfig; -import android.media.MediaPlayer; -import android.media.RingtoneManager; -import android.net.Uri; -import android.util.Log; - -import java.io.File; -import java.io.IOException; - -public class AudioUtils { - private static final String TAG = AudioUtils.class.getSimpleName(); - - public static void loadThemeAudible(Context context, int type, String pkgName, MediaPlayer mp) - throws PackageManager.NameNotFoundException { - if (ThemeConfig.HOLO_DEFAULT.equals(pkgName)) { - loadSystemAudible(type, mp); - return; - } - PackageInfo pi = context.getPackageManager().getPackageInfo(pkgName, 0); - Context themeCtx = context.createPackageContext(pkgName, 0); - if (pi.isLegacyThemeApk) { - loadLegacyThemeAudible(themeCtx, type, pi, mp); - return; - } - AssetManager assetManager = themeCtx.getAssets(); - String assetPath; - switch (type) { - case RingtoneManager.TYPE_ALARM: - assetPath = "alarms"; - break; - case RingtoneManager.TYPE_NOTIFICATION: - assetPath = "notifications"; - break; - case RingtoneManager.TYPE_RINGTONE: - assetPath = "ringtones"; - break; - default: - assetPath = null; - break; - } - if (assetPath != null) { - try { - String[] assetList = assetManager.list(assetPath); - if (assetList != null && assetList.length > 0) { - AssetFileDescriptor afd = assetManager.openFd(assetPath - + File.separator + assetList[0]); - if (mp != null) { - mp.reset(); - mp.setDataSource(afd.getFileDescriptor(), - afd.getStartOffset(), afd.getLength()); - mp.prepare(); - } - } - } catch (IOException e) { - Log.e(TAG, "Unable to load sound for " + pkgName, e); - } - } - } - - public static void loadLegacyThemeAudible(Context themeCtx, int type, PackageInfo pi, - MediaPlayer mp) { - if (pi.legacyThemeInfos == null || pi.legacyThemeInfos.length == 0) - return; - AssetManager assetManager = themeCtx.getAssets(); - String assetPath; - switch (type) { - case RingtoneManager.TYPE_NOTIFICATION: - assetPath = pi.legacyThemeInfos[0].notificationFileName; - break; - case RingtoneManager.TYPE_RINGTONE: - assetPath = pi.legacyThemeInfos[0].ringtoneFileName; - break; - default: - assetPath = null; - break; - } - if (assetPath != null) { - try { - AssetFileDescriptor afd = assetManager.openFd(assetPath); - if (mp != null) { - mp.reset(); - mp.setDataSource(afd.getFileDescriptor(), - afd.getStartOffset(), afd.getLength()); - mp.prepare(); - } - } catch (IOException e) { - Log.e(TAG, "Unable to load legacy sound for " + pi.packageName, e); - } - } - } - - public static void loadSystemAudible(int type, MediaPlayer mp) { - final String audiblePath = ThemeUtils.getDefaultAudiblePath(type); - if (audiblePath != null && (new File(audiblePath)).exists()) { - try { - mp.reset(); - mp.setDataSource(audiblePath); - mp.prepare(); - } catch (IOException e) { - Log.e(TAG, "Unable to load system sound " + audiblePath, e); - } - } - } - - public static Uri loadDefaultAudible(Context context, int type, MediaPlayer mp) - throws IOException { - Uri ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri(context, type); - mp.reset(); - mp.setDataSource(context, ringtoneUri); - mp.prepare(); - - return ringtoneUri; - } -} diff --git a/src/org/cyanogenmod/theme/util/BootAnimationHelper.java b/src/org/cyanogenmod/theme/util/BootAnimationHelper.java deleted file mode 100644 index 6d18ffb..0000000 --- a/src/org/cyanogenmod/theme/util/BootAnimationHelper.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (C) 2014 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.util; - -import android.app.ActivityManager; -import android.content.Context; -import android.content.res.ThemeConfig; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.os.AsyncTask; -import android.view.View; -import android.widget.ImageView; - -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import java.util.zip.ZipInputStream; - -public class BootAnimationHelper { - private static final int MAX_REPEAT_COUNT = 3; - - public static final String THEME_INTERNAL_BOOT_ANI_PATH = - "assets/bootanimation/bootanimation.zip"; - public static final String SYSTEM_BOOT_ANI_PATH = "/system/media/bootanimation.zip"; - public static final String CACHED_SUFFIX = "_bootanimation.zip"; - - public static class AnimationPart { - /** - * Number of times to play this part - */ - public int playCount; - /** - * If non-zero, pause for the given # of seconds before moving on to next part. - */ - public int pause; - /** - * The name of this part - */ - public String partName; - /** - * Time each frame is displayed - */ - public int frameRateMillis; - /** - * List of file names for the given frames in this part - */ - public List<String> frames; - /** - * width of the animation - */ - public int width; - /** - * height of the animation - */ - public int height; - - public AnimationPart(int playCount, int pause, String partName, int frameRateMillis, - int width, int height) { - this.playCount = playCount == 0 ? MAX_REPEAT_COUNT : playCount; - this.pause = pause; - this.partName = partName; - this.frameRateMillis = frameRateMillis; - this.width = width; - this.height = height; - frames = new ArrayList<String>(); - } - - public void addFrame(String frame) { - frames.add(frame); - } - } - - /** - * Gather up all the details for the given boot animation - * @param context - * @param zip The bootanimation.zip - * @return A list of AnimationPart if successful, null if not. - * @throws IOException - */ - public static List<AnimationPart> parseAnimation(Context context, ZipFile zip) - throws IOException { - List<AnimationPart> animationParts = null; - - ZipEntry ze = zip.getEntry("desc.txt"); - if (ze != null) { - animationParts = parseDescription(zip.getInputStream(ze)); - } - - if (animationParts == null) return null; - - for (AnimationPart a : animationParts) { - for (Enumeration<? extends ZipEntry> e = zip.entries();e.hasMoreElements();) { - ze = e.nextElement(); - if (!ze.isDirectory() && ze.getName().contains(a.partName)) { - a.addFrame(ze.getName()); - } - } - Collections.sort(a.frames); - } - - return animationParts; - } - - /** - * Parses the desc.txt of the boot animation - * @param in InputStream to the desc.txt - * @return A list of the parts as given in desc.txt - * @throws IOException - */ - private static List<AnimationPart> parseDescription(InputStream in) throws IOException { - BufferedReader reader = new BufferedReader(new InputStreamReader(in)); - String line = reader.readLine(); - String[] details = line.split(" "); - final int width = Integer.parseInt(details[0]); - final int height = Integer.parseInt(details[1]); - final int frameRateMillis = 1000 / Integer.parseInt(details[2]); - - List<AnimationPart> animationParts = new ArrayList<AnimationPart>(); - while ((line = reader.readLine()) != null) { - String[] info = line.split(" "); - if (info.length == 4 && (info[0].equals("p") || info[0].equals("c"))) { - int playCount = Integer.parseInt(info[1]); - int pause = Integer.parseInt(info[2]); - String name = info[3]; - AnimationPart ap = new AnimationPart(playCount, pause, name, frameRateMillis, - width, height); - animationParts.add(ap); - } - } - - return animationParts; - } - - public static String getPreviewFrameEntryName(InputStream is) throws IOException { - ZipInputStream zis = (is instanceof ZipInputStream) ? (ZipInputStream) is - : new ZipInputStream(new BufferedInputStream(is)); - ZipEntry ze; - // First thing to do is iterate over all the entries and the zip and store them - // for building the animations afterwards - String previewName = null; - while ((ze = zis.getNextEntry()) != null) { - final String entryName = ze.getName(); - if (entryName.contains("/") - && (entryName.endsWith(".png") || entryName.endsWith(".jpg"))) { - previewName = entryName; - } - } - - return previewName; - } - - public static Bitmap loadPreviewFrame(Context context, InputStream is, String previewName) - throws IOException { - ZipInputStream zis = (is instanceof ZipInputStream) ? (ZipInputStream) is - : new ZipInputStream(new BufferedInputStream(is)); - ZipEntry ze; - ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); - BitmapFactory.Options opts = new BitmapFactory.Options(); - opts.inSampleSize = am.isLowRamDevice() ? 4 : 2; - opts.inPreferredConfig = Bitmap.Config.RGB_565; - // First thing to do is iterate over all the entries and the zip and store them - // for building the animations afterwards - Bitmap preview = null; - while ((ze = zis.getNextEntry()) != null && preview == null) { - final String entryName = ze.getName(); - if (entryName.equals(previewName)) { - preview = BitmapFactory.decodeStream(zis, null, opts); - } - } - zis.close(); - - return preview; - } - - public static void clearBootAnimationCache(Context context) { - File cache = context.getCacheDir(); - if (cache.exists()) { - for(File f : cache.listFiles()) { - // volley stores stuff in cache so don't delete the volley directory - if(!f.isDirectory() && f.getName().endsWith(CACHED_SUFFIX)) f.delete(); - } - } - } - - public static class LoadBootAnimationImage extends AsyncTask<Object, Void, Bitmap> { - private ImageView imv; - private String path; - private Context context; - - public LoadBootAnimationImage(ImageView imv, Context context, String path) { - this.imv = imv; - this.context = context; - this.path = path; - } - - @Override - protected Bitmap doInBackground(Object... params) { - Bitmap bitmap = null; - String previewName = null; - // this is ugly, ugly, ugly. Did I mention this is ugly? - try { - if (ThemeConfig.HOLO_DEFAULT.equals(path)) { - previewName = getPreviewFrameEntryName( - new FileInputStream(SYSTEM_BOOT_ANI_PATH)); - bitmap = loadPreviewFrame( - context, new FileInputStream(SYSTEM_BOOT_ANI_PATH), previewName); - } else { - final Context themeCtx = context.createPackageContext(path, 0); - previewName = getPreviewFrameEntryName( - themeCtx.getAssets().open("bootanimation/bootanimation.zip")); - bitmap = loadPreviewFrame(context, - themeCtx.getAssets().open("bootanimation/bootanimation.zip"), - previewName); - } - } catch (Exception e) { - // don't care since a null bitmap will be returned - e.printStackTrace(); - } - return bitmap; - } - - @Override - protected void onPostExecute(Bitmap result) { - if (result != null && imv != null) { - imv.setVisibility(View.VISIBLE); - imv.setImageBitmap(result); - } - } - } -} diff --git a/src/org/cyanogenmod/theme/util/ChooserDetailLinearLayout.java b/src/org/cyanogenmod/theme/util/ChooserDetailLinearLayout.java deleted file mode 100644 index b178d03..0000000 --- a/src/org/cyanogenmod/theme/util/ChooserDetailLinearLayout.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2014 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.util; - -import android.content.Context; -import android.support.v4.view.ViewPager; -import android.util.AttributeSet; -import android.view.View; -import android.widget.LinearLayout; - - -/** - * This class will layout its children in a very specific way. It assumes it is a child of a - * scroll view. - * - * The first two children are assumed to be the "theme preview" and the "drawer handle" which will - * be visible. These children will be restricted in their size since they must be entirely visible. - * The third child will be shown as the user scrolls down and can take as much space as it needs. - */ -public class ChooserDetailLinearLayout extends LinearLayout { - - // The smaller this value the greater the effect - public final int PARALLAX_CONSTANT = 2; - - // Child indices - public final int THEME_PREVIEW_INDEX = 0; - public final int DRAWER_HANDLE_INDEX = 1; - public final int DRAWER_CONTENT_INDEX = 2; - public final int PAGE_INDICATOR_INDEX = 3; - - private ViewPager mPager; - - public ChooserDetailLinearLayout(Context context) { - super(context); - } - - public ChooserDetailLinearLayout(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public ChooserDetailLinearLayout(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - /** - * Assumes the heightMeasureSpec will be exact. This exact data will be used - * to determine the visible page size. - */ - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int heightSize = MeasureSpec.getSize(heightMeasureSpec); - - // Drawer handle is just author/title. Should get whatever space it needs - View drawerHandle = getChildAt(DRAWER_HANDLE_INDEX); - measureChildWithMargins(drawerHandle, widthMeasureSpec, 0, heightMeasureSpec, 0); - - // Give the theme preview the remainder - View themePreview = getChildAt(THEME_PREVIEW_INDEX); - int usedHeight = drawerHandle.getMeasuredHeight(); - measureChildWithMargins(themePreview, widthMeasureSpec, 0, heightMeasureSpec, usedHeight); - - // Give the drawer content as much as space as it needs. - View drawerContent = getChildAt(DRAWER_CONTENT_INDEX); - final MarginLayoutParams lp = (MarginLayoutParams) drawerContent.getLayoutParams(); - int childWidthSpec = getChildMeasureSpec(widthMeasureSpec, 0, lp.width); - int childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - drawerContent.measure(childWidthSpec, childHeightSpec); - - //Give the page indicator as much space as it needs - View pageIndicator = getChildAt(PAGE_INDICATOR_INDEX); - pageIndicator.measure(childWidthSpec, childHeightSpec); - - // Measure ourself - int width = drawerHandle.getMeasuredWidth(); - int height = themePreview.getMeasuredHeight() + - drawerHandle.getMeasuredHeight() + drawerContent.getMeasuredHeight(); - setMeasuredDimension(width, height); - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - super.onLayout(changed, l, t, r, b); - - // Place the page indicator above the drawer handle - View pageIndicator = getChildAt(PAGE_INDICATOR_INDEX); - int top = getChildAt(DRAWER_HANDLE_INDEX).getTop(); - int height = pageIndicator.getMeasuredHeight(); - pageIndicator.layout(l, top-height, r, top); - } - - public void onScrollChanged(int l, int t, int oldl, int oldt) { - // Give a parallax effect to the theme preview by scrolling in the - // opposite direction of the scrollview - int yScroll = (int) (-t / PARALLAX_CONSTANT); - getChildAt(THEME_PREVIEW_INDEX).scrollTo(0, yScroll); - } - - View getHandle() { - return getChildAt(DRAWER_HANDLE_INDEX); - } -} diff --git a/src/org/cyanogenmod/theme/util/ChooserDetailScrollView.java b/src/org/cyanogenmod/theme/util/ChooserDetailScrollView.java deleted file mode 100644 index 8734cae..0000000 --- a/src/org/cyanogenmod/theme/util/ChooserDetailScrollView.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2014 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.util; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.GestureDetector; -import android.view.MotionEvent; -import android.view.View; -import android.widget.ScrollView; - -/** - * A custom ScrollView capable of alerting its children when a scroll has changed. - * - * This custom view will also measure its children differently. Normally a child in scrollview - * receives an UNSPECIFIED MeasureSpec so that the child will size itself as large as it needs to be. - * - * In our case we want to have a unique layout where the first full page of the scrollview - * has very particular content - * ie the "drawer title/author", and the viewpager taking the remaining part of the screen", with the - * theme component checkboxes taking as much space as it needs. - * - **/ -public class ChooserDetailScrollView extends ScrollView { - private float xDistance; - private float yDistance; - private float lastX; - private float lastY; - - public ChooserDetailScrollView(Context context) { - super(context); - } - - public ChooserDetailScrollView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public ChooserDetailScrollView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - @Override - protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, - int parentHeightMeasureSpec, int heightUsed) { - final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); - - final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec, - mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin - + widthUsed, lp.width); - child.measure(childWidthMeasureSpec, parentHeightMeasureSpec); - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { - switch (ev.getAction()) { - case MotionEvent.ACTION_DOWN: - xDistance = yDistance = 0f; - lastX = ev.getX(); - lastY = ev.getY(); - break; - case MotionEvent.ACTION_MOVE: - final float curX = ev.getX(); - final float curY = ev.getY(); - xDistance = Math.abs(curX - lastX); - yDistance = Math.abs(curY - lastY); - lastX = curX; - lastY = curY; - if(xDistance > yDistance) return false; - } - - return super.onInterceptTouchEvent(ev); - } - - @Override - protected void onScrollChanged(int l, int t, int oldl, int oldt) { - super.onScrollChanged(l, t, oldl, oldt); - ((ChooserDetailLinearLayout)getChildAt(0)).onScrollChanged(l, t, oldl, oldt); - } - - public View getHandle() { - return ((ChooserDetailLinearLayout)getChildAt(0)).getHandle(); - } -} diff --git a/src/org/cyanogenmod/theme/util/ClickableViewPager.java b/src/org/cyanogenmod/theme/util/ClickableViewPager.java deleted file mode 100644 index 98364ea..0000000 --- a/src/org/cyanogenmod/theme/util/ClickableViewPager.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2014 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.util; - -import android.content.Context; -import android.support.v4.view.ViewPager; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.ViewConfiguration; - -/** - * Adds click functionality for the view pager since it not normally clickable - * and focus/clickable attributes have no impact on it. - */ -public class ClickableViewPager extends ViewPager { - private boolean mIsDragging = false; - private float mSlop; - private float mLastX; - private float mLastY; - - public ClickableViewPager(Context context) { - super(context); - initView(context); - } - - public ClickableViewPager(Context context, AttributeSet attrs) { - super(context, attrs); - initView(context); - } - - private void initView(Context context) { - mSlop = ViewConfiguration.get(context).getScaledTouchSlop(); - } - - @Override - public boolean onTouchEvent(MotionEvent ev) { - switch (ev.getAction()) { - case MotionEvent.ACTION_DOWN: - mLastX = ev.getX(); - mLastY = ev.getY(); - break; - case MotionEvent.ACTION_MOVE: - float xDist = Math.abs(mLastX - ev.getX()); - float yDist = Math.abs(mLastY - ev.getY()); - if (xDist > mSlop || yDist > mSlop) { - mIsDragging = true; - } - break; - case MotionEvent.ACTION_CANCEL: - mIsDragging = false; - break; - case MotionEvent.ACTION_UP: - if (!mIsDragging) { - performClick(); - } - mIsDragging = false; - break; - } - return super.onTouchEvent(ev); - } -}
\ No newline at end of file diff --git a/src/org/cyanogenmod/theme/util/CustomTypeFaceSpan.java b/src/org/cyanogenmod/theme/util/CustomTypeFaceSpan.java deleted file mode 100644 index 15650cd..0000000 --- a/src/org/cyanogenmod/theme/util/CustomTypeFaceSpan.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Author: Laurence Dawson - * Source: http://stackoverflow.com/questions/9618835/apply-two-different-font-styles-to-a-textview - */ -package org.cyanogenmod.theme.util; - - -import android.graphics.Paint; -import android.graphics.Typeface; -import android.text.TextPaint; -import android.text.style.TypefaceSpan; - -public class CustomTypeFaceSpan extends TypefaceSpan { - - public Typeface mTf; - - public CustomTypeFaceSpan(Typeface tf) { - super(""); - mTf = tf; - } - - @Override - public void updateDrawState(TextPaint ds) { - apply(ds); - - } - - @Override - public void updateMeasureState(TextPaint paint) { - apply(paint); - } - - private void apply(Paint paint) { - int oldStyle; - - Typeface old = paint.getTypeface(); - if (old == null) { - oldStyle = 0; - } else { - oldStyle = old.getStyle(); - } - - int fake = oldStyle & ~mTf.getStyle(); - - if ((fake & Typeface.BOLD) != 0) { - paint.setFakeBoldText(true); - } - - if ((fake & Typeface.ITALIC) != 0) { - paint.setTextSkewX(-0.25f); - } - - paint.setTypeface(mTf); - } -} diff --git a/src/org/cyanogenmod/theme/util/FittedTextView.java b/src/org/cyanogenmod/theme/util/FittedTextView.java deleted file mode 100644 index cbfe5b9..0000000 --- a/src/org/cyanogenmod/theme/util/FittedTextView.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2014 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.util; - -import android.content.Context; -import android.graphics.Paint; -import android.util.AttributeSet; -import android.util.TypedValue; -import android.widget.TextView; - -/** - * Change the font size to match the measured - * textview size by width - * - */ -public class FittedTextView extends TextView { - private Paint mPaint; - - public FittedTextView(Context context) { - super(context); - mPaint = new Paint(); - } - - public FittedTextView(Context context, AttributeSet attrs) { - super(context, attrs); - mPaint = new Paint(); - } - - public FittedTextView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - mPaint = new Paint(); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - final float THRESHOLD = 0.5f; - final float TARGET_WIDTH = getMeasuredWidth(); - final String text = getText().toString(); - mPaint.set(getPaint()); - - float max = 200; - float min = 2; - while(max > min) { - float size = (max+min) / 2; - mPaint.setTextSize(size); - float measuredWidth = mPaint.measureText(text); - if (Math.abs(TARGET_WIDTH - measuredWidth) <= THRESHOLD) { - break; - } else if (measuredWidth > TARGET_WIDTH) { - max = size-1; - } else { - min = size+1; - } - } - this.setTextSize(TypedValue.COMPLEX_UNIT_PX, min-1); - } -} diff --git a/src/org/cyanogenmod/theme/util/FontConfigParser.java b/src/org/cyanogenmod/theme/util/FontConfigParser.java deleted file mode 100644 index 1f0b1b1..0000000 --- a/src/org/cyanogenmod/theme/util/FontConfigParser.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2014 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.util; - -import android.util.Xml; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -/** - * Parses an XML font config. Example: - * - *<familyset> - * - * <family> - * <nameset> - * <name>sans-serif</name> - * <name>arial</name> - * </nameset> - * <fileset> - * <file>Roboto-Regular.ttf</file> - * <file>Roboto-Bold.ttf</file> - * <file>Roboto-Italic.ttf</file> - * <file>Roboto-BoldItalic.ttf</file> - * </fileset> - * </family> - * <family> - * ... - * </family> - *</familyset> - */ -public class FontConfigParser { - - public static class Family { - public List<String> nameset = new ArrayList<String>(); - public List<String> fileset = new ArrayList<String>(); - } - - public static List<Family> parse(InputStream in) throws XmlPullParserException, IOException { - try { - XmlPullParser parser = Xml.newPullParser(); - parser.setInput(in, null); - parser.nextTag(); - return readFamilySet(parser); - } finally { - in.close(); - } - } - - private static List<Family> readFamilySet(XmlPullParser parser) throws XmlPullParserException, IOException { - List<Family> families = new ArrayList<Family>(); - parser.require(XmlPullParser.START_TAG, null, "familyset"); - - while (parser.next() != XmlPullParser.END_TAG) { - if (parser.getEventType() != XmlPullParser.START_TAG) { - continue; - } - String name = parser.getName(); - - // Starts by looking for the entry tag - if (name.equals("family")) { - Family family = readFamily(parser); - families.add(family); - } - } - return families; - } - - private static Family readFamily(XmlPullParser parser) throws XmlPullParserException, IOException { - Family family = new Family(); - parser.require(XmlPullParser.START_TAG, null, "family"); - - while (parser.next() != XmlPullParser.END_TAG) { - if (parser.getEventType() != XmlPullParser.START_TAG) { - continue; - } - String name = parser.getName(); - if (name.equals("nameset")) { - List<String> nameset = readNameset(parser); - family.nameset = nameset; - } else if (name.equals("fileset")) { - List<String> fileset = readFileset(parser); - family.fileset = fileset; - } else { - skip(parser); - } - } - return family; - } - - private static List<String> readNameset(XmlPullParser parser) throws XmlPullParserException, IOException { - List<String> names = new ArrayList<String>(); - parser.require(XmlPullParser.START_TAG, null, "nameset"); - - while (parser.next() != XmlPullParser.END_TAG) { - if (parser.getEventType() != XmlPullParser.START_TAG) { - continue; - } - String tagname = parser.getName(); - if (tagname.equals("name")) { - String name = readText(parser); - names.add(name); - } else { - skip(parser); - } - } - return names; - } - - private static List<String> readFileset(XmlPullParser parser) throws XmlPullParserException, IOException { - List<String> files = new ArrayList<String>(); - parser.require(XmlPullParser.START_TAG, null, "fileset"); - - while (parser.next() != XmlPullParser.END_TAG) { - if (parser.getEventType() != XmlPullParser.START_TAG) { - continue; - } - String name = parser.getName(); - if (name.equals("file")) { - String file = readText(parser); - files.add(file); - } else { - skip(parser); - } - } - return files; - } - - // For the tags title and summary, extracts their text values. - private static String readText(XmlPullParser parser) throws IOException, XmlPullParserException { - String result = ""; - if (parser.next() == XmlPullParser.TEXT) { - result = parser.getText(); - parser.nextTag(); - } - return result; - } - - private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException { - if (parser.getEventType() != XmlPullParser.START_TAG) { - throw new IllegalStateException(); - } - int depth = 1; - while (depth != 0) { - switch (parser.next()) { - case XmlPullParser.END_TAG: - depth--; - break; - case XmlPullParser.START_TAG: - depth++; - break; - } - } - } -} diff --git a/src/org/cyanogenmod/theme/util/IconPreviewHelper.java b/src/org/cyanogenmod/theme/util/IconPreviewHelper.java deleted file mode 100644 index ce85fd1..0000000 --- a/src/org/cyanogenmod/theme/util/IconPreviewHelper.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (C) 2014 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.util; - -import android.app.ActivityManager; -import android.app.ComposedIconInfo; -import android.app.IconPackHelper; -import android.content.ComponentName; -import android.content.Context; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageItemInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.res.AssetManager; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.drawable.Drawable; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.SparseArray; - -/** - * This class handles all the logic to build a preview icon - * If the system currently has a theme applied we do NOT - * want this code to be impacted by it. So code in this - * class creates special "no theme attached" resource objects - * to retrieve objects from. - */ -public class IconPreviewHelper { - private static final String TAG = IconPreviewHelper.class.getSimpleName(); - private final static float ICON_SCALE_FACTOR = 1.3f; //Arbitrary. Looks good - - private Context mContext; - private DisplayMetrics mDisplayMetrics; - private Configuration mConfiguration; - private int mIconDpi = 0; - private String mThemePkgName; - private IconPackHelper mIconPackHelper; - private int mIconSize; - - /** - * @param themePkgName - The package name of the theme we wish to preview - */ - public IconPreviewHelper(Context context, String themePkgName) { - mContext = context; - mDisplayMetrics = context.getResources().getDisplayMetrics(); - mConfiguration = context.getResources().getConfiguration(); - ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); - mIconDpi = (int) (am.getLauncherLargeIconDensity() * ICON_SCALE_FACTOR); - mThemePkgName = themePkgName; - mIconPackHelper = new IconPackHelper(mContext); - try { - mIconPackHelper.loadIconPack(mThemePkgName); - } catch (NameNotFoundException e) {} - mIconSize = (int) (am.getLauncherLargeIconSize() * ICON_SCALE_FACTOR); - } - - /** - * Returns the actual label name for a given component - * If the activity does not have a label it will return app's label - * If neither has a label returns empty string - */ - public String getLabel(ComponentName component) { - String label = ""; - try { - PackageManager pm = mContext.getPackageManager(); - ApplicationInfo appInfo = pm.getApplicationInfo(component.getPackageName(), 0); - ActivityInfo activityInfo = pm.getActivityInfo(component, 0); - - AssetManager assets = new AssetManager(); - assets.addAssetPath(appInfo.publicSourceDir); - Resources res = new Resources(assets, mDisplayMetrics, mConfiguration); - - if (activityInfo.labelRes != 0) { - label = res.getString(activityInfo.labelRes); - } else if (appInfo.labelRes != 0) { - label = res.getString(appInfo.labelRes); - } - } catch(NameNotFoundException exception) { - Log.e(TAG, "unable to find pkg for " + component.toString()); - } - return label; - } - - /** - * Returns the icon for the given component regardless of the system's - * currently applied theme. If the preview theme does not support the icon, then - * return the system default icon. - */ - public Drawable getIcon(ComponentName component) { - String packageName = component.getPackageName(); - String activityName = component.getClassName(); - Drawable icon = getThemedIcon(packageName, activityName); - if (icon == null) { - icon = getDefaultIcon(packageName, activityName); - } - if (icon != null) { - icon.setBounds(0, 0, mIconSize, mIconSize); - } - return icon; - } - - private Drawable getThemedIcon(String pkgName, String activityName) { - Drawable drawable = null; - ActivityInfo info = new ActivityInfo(); - info.packageName = pkgName; - info.name = activityName; - drawable = mIconPackHelper.getDrawableForActivityWithDensity(info, mIconDpi); - - return drawable; - } - - /** - * Returns the default icon. This can be the normal icon associated with the app or a composed - * icon if the icon pack supports background, mask, and/or foreground. - * @param pkgName - * @param activityName - * @return - */ - public Drawable getDefaultIcon(String pkgName, String activityName) { - Drawable drawable = null; - ComponentName component = new ComponentName(pkgName, activityName); - PackageManager pm = mContext.getPackageManager(); - Resources res = null; - try { - ActivityInfo info = pm.getActivityInfo(component, 0); - ApplicationInfo appInfo = pm.getApplicationInfo(pkgName, 0); - - AssetManager assets = new AssetManager(); - assets.addAssetPath(appInfo.publicSourceDir); - res = new Resources(assets, mDisplayMetrics, mConfiguration); - - final int iconId = info.icon != 0 ? info.icon : appInfo.icon; - info.themedIcon = 0; - setupComposedIcon(res, info, iconId); - drawable = getFullResIcon(res, iconId); - } catch (NameNotFoundException e2) { - Log.w(TAG, "Unable to get the icon for " + pkgName + " using default"); - } - drawable = (drawable != null) ? - getComposedIcon(res, drawable) : getFullResDefaultActivityIcon(); - return drawable; - } - - private Drawable getComposedIcon(Resources res, Drawable baseIcon) { - ComposedIconInfo iconInfo = mIconPackHelper.getComposedIconInfo(); - if (res != null && iconInfo != null && (iconInfo.iconBacks != null || - iconInfo.iconMask != null || iconInfo.iconUpon != null)) { - return IconPackHelper.IconCustomizer.getComposedIconDrawable(baseIcon, res, iconInfo); - } - return baseIcon; - } - - private void setupComposedIcon(Resources res, ActivityInfo info, int iconId) { - ComposedIconInfo iconInfo = mIconPackHelper.getComposedIconInfo(); - if (iconInfo.iconBacks == null && iconInfo.iconMask == null && iconInfo.iconUpon == null) { - return; - } - - res.setComposedIconInfo(iconInfo); - - SparseArray<PackageItemInfo> icons = new SparseArray<PackageItemInfo>(1); - info.themedIcon = 0; - icons.put(iconId, info); - res.setIconResources(icons); - } - - private Drawable getFullResIcon(Resources resources, int iconId) { - Drawable d; - try { - d = resources.getDrawableForDensity(iconId, mIconDpi, false); - } catch (Resources.NotFoundException e) { - d = null; - } - return (d != null) ? d : getFullResDefaultActivityIcon(); - } - - private Drawable getFullResDefaultActivityIcon() { - return getFullResIcon(Resources.getSystem(), android.R.mipmap.sym_def_app_icon); - } -} diff --git a/src/org/cyanogenmod/theme/util/NotificationHelper.java b/src/org/cyanogenmod/theme/util/NotificationHelper.java deleted file mode 100644 index 9eaf261..0000000 --- a/src/org/cyanogenmod/theme/util/NotificationHelper.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2014 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.util; - -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.graphics.BitmapFactory; -import android.text.TextUtils; -import org.cyanogenmod.theme.chooser.ChooserActivity; -import org.cyanogenmod.theme.chooser.R; - -public class NotificationHelper { - public static void postThemeInstalledNotification(Context context, String pkgName) { - String themeName = null; - try { - PackageInfo pi = context.getPackageManager().getPackageInfo(pkgName, 0); - if (pi.themeInfos != null && pi.themeInfos.length > 0) { - themeName = pi.themeInfos[0].name; - } else if (pi.legacyThemeInfos != null && pi.legacyThemeInfos[0] != null) { - themeName = pi.legacyThemeInfos[0].name; - } - } catch (PackageManager.NameNotFoundException e) { - e.printStackTrace(); - return; - } - if (TextUtils.isEmpty(themeName)) { - return; - } - - Intent intent = new Intent(context, ChooserActivity.class); - intent.setAction(Intent.ACTION_MAIN); - intent.putExtra("pkgName", pkgName); - PendingIntent pi = PendingIntent.getActivity(context, 0, intent, - PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT); - - NotificationManager nm = - (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - Notification notice = new Notification.Builder(context) - .setAutoCancel(true) - .setOngoing(false) - .setContentTitle(String.format( - context.getString(R.string.theme_installed_notification_title), themeName)) - .setContentText(context.getString(R.string.theme_installed_notification_text)) - .setContentIntent(pi) - .setSmallIcon(R.drawable.ic_notifiy) - .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), - R.drawable.ic_app_themes)) - .setWhen(System.currentTimeMillis()) - .build(); - nm.notify(pkgName.hashCode(), notice); - } - - public static void cancelNotificationForPackage(Context context, String pkgName) { - NotificationManager nm = (NotificationManager) - context.getSystemService(Context.NOTIFICATION_SERVICE); - nm.cancel(pkgName.hashCode()); - } -} diff --git a/src/org/cyanogenmod/theme/util/ThemedTypefaceHelper.java b/src/org/cyanogenmod/theme/util/ThemedTypefaceHelper.java deleted file mode 100644 index 67d7b33..0000000 --- a/src/org/cyanogenmod/theme/util/ThemedTypefaceHelper.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2014 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.util; - -import android.content.Context; -import android.content.pm.ThemeUtils; -import android.content.res.AssetManager; -import android.graphics.Typeface; -import android.util.Log; - -import org.cyanogenmod.theme.util.FontConfigParser.Family; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.util.List; - -/** - * Assists in loading a themes font typefaces. - * Will load system default if there is a load issue - */ -public class ThemedTypefaceHelper { - private static final String TAG = ThemedTypefaceHelper.class.getName(); - private static final String FAMILY_SANS_SERIF = "sans-serif"; - private static final String FONTS_DIR = "fonts/"; - private static final String SYSTEM_FONTS_XML = "/system/etc/system_fonts.xml"; - private static final String SYSTEM_FONTS_DIR = "/system/fonts/"; - - private boolean mIsLoaded; - private Context mThemeContext; - private List<Family> mFamilies; - private Typeface[] mTypefaces = new Typeface[4]; - - public void load(Context context, String pkgName) { - try { - loadThemedFonts(context, pkgName); - return; - } catch(Exception e) { - Log.w(TAG, "Unable to parse and load themed fonts. Falling back to system fonts"); - } - - try { - loadSystemFonts(); - return; - } catch(Exception e) { - Log.e(TAG, "Parsing system fonts failed. Falling back to Typeface loaded fonts"); - - } - - // There is no reason for this to happen unless someone - // messed up the system_fonts.xml - loadDefaultFonts(); - } - - private void loadThemedFonts(Context context, String pkgName) throws Exception { - //Parse the font XML - mThemeContext = context.createPackageContext(pkgName, Context.CONTEXT_IGNORE_SECURITY); - AssetManager assetManager = mThemeContext.getAssets(); - InputStream is = assetManager.open(FONTS_DIR + ThemeUtils.FONT_XML); - mFamilies = FontConfigParser.parse(is); - - //Load the typefaces for sans-serif - Family sanSerif = getFamily(FAMILY_SANS_SERIF); - mTypefaces[Typeface.NORMAL] = loadTypeface(sanSerif, Typeface.NORMAL); - mTypefaces[Typeface.BOLD] = loadTypeface(sanSerif, Typeface.BOLD); - mTypefaces[Typeface.ITALIC] = loadTypeface(sanSerif, Typeface.ITALIC); - mTypefaces[Typeface.BOLD_ITALIC] = loadTypeface(sanSerif, Typeface.BOLD_ITALIC); - mIsLoaded = true; - } - - private void loadSystemFonts() throws Exception { - //Parse the system font XML - File file = new File(SYSTEM_FONTS_XML); - InputStream is = new FileInputStream(file); - mFamilies = FontConfigParser.parse(is); - - //Load the typefaces for sans-serif - Family sanSerif = getFamily(FAMILY_SANS_SERIF); - if (mTypefaces[Typeface.NORMAL] == null) { - mTypefaces[Typeface.NORMAL] = loadSystemTypeface(sanSerif, Typeface.NORMAL); - } - if (mTypefaces[Typeface.BOLD] == null) { - mTypefaces[Typeface.BOLD] = loadSystemTypeface(sanSerif, Typeface.BOLD); - } - if (mTypefaces[Typeface.ITALIC] == null) { - mTypefaces[Typeface.ITALIC] = loadSystemTypeface(sanSerif, Typeface.ITALIC); - } - if (mTypefaces[Typeface.BOLD_ITALIC] == null) { - mTypefaces[Typeface.BOLD_ITALIC] = loadSystemTypeface(sanSerif, Typeface.BOLD_ITALIC); - } - mIsLoaded = true; - } - - private void loadDefaultFonts() { - mTypefaces[Typeface.NORMAL] = Typeface.DEFAULT; - mTypefaces[Typeface.BOLD] = Typeface.DEFAULT_BOLD; - mIsLoaded = true; - } - - private Family getFamily(String familyName) throws Exception { - for(Family family : mFamilies) { - if (family.nameset.contains(familyName)) { - return family; - } - } - throw new Exception("Unable to find " + familyName); - } - - private Typeface loadTypeface(Family family, int style) { - AssetManager assets = mThemeContext.getAssets(); - String path = FONTS_DIR + family.fileset.get(style); - return Typeface.createFromAsset(assets, path); - } - - private Typeface loadSystemTypeface(Family family, int style) { - return Typeface.createFromFile(SYSTEM_FONTS_DIR + family.fileset.get(style)); - } - - public Typeface getTypeface(int style) { - if (!mIsLoaded) throw new IllegalStateException("Helper was not loaded"); - return mTypefaces[style]; - } -} diff --git a/src/org/cyanogenmod/theme/util/TypefaceHelperCache.java b/src/org/cyanogenmod/theme/util/TypefaceHelperCache.java deleted file mode 100644 index bba04f1..0000000 --- a/src/org/cyanogenmod/theme/util/TypefaceHelperCache.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2014 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.util; - -import android.content.Context; - -import java.util.HashMap; -import java.util.Map; - -public class TypefaceHelperCache { - private static TypefaceHelperCache sHelperCache; - private final Map<String, ThemedTypefaceHelper> mCache; - - private TypefaceHelperCache() { - mCache = new HashMap<String, ThemedTypefaceHelper>(); - } - - public static synchronized TypefaceHelperCache getInstance() { - if (sHelperCache == null) { - sHelperCache = new TypefaceHelperCache(); - } - return sHelperCache; - } - - public ThemedTypefaceHelper getHelperForTheme(Context context, String pkgName) { - synchronized (mCache) { - ThemedTypefaceHelper helper = mCache.get(pkgName); - if (helper == null) { - helper = new ThemedTypefaceHelper(); - helper.load(context, pkgName); - mCache.put(pkgName, helper); - } - return helper; - } - } - - public int getTypefaceCount() { - synchronized (mCache) { - return mCache.size(); - } - } -} diff --git a/src/org/cyanogenmod/theme/util/Utils.java b/src/org/cyanogenmod/theme/util/Utils.java deleted file mode 100644 index 747eb42..0000000 --- a/src/org/cyanogenmod/theme/util/Utils.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (C) 2014 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.util; - -import android.content.Context; -import android.content.res.AssetManager; -import android.content.res.Resources; -import android.database.Cursor; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.BitmapRegionDecoder; -import android.graphics.Rect; -import android.provider.ThemesContract; -import android.util.Log; -import android.util.TypedValue; -import android.view.ViewConfiguration; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class Utils { - private static final String TAG = Utils.class.getSimpleName(); - - public static Bitmap decodeFile(String path, int reqWidth, int reqHeight) { - BitmapFactory.Options opts = new BitmapFactory.Options(); - - // Determine insample size - opts.inJustDecodeBounds = true; - BitmapFactory.decodeFile(path, opts); - opts.inSampleSize = calculateInSampleSize(opts, reqWidth, reqHeight); - - // Decode the bitmap, regionally if necessary - Bitmap bitmap = null; - opts.inJustDecodeBounds = false; - Rect rect = getCropRectIfNecessary(opts, reqWidth, reqHeight); - try { - if (rect != null) { - BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(path, false); - // Check if we can downsample more now that we cropped - opts.inSampleSize = calculateInSampleSize(rect.width(), rect.height(), - reqWidth, reqHeight); - bitmap = decoder.decodeRegion(rect, opts); - } else { - bitmap = BitmapFactory.decodeFile(path, opts); - } - } catch (IOException e) { - Log.e(TAG, "Unable to open resource in path" + path, e); - } - return bitmap; - } - - public static Bitmap decodeResource(Resources res, int resId, int reqWidth, int reqHeight) { - BitmapFactory.Options opts = new BitmapFactory.Options(); - - // Determine insample size - opts.inJustDecodeBounds = true; - BitmapFactory.decodeResource(res, resId, opts); - opts.inSampleSize = calculateInSampleSize(opts, reqWidth, reqHeight); - - // Decode the bitmap, regionally if necessary - Bitmap bitmap = null; - opts.inJustDecodeBounds = false; - Rect rect = getCropRectIfNecessary(opts, reqWidth, reqHeight); - - InputStream stream = null; - try { - if (rect != null) { - stream = res.openRawResource(resId, new TypedValue()); - if (stream == null) return null; - BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(stream, false); - // Check if we can downsample a little more now that we cropped - opts.inSampleSize = calculateInSampleSize(rect.width(), rect.height(), - reqWidth, reqHeight); - bitmap = decoder.decodeRegion(rect, opts); - } else { - bitmap = BitmapFactory.decodeResource(res, resId, opts); - } - } catch (IOException e) { - Log.e(TAG, "Unable to open resource " + resId, e); - } finally { - closeQuiet(stream); - } - return bitmap; - } - - - public static Bitmap getBitmapFromAsset(Context ctx, String path,int reqWidth, int reqHeight) { - if (ctx == null || path == null) - return null; - - String ASSET_BASE = "file:///android_asset/"; - path = path.substring(ASSET_BASE.length()); - - - Bitmap bitmap = null; - try { - AssetManager assets = ctx.getAssets(); - InputStream is = assets.open(path); - - // Determine insample size - BitmapFactory.Options opts = new BitmapFactory.Options(); - opts.inJustDecodeBounds = true; - BitmapFactory.decodeStream(is, null, opts); - opts.inSampleSize = calculateInSampleSize(opts, reqWidth, reqHeight); - is.close(); - - // Decode the bitmap, regionally if neccessary - is = assets.open(path); - opts.inJustDecodeBounds = false; - Rect rect = getCropRectIfNecessary(opts, reqWidth, reqHeight); - if (rect != null) { - BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(is, false); - // Check if we can downsample a little more now that we cropped - opts.inSampleSize = calculateInSampleSize(rect.width(), rect.height(), - reqWidth, reqHeight); - bitmap = decoder.decodeRegion(rect, opts); - } else { - bitmap = BitmapFactory.decodeStream(is); - } - } catch (IOException e) { - e.printStackTrace(); - } - return bitmap; - } - - - /** - * For excessively large images with an awkward ratio we - * will want to crop them - * @return - */ - public static Rect getCropRectIfNecessary( - BitmapFactory.Options options,int reqWidth, int reqHeight) { - Rect rect = null; - // Determine downsampled size - int width = options.outWidth / options.inSampleSize; - int height = options.outHeight / options.inSampleSize; - - if ((reqHeight * 1.5 < height)) { - int bottom = height/ 4; - int top = bottom + height/2; - rect = new Rect(0, bottom, width, top); - } else if ((reqWidth * 1.5 < width)) { - int left = width / 4; - int right = left + height/2; - rect = new Rect(left, 0, right, height); - } - return rect; - } - - public static int calculateInSampleSize( - BitmapFactory.Options options, int reqWidth, int reqHeight) { - return calculateInSampleSize(options.outWidth, options.outHeight, reqWidth, reqHeight); - } - - // Modified from original source: - // http://developer.android.com/training/displaying-bitmaps/load-bitmap.html - public static int calculateInSampleSize( - int decodeWidth, int decodeHeight, int reqWidth, int reqHeight) { - // Raw height and width of image - int inSampleSize = 1; - - if (decodeHeight > reqHeight || decodeWidth > reqWidth) { - final int halfHeight = decodeHeight / 2; - final int halfWidth = decodeWidth / 2; - - // Calculate the largest inSampleSize value that is a power of 2 and keeps both - // height and width larger than the requested height and width. - while ((halfHeight / inSampleSize) > reqHeight && - (halfWidth / inSampleSize) > reqWidth) { - inSampleSize *= 2; - } - } - - return inSampleSize; - } - - public static InputStream getInputStreamFromAsset( - Context ctx, String path) throws IOException { - if (ctx == null || path == null) - return null; - InputStream is = null; - String ASSET_BASE = "file:///android_asset/"; - path = path.substring(ASSET_BASE.length()); - AssetManager assets = ctx.getAssets(); - is = assets.open(path); - return is; - } - - public static void copy(InputStream is, OutputStream os) throws IOException { - final byte[] bytes = new byte[4096]; - int len; - while ((len = is.read(bytes)) > 0) { - os.write(bytes, 0, len); - } - } - - public static void closeQuiet(InputStream stream) { - if (stream == null) - return; - try { - stream.close(); - } catch (IOException e) { - } - } - - public static void closeQuiet(OutputStream stream) { - if (stream == null) - return; - try { - stream.close(); - } catch (IOException e) { - } - } - - //Note: will not delete populated subdirs - public static void deleteFilesInDir(String dirPath) { - File fontDir = new File(dirPath); - File[] files = fontDir.listFiles(); - if (files != null) { - for(File file : fontDir.listFiles()) { - file.delete(); - } - } - } - - public static boolean hasNavigationBar(Context context) { - return !ViewConfiguration.get(context).hasPermanentMenuKey(); - } - - public static Bitmap loadBitmapBlob(Cursor cursor, int columnIdx) { - if (columnIdx < 0) { - Log.w(TAG, "loadBitmapBlob(): Invalid index provided, returning null"); - return null; - } - byte[] blob = cursor.getBlob(columnIdx); - if (blob == null) return null; - return BitmapFactory.decodeByteArray(blob, 0, blob.length); - } - - public static String getBatteryIndex(int type) { - switch(type) { - case 2: - return ThemesContract.PreviewColumns.STATUSBAR_BATTERY_CIRCLE; - case 5: - return ThemesContract.PreviewColumns.STATUSBAR_BATTERY_LANDSCAPE; - default: - return ThemesContract.PreviewColumns.STATUSBAR_BATTERY_PORTRAIT; - } - } - -} diff --git a/src/org/cyanogenmod/theme/widget/BootAniImageView.java b/src/org/cyanogenmod/theme/widget/BootAniImageView.java deleted file mode 100644 index 16d2ddf..0000000 --- a/src/org/cyanogenmod/theme/widget/BootAniImageView.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2014 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.widget; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.util.AttributeSet; -import android.util.Log; -import android.widget.ImageView; -import libcore.io.IoUtils; -import org.cyanogenmod.theme.util.BootAnimationHelper; - -import java.io.IOException; -import java.util.List; -import java.util.zip.ZipFile; - -public class BootAniImageView extends ImageView { - private static final String TAG = BootAniImageView.class.getName(); - - private static final int MAX_BUFFERS = 2; - - private Bitmap[] mBuffers = new Bitmap[MAX_BUFFERS]; - private int mReadBufferIndex = 0; - private int mWriteBufferIndex = 0; - private ZipFile mBootAniZip; - - private List<BootAnimationHelper.AnimationPart> mAnimationParts; - private int mCurrentPart; - private int mCurrentFrame; - private int mCurrentPartPlayCount; - private int mFrameDuration; - - private boolean mActive = false; - - public BootAniImageView(Context context) { - this(context, null); - } - - public BootAniImageView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public BootAniImageView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - @Override - public void setVisibility(int visibility) { - super.setVisibility(visibility); - if (visibility == VISIBLE) { - if (mBootAniZip != null) start(); - } else { - stop(); - } - } - - @Override - protected void onDraw(Canvas canvas) { - // In case we end up in the mid dle of onDraw while the buffers are being recycled - // we catch the exception and just let frame not be rendered. - try { - super.onDraw(canvas); - } catch (RuntimeException e) { - Log.e(TAG, "Unable to draw boot animation frame."); - } - } - - public synchronized boolean setBootAnimation(ZipFile bootAni) { - // make sure we are stopped first - stop(); - - if (mBootAniZip != null) { - IoUtils.closeQuietly(mBootAniZip); - // This boot animation may be a different size than the previous - // one so clear out the buffers so they can be recreated with - // the correct size. - for (int i = 0; i < MAX_BUFFERS; i++) { - if (mBuffers[i] != null) { - mBuffers[i].recycle(); - mBuffers[i] = null; - } - } - } - mBootAniZip = bootAni; - try { - mAnimationParts = BootAnimationHelper.parseAnimation(mContext, mBootAniZip); - } catch (IOException e) { - return false; - } - - final BootAnimationHelper.AnimationPart part = mAnimationParts.get(0); - mCurrentPart = 0; - mCurrentPartPlayCount = part.playCount; - mFrameDuration = part.frameRateMillis; - mWriteBufferIndex = mReadBufferIndex = 0; - mCurrentFrame = 0; - - getNextFrame(); - - return true; - } - - private void getNextFrame() { - BitmapFactory.Options opts = new BitmapFactory.Options(); - opts.inBitmap = mBuffers[mWriteBufferIndex]; - opts.inPreferredConfig = Bitmap.Config.RGB_565; - opts.inMutable = true; - final BootAnimationHelper.AnimationPart part = mAnimationParts.get(mCurrentPart); - try { - mBuffers[mWriteBufferIndex] = - BitmapFactory.decodeStream(mBootAniZip.getInputStream(mBootAniZip.getEntry( - part.frames.get(mCurrentFrame++))), null, opts); - } catch (Exception e) { - Log.w(TAG, "Unable to get next frame", e); - } - mWriteBufferIndex = (mWriteBufferIndex + 1) % MAX_BUFFERS; - if (mCurrentFrame >= part.frames.size()) { - if (mCurrentPartPlayCount > 0) { - if (--mCurrentPartPlayCount == 0) { - mCurrentPart++; - if (mCurrentPart >= mAnimationParts.size()) mCurrentPart = 0; - mCurrentFrame = 0; - mCurrentPartPlayCount = mAnimationParts.get(mCurrentPart).playCount; - } else { - mCurrentFrame = 0; - } - } else { - mCurrentFrame = 0; - } - } - } - - public void start() { - mActive = true; - post(mUpdateAnimationRunnable); - } - - public void stop() { - mActive = false; - removeCallbacks(mUpdateImageRunnable); - removeCallbacks(mUpdateAnimationRunnable); - } - - private Runnable mUpdateAnimationRunnable = new Runnable() { - @Override - public void run() { - if (!mActive) return; - BootAniImageView.this.postDelayed(mUpdateAnimationRunnable, mFrameDuration); - if (!isOffScreen()) { - BootAniImageView.this.post(mUpdateImageRunnable); - mReadBufferIndex = (mReadBufferIndex + 1) % MAX_BUFFERS; - getNextFrame(); - } - } - }; - - private Runnable mUpdateImageRunnable = new Runnable() { - @Override - public void run() { - setImageBitmap(mBuffers[mReadBufferIndex]); - } - }; - - private boolean isOffScreen() { - int[] pos = new int[2]; - getLocationOnScreen(pos); - return pos[1] >= mContext.getResources().getDisplayMetrics().heightPixels; - } -} |