diff options
-rw-r--r-- | AndroidManifest.xml | 3 | ||||
-rw-r--r-- | res/layout/fragment_pager_list.xml | 1 | ||||
-rw-r--r-- | res/layout/processing_layout.xml | 22 | ||||
-rw-r--r-- | res/values/colors.xml | 2 | ||||
-rw-r--r-- | res/values/strings.xml | 2 | ||||
-rw-r--r-- | src/com/cyngn/theme/chooser/AppReceiver.java | 27 | ||||
-rw-r--r-- | src/com/cyngn/theme/chooser/ThemeFragment.java | 63 | ||||
-rw-r--r-- | src/com/cyngn/theme/util/PreferenceUtils.java | 39 |
8 files changed, 156 insertions, 3 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 4722ac9..5f894f5 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -67,6 +67,9 @@ android:name="com.tmobile.intent.category.THEME_PACKAGE_INSTALL_STATE_CHANGE" /> <data android:scheme="package" /> </intent-filter> + <intent-filter> + <action android:name="android.intent.action.THEME_RESOURCES_CACHED" /> + </intent-filter> </receiver> <service android:name="com.cyngn.theme.chooser.NotificationHijackingService" diff --git a/res/layout/fragment_pager_list.xml b/res/layout/fragment_pager_list.xml index c562080..ccc301a 100644 --- a/res/layout/fragment_pager_list.xml +++ b/res/layout/fragment_pager_list.xml @@ -48,6 +48,7 @@ </LinearLayout> <include layout="@layout/confirm_cancel_overlay"/> <include layout="@layout/customize_reset_theme_layout"/> + <include layout="@layout/processing_layout"/> <View android:id="@+id/clickable_view" android:layout_width="match_parent" diff --git a/res/layout/processing_layout.xml b/res/layout/processing_layout.xml new file mode 100644 index 0000000..9e8bc25 --- /dev/null +++ b/res/layout/processing_layout.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2014 Cyanogen, Inc. +--> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/processing_theme_layout" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:visibility="gone" + android:background="@color/apply_overlay_background"> + + <com.cyngn.theme.widget.LatoTextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:gravity="center" + android:textSize="20sp" + android:textAllCaps="true" + android:textColor="@color/processing_text_color" + android:text="@string/processing_theme" /> + +</FrameLayout>
\ No newline at end of file diff --git a/res/values/colors.xml b/res/values/colors.xml index 2f51e9d..15d86f0 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -53,4 +53,6 @@ <color name="theme_title_text_color">#78000000</color> <color name="theme_author_text_color">#40000000</color> + <color name="processing_text_color">#ffffff</color> + </resources> diff --git a/res/values/strings.xml b/res/values/strings.xml index 6a0547f..ca09f9d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -71,4 +71,6 @@ <string name="wallpaper_external_title">Pick image</string> <string name="wallpaper_none_title">None</string> + <string name="processing_theme">Processing</string> + </resources> diff --git a/src/com/cyngn/theme/chooser/AppReceiver.java b/src/com/cyngn/theme/chooser/AppReceiver.java index 2ef37e1..257aa65 100644 --- a/src/com/cyngn/theme/chooser/AppReceiver.java +++ b/src/com/cyngn/theme/chooser/AppReceiver.java @@ -7,11 +7,15 @@ import android.content.BroadcastReceiver; 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.ThemeManager; import android.net.Uri; import com.cyngn.theme.util.NotificationHelper; import com.cyngn.theme.util.PreferenceUtils; +import java.util.Set; + public class AppReceiver extends BroadcastReceiver { @Override @@ -24,7 +28,12 @@ public class AppReceiver extends BroadcastReceiver { if (Intent.ACTION_PACKAGE_ADDED.equals(action) && !isReplacing) { try { if (isTheme(context, pkgName)) { - NotificationHelper.postThemeInstalledNotification(context, pkgName); + if (!isThemeBeingProcessed(context, pkgName)) { + NotificationHelper.postThemeInstalledNotification(context, pkgName); + } else { + // store this package name so we know it's being processed + PreferenceUtils.addThemeBeingProcessed(context, pkgName); + } } } catch (NameNotFoundException e) { } @@ -43,6 +52,17 @@ public class AppReceiver extends BroadcastReceiver { } } catch (NameNotFoundException e) { } + } else if (Intent.ACTION_THEME_RESOURCES_CACHED.equals(action)) { + final String themePkgName = intent.getStringExtra(Intent.EXTRA_THEME_PACKAGE_NAME); + final int result = intent.getIntExtra(Intent.EXTRA_THEME_RESULT, + PackageManager.INSTALL_FAILED_THEME_UNKNOWN_ERROR); + Set<String> processingThemes = + PreferenceUtils.getInstalledThemesBeingProcessed(context); + if (processingThemes != null && + processingThemes.contains(themePkgName) && result >= 0) { + NotificationHelper.postThemeInstalledNotification(context, themePkgName); + PreferenceUtils.removeThemeBeingProcessed(context, themePkgName); + } } } @@ -57,4 +77,9 @@ public class AppReceiver extends BroadcastReceiver { return false; } + + private boolean isThemeBeingProcessed(Context context, String pkgName) { + ThemeManager tm = (ThemeManager) context.getSystemService(Context.THEME_SERVICE); + return tm.isThemeBeingProcessed(pkgName); + } } diff --git a/src/com/cyngn/theme/chooser/ThemeFragment.java b/src/com/cyngn/theme/chooser/ThemeFragment.java index e767235..3bfcb30 100644 --- a/src/com/cyngn/theme/chooser/ThemeFragment.java +++ b/src/com/cyngn/theme/chooser/ThemeFragment.java @@ -104,7 +104,7 @@ 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 { + ThemeManager.ThemeChangeListener, ThemeManager.ThemeProcessingListener { private static final String TAG = ThemeFragment.class.getSimpleName(); public static final int ANIMATE_START_DELAY = 200; @@ -253,6 +253,9 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb protected View mCustomizeButton; protected View mDismissButton; + // Processing theme layout + protected View mProcessingThemeLayout; + protected ThemeTagLayout mThemeTagLayout; protected View mClickableView; @@ -449,6 +452,8 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb mCustomizeButton = mCustomizeResetLayout.findViewById(R.id.btn_customize); mCustomizeButton.setOnClickListener(mCustomizeResetClickListener); + mProcessingThemeLayout = v.findViewById(R.id.processing_theme_layout); + if (mPkgName.equals(ThemeUtils.getDefaultThemePackageName(getActivity()))) { mThemeTagLayout.setDefaultTagEnabled(true); } @@ -475,11 +480,40 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb } @Override + public void onResume() { + super.onResume(); + ThemeManager tm = getThemeManager(); + if (tm != null) { + final String pkgName = mBaseThemePkgName != null ? mBaseThemePkgName : mPkgName; + if (tm.isThemeBeingProcessed(pkgName)) { + tm.registerProcessingListener(this); + mProcessingThemeLayout.setVisibility(View.VISIBLE); + mCustomize.setVisibility(View.INVISIBLE); + mCustomize.setAlpha(0f); + if (mDelete.getVisibility() != View.GONE) { + mDelete.setVisibility(View.INVISIBLE); + mDelete.setAlpha(0f); + } + } else { + mCustomize.setVisibility(View.VISIBLE); + mCustomize.setAlpha(1f); + if (mDelete.getVisibility() != View.GONE) { + mDelete.setVisibility(View.VISIBLE); + mDelete.setAlpha(1f); + } + } + } + } + + @Override public void onDestroy() { super.onDestroy(); freeMediaPlayers(); ThemeManager tm = getThemeManager(); - if (tm != null) tm.removeClient(this); + if (tm != null) { + tm.removeClient(this); + tm.unregisterProcessingListener(this); + } } @Override @@ -505,6 +539,28 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb } @Override + public void onFinishedProcessing(String pkgName) { + if (pkgName.equals(mPkgName) || pkgName.equals(mBaseThemePkgName)) { + if (mProcessingThemeLayout.getVisibility() == View.VISIBLE) { + mProcessingThemeLayout.animate().alpha(0).withEndAction(new Runnable() { + @Override + public void run() { + mProcessingThemeLayout.setVisibility(View.GONE); + } + }).setDuration(ANIMATE_APPLY_LAYOUT_DURATION).start(); + mCustomize.setVisibility(View.VISIBLE); + mCustomize.animate().alpha(1f).setDuration(ANIMATE_APPLY_LAYOUT_DURATION).start(); + mOverflow.setVisibility(View.VISIBLE); + mOverflow.animate().alpha(1f).setDuration(ANIMATE_APPLY_LAYOUT_DURATION).start(); + } + ThemeManager tm = getThemeManager(); + if (tm != null) { + tm.unregisterProcessingListener(this); + } + } + } + + @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (mThemeTagLayout == null) return; @@ -675,6 +731,9 @@ public class ThemeFragment extends Fragment implements LoaderManager.LoaderCallb } public void performClick(boolean clickedOnContent) { + // Don't do anything if the theme is being processed + if (mProcessingThemeLayout.getVisibility() == View.VISIBLE) return; + if (clickedOnContent) { showApplyThemeOverlay(); } else { diff --git a/src/com/cyngn/theme/util/PreferenceUtils.java b/src/com/cyngn/theme/util/PreferenceUtils.java index 6b3417d..5e81a9a 100644 --- a/src/com/cyngn/theme/util/PreferenceUtils.java +++ b/src/com/cyngn/theme/util/PreferenceUtils.java @@ -9,14 +9,18 @@ import android.content.pm.ThemeUtils; import android.content.res.Resources; import android.content.res.ThemeConfig; import android.text.TextUtils; +import android.util.Log; import java.util.HashSet; import java.util.Set; public class PreferenceUtils { + private static final String TAG = PreferenceUtils.class.getSimpleName(); + public static final String PREF_APPLIED_BASE_THEME = "applied_base_theme"; public static final String PREF_UPDATED_THEMES = "updated_themes"; public static final String PREF_NEWLY_INSTALLED_THEME_COUNT = "newly_installed_theme_count"; + public static final String PREF_INSTALLED_THEMES_PROCESSING = "installed_themes_processing"; public static SharedPreferences getSharedPreferences(Context context) { if (context == null) return null; @@ -77,6 +81,41 @@ public class PreferenceUtils { } } + public static Set<String> getInstalledThemesBeingProcessed(Context context) { + SharedPreferences prefs = getSharedPreferences(context); + if (prefs == null) return null; + + return prefs.getStringSet(PREF_INSTALLED_THEMES_PROCESSING, null); + } + + public static void addThemeBeingProcessed(Context context, String pkgName) { + SharedPreferences prefs = getSharedPreferences(context); + if (prefs != null) { + Set<String> current = prefs.getStringSet(PREF_INSTALLED_THEMES_PROCESSING, null); + if (current != null && current.add(pkgName)) { + prefs.edit().putStringSet(PREF_INSTALLED_THEMES_PROCESSING, current).apply(); + } + } else { + Log.w(TAG, "addThemeBeingProcessed: Unable to get shared preferences"); + } + } + + public static void removeThemeBeingProcessed(Context context, String pkgName) { + SharedPreferences prefs = getSharedPreferences(context); + if (prefs != null) { + Set<String> updatedThemes = new HashSet<String>(); + Set<String> current = prefs.getStringSet(PREF_INSTALLED_THEMES_PROCESSING, null); + if (current != null) { + updatedThemes.addAll(current); + } + if (updatedThemes.remove(pkgName)) { + prefs.edit().putStringSet(PREF_INSTALLED_THEMES_PROCESSING, updatedThemes).apply(); + } + } else { + Log.w(TAG, "removeThemeBeingProcessed: Unable to get shared preferences"); + } + } + public static boolean hasThemeBeenUpdated(Context context, String pkgName) { Set<String> updatedThemes = getUpdatedThemes(context); return updatedThemes != null && updatedThemes.contains(pkgName); |