diff options
author | Clark Scheff <clark@cyngn.com> | 2014-06-13 17:50:28 -0700 |
---|---|---|
committer | Andy Mast <andy@cyngn.com> | 2015-01-15 09:47:45 -0800 |
commit | 3c1b6dd43a9f53bb55c0c1fd8ab52da0989facaf (patch) | |
tree | 5e9253dd240c4c81d501b0a5a7240732ebd61bbc /src/org/cyanogenmod/themes/provider/ThemesProvider.java | |
parent | 7ccb6305880d89f7ab10356dbe1a9f4ba34796ce (diff) | |
download | android_packages_providers_ThemesProvider-3c1b6dd43a9f53bb55c0c1fd8ab52da0989facaf.tar.gz android_packages_providers_ThemesProvider-3c1b6dd43a9f53bb55c0c1fd8ab52da0989facaf.tar.bz2 android_packages_providers_ThemesProvider-3c1b6dd43a9f53bb55c0c1fd8ab52da0989facaf.zip |
Themes: Port to CM12 [4/6]
Auto-generate previews.
Id: Ia8f12bc852fb708e52ccc98641eea278756b198f
Add MODIFIES_STATUS_BAR and MODIFIES_NAVIGATION_BAR
Id: If1f81b122cfb5075835c70dff0bcfa6dea5d8de8
Use image with largest size for boot ani preview.
Id: I3f2c16aa6ceb18387925e2cf2812d8c3ddf0d3d7
Use same components used in the original chooser.
Icon previews will be generated using the same login used in the
theme chooser v1.
Id: Iafcd9f3d78fc86a66fe3635d27ee9fb7d47ae531
Remove (Default) from Holo's title.
Holo may not be the default theme and therefore we should not add
this to the title. The clients can handle determining which theme
is the default on a device and act accordingly.
Id: I162b3af97b05205c3ddf1e6ce130d05d9e0fe81f
Add query for retrieving previews of currently applied components.
Id: Ic3cffb4b762a047af40c72846e6e6bcf9a273619
Delete previews from provider when theme removed
Id: Ica221885b929f7671f048d367648f7c6f82e4529
Alias status bar background as navbar_background
Id: I3a32ea59e8fa94689d20fe92fbbc544b9da6e32b
Fix provider not updating previews due to missing action.
Id: Icd9f38ab499cfc617862be7638f06a9273dbdc22
Retrieve correct wallpaper size and store as jpeg
Id: I346516a5860819f15a6b689e6da1a6bdf4f2540f
Add style preview.
What was originally called STYLE_PREVIEW is now STYLE_THUMBNAIL and
STYLE_PREVIEW is now a larger sized image of various controls.
Id: Iecf9785e992efa98360c84af2054d3a2a113f094
Use ThemeUtils methods for getting wallpaper paths.
Id: I7fb269abe38560d638a2bad74fcfb7ed6a9a4c43
Add newly added navbar background in ThemesContract. [1/2]
Id: I6fc92388a58b69c7a52053103cf85bb348f6144a
Keep track of when a theme was installed
Id: I9cdf637d63a4ed3d14b978a7d6c019aed0afe8e0
Update provider with ComposedIconInfo changes in f/b
Id: I6ad0db5f55ed0dfb42c30cb5946f5c10af5b5a0f
Use getThemedResourcesForApplication for icons
Since we no longer pass bitmaps around in ComposedIconInfo we need
to make sure the icons are actually attached to the resources in
order to retrieve the drawables for the composed icons.
Id: I7c92ee9d4114399024743c01d0df7fcc0284c150
Themes: Let ThemeService handle all theme processing [3/3]
Id: Ied877eb5f1e96774d2e415970034d0b892765134
Add theme to db when installed and defer processing
This allows the theme to show up in the theme provider even though
the theme resources still need to be compiled. Once they are compiled
the themes provider will update the database with the previews.
Id: I2505cb875ee36975745a46469b2e55afe4fd1e68
Catch excpetions that occur when generating icon previews
Id: I22e270911af12b6bd3cd69c84205d8455f74cf79
REF: THEMES-387
Catch all exceptions for styles and systemui previews
Id: I4e3ee24e049d6dedba331175e21a143872de1f8e
Presentable themes should contian icons, wallpaper and overlays
The thems provider considered any theme with 2 or more components as
a presentable theme which may not be represented well in the Theme Chooser.
This patch makes it mandatory that a theme have icons, wallpaper and
overlays in order to be considered a presentable theme.
Id: If9918bd50125a4cd74b7926c5617c882eb89d5c2
REF: CHOOSER-2
Get working on CM12
Id: If585b1c9ee10b049f473ba2ca4ee313e09b6e715
Add column for target api
This column will allow us to easily track what version of CM a
theme was built for in case of incompatibility issues. The
system theme will have a value of 0 indicating that it works on
whatever the current api level is on the device. This prevents us
from updating the row for the system font whenever the api level
increases.
Id: Ic43b63f2f801243914124043c4f4113a6b75b914
CM11 -> CM12 Upgrade [2/3]
Renamed the "holo" theme to "system"
Id: I82f2cde2e26e0b13c95ebb0fc61253c805c0a16e
Fix String.format in upgradeToVersion11()
Id: I13917d0c7ab34ff25a6326aebc0d707780bd6769
Change-Id: Ic98ec257e56a82d7faef37c0d2a2cfe360d6e35c
Diffstat (limited to 'src/org/cyanogenmod/themes/provider/ThemesProvider.java')
-rw-r--r-- | src/org/cyanogenmod/themes/provider/ThemesProvider.java | 229 |
1 files changed, 193 insertions, 36 deletions
diff --git a/src/org/cyanogenmod/themes/provider/ThemesProvider.java b/src/org/cyanogenmod/themes/provider/ThemesProvider.java index 24c79bf..b64eafe 100644 --- a/src/org/cyanogenmod/themes/provider/ThemesProvider.java +++ b/src/org/cyanogenmod/themes/provider/ThemesProvider.java @@ -35,10 +35,13 @@ import android.os.Handler; import android.preference.PreferenceManager; import android.provider.ThemesContract; import android.provider.ThemesContract.MixnMatchColumns; +import android.provider.ThemesContract.PreviewColumns; import android.provider.ThemesContract.ThemesColumns; +import android.text.TextUtils; import android.util.Log; import org.cyanogenmod.themes.provider.ThemesOpenHelper.MixnMatchTable; +import org.cyanogenmod.themes.provider.ThemesOpenHelper.PreviewsTable; import org.cyanogenmod.themes.provider.ThemesOpenHelper.ThemesTable; import java.util.ArrayList; @@ -48,7 +51,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; -import static android.content.res.ThemeConfig.HOLO_DEFAULT; +import static android.content.res.ThemeConfig.SYSTEM_DEFAULT; public class ThemesProvider extends ContentProvider { private static final String TAG = ThemesProvider.class.getSimpleName(); @@ -57,9 +60,14 @@ public class ThemesProvider extends ContentProvider { private static final int MIXNMATCH_KEY = 2; private static final int THEMES = 3; private static final int THEMES_ID = 4; + private static final int PREVIEWS = 5; + private static final int PREVIEWS_ID = 6; + private static final int APPLIED_PREVIEWS = 7; private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); + public static final String KEY_PROCESS_PREVIEWS = "process_previews"; + private final Handler mHandler = new Handler(); private ThemesOpenHelper mDatabase; @@ -68,6 +76,9 @@ public class ThemesProvider extends ContentProvider { sUriMatcher.addURI(ThemesContract.AUTHORITY, "mixnmatch/*", MIXNMATCH_KEY); sUriMatcher.addURI(ThemesContract.AUTHORITY, "themes/", THEMES); sUriMatcher.addURI(ThemesContract.AUTHORITY, "themes/#", THEMES_ID); + sUriMatcher.addURI(ThemesContract.AUTHORITY, "previews/", PREVIEWS); + sUriMatcher.addURI(ThemesContract.AUTHORITY, "previews/#", PREVIEWS_ID); + sUriMatcher.addURI(ThemesContract.AUTHORITY, "applied_previews/", APPLIED_PREVIEWS); } public static void setActiveTheme(Context context, String pkgName) { @@ -90,17 +101,14 @@ public class ThemesProvider extends ContentProvider { case THEMES: SQLiteDatabase sqlDB = mDatabase.getWritableDatabase(); - // Determine the pkg name and delete preview images - String[] columns = new String[] {ThemesColumns.PKG_NAME}; + // Get the theme's _id and delete preview images + String[] columns = new String[] { ThemesColumns._ID }; Cursor c = sqlDB.query(ThemesTable.TABLE_NAME, columns, selection, selectionArgs, null, null, null); if (c == null) return 0; if (c.moveToFirst()) { - String pkgName = c.getString(0); - Intent intent = new Intent(getContext(), CopyImageService.class); - intent.setAction(CopyImageService.ACTION_DELETE); - intent.putExtra(CopyImageService.EXTRA_PKG_NAME, pkgName); - getContext().startService(intent); + sqlDB.delete(PreviewsTable.TABLE_NAME, + PreviewColumns.THEME_ID + "=" + c.getInt(0), null); } c.close(); @@ -125,6 +133,10 @@ public class ThemesProvider extends ContentProvider { return "vnd.android.cursor.dir/mixnmatch"; case MIXNMATCH_KEY: return "vnd.android.cursor.item/mixnmatch"; + case PREVIEWS: + return "vnd.android.cursor.dir/previews"; + case PREVIEWS_ID: + return "vnd.android.cursor.item/previews"; default: return null; } @@ -137,17 +149,41 @@ public class ThemesProvider extends ContentProvider { long id = 0; switch (uriType) { case THEMES: + boolean processPreviews = true; + if (values.containsKey(KEY_PROCESS_PREVIEWS)) { + processPreviews = values.getAsBoolean(KEY_PROCESS_PREVIEWS); + values.remove(KEY_PROCESS_PREVIEWS); + } id = sqlDB.insert(ThemesOpenHelper.ThemesTable.TABLE_NAME, null, values); - Intent intent = new Intent(getContext(), CopyImageService.class); - intent.setAction(CopyImageService.ACTION_INSERT); - intent.putExtra(CopyImageService.EXTRA_PKG_NAME, - values.getAsString(ThemesColumns.PKG_NAME)); - getContext().startService(intent); + if (processPreviews) { + Intent intent = new Intent(getContext(), PreviewGenerationService.class); + intent.setAction(PreviewGenerationService.ACTION_INSERT); + intent.putExtra(PreviewGenerationService.EXTRA_PKG_NAME, + values.getAsString(ThemesColumns.PKG_NAME)); + Boolean hasSystemUi = values.getAsBoolean(ThemesColumns.MODIFIES_STATUS_BAR); + intent.putExtra(PreviewGenerationService.EXTRA_HAS_SYSTEMUI, + hasSystemUi != null && hasSystemUi); + Boolean hasIcons = values.getAsBoolean(ThemesColumns.MODIFIES_ICONS); + intent.putExtra(PreviewGenerationService.EXTRA_HAS_ICONS, + hasIcons != null && hasIcons); + Boolean hasStyles = values.getAsBoolean(ThemesColumns.MODIFIES_OVERLAYS); + intent.putExtra(PreviewGenerationService.EXTRA_HAS_STYLES, + hasStyles != null && hasStyles); + Boolean hasWallpaper = values.getAsBoolean(ThemesColumns.MODIFIES_LAUNCHER); + intent.putExtra(PreviewGenerationService.EXTRA_HAS_WALLPAPER, + hasWallpaper != null && hasWallpaper); + Boolean hasBootAni = values.getAsBoolean(ThemesColumns.MODIFIES_BOOT_ANIM); + intent.putExtra(PreviewGenerationService.EXTRA_HAS_BOOTANIMATION, + hasBootAni != null && hasBootAni); + getContext().startService(intent); + } break; case MIXNMATCH: throw new UnsupportedOperationException("Cannot insert rows into MixNMatch table"); + case PREVIEWS: + id = sqlDB.insert(ThemesOpenHelper.PreviewsTable.TABLE_NAME, null, values); + break; default: - throw new IllegalArgumentException("Unknown URI: " + uri); } getContext().getContentResolver().notifyChange(uri, null); return Uri.parse(MixnMatchColumns.CONTENT_URI + "/" + id); @@ -195,6 +231,15 @@ public class ThemesProvider extends ContentProvider { queryBuilder.setTables(THEMES_MIXNMATCH_INNER_JOIN); queryBuilder.appendWhere(MixnMatchColumns.COL_KEY + "=" + uri.getLastPathSegment()); break; + case PREVIEWS: + queryBuilder.setTables(THEMES_PREVIEWS_INNER_JOIN); + break; + case PREVIEWS_ID: + queryBuilder.setTables(THEMES_PREVIEWS_INNER_JOIN); + queryBuilder.appendWhere(PreviewColumns._ID + "=" + uri.getLastPathSegment()); + break; + case APPLIED_PREVIEWS: + return getAppliedPreviews(db); default: return null; } @@ -212,6 +257,10 @@ public class ThemesProvider extends ContentProvider { + " INNER JOIN " + ThemesTable.TABLE_NAME + " ON (" + MixnMatchColumns.COL_VALUE + " = " + ThemesColumns.PKG_NAME + ")"; + private static final String THEMES_PREVIEWS_INNER_JOIN = PreviewsTable.TABLE_NAME + + " INNER JOIN " + ThemesTable.TABLE_NAME + " ON (" + PreviewColumns.THEME_ID + + " = " + ThemesTable.TABLE_NAME + "." + ThemesColumns._ID + ")"; + @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { @@ -220,36 +269,120 @@ public class ThemesProvider extends ContentProvider { switch (sUriMatcher.match(uri)) { case THEMES: - rowsUpdated = sqlDB.update(ThemesTable.TABLE_NAME, values, selection, selectionArgs); - if (updateNotTriggeredByContentProvider(values)) { - Intent intent = new Intent(getContext(), CopyImageService.class); - intent.putExtra(CopyImageService.EXTRA_PKG_NAME, - values.getAsString(ThemesColumns.PKG_NAME)); - getContext().startService(intent); - getContext().getContentResolver().notifyChange(uri, null); - } - return rowsUpdated; case THEMES_ID: + String pkgName = values.getAsString(ThemesColumns.PKG_NAME); + final boolean updatePreviews = getShouldUpdatePreviews(sqlDB, pkgName); rowsUpdated = sqlDB.update(ThemesTable.TABLE_NAME, values, selection, selectionArgs); - if (updateNotTriggeredByContentProvider(values)) { - Intent intent = new Intent(getContext(), CopyImageService.class); - intent.putExtra(CopyImageService.EXTRA_PKG_NAME, + if (updateNotTriggeredByContentProvider(values) && updatePreviews) { + Intent intent = new Intent(getContext(), PreviewGenerationService.class); + intent.setAction(PreviewGenerationService.ACTION_UPDATE); + intent.putExtra(PreviewGenerationService.EXTRA_PKG_NAME, values.getAsString(ThemesColumns.PKG_NAME)); + Boolean hasSystemUi = values.getAsBoolean(ThemesColumns.MODIFIES_STATUS_BAR); + intent.putExtra(PreviewGenerationService.EXTRA_HAS_SYSTEMUI, + hasSystemUi != null && hasSystemUi); + Boolean hasIcons = values.getAsBoolean(ThemesColumns.MODIFIES_ICONS); + intent.putExtra(PreviewGenerationService.EXTRA_HAS_ICONS, + hasIcons != null && hasIcons); + Boolean hasStyles = values.getAsBoolean(ThemesColumns.MODIFIES_OVERLAYS); + intent.putExtra(PreviewGenerationService.EXTRA_HAS_STYLES, + hasStyles != null && hasStyles); + Boolean hasWallpaper = values.getAsBoolean(ThemesColumns.MODIFIES_LAUNCHER); + intent.putExtra(PreviewGenerationService.EXTRA_HAS_WALLPAPER, + hasWallpaper != null && hasWallpaper); + Boolean hasBootAni = values.getAsBoolean(ThemesColumns.MODIFIES_BOOT_ANIM); + intent.putExtra(PreviewGenerationService.EXTRA_HAS_BOOTANIMATION, + hasBootAni != null && hasBootAni); getContext().startService(intent); - getContext().getContentResolver().notifyChange(uri, null); } getContext().getContentResolver().notifyChange(uri, null); - return rowsUpdated; + break; case MIXNMATCH: rowsUpdated = sqlDB.update(MixnMatchTable.TABLE_NAME, values, selection, selectionArgs); getContext().getContentResolver().notifyChange(uri, null); + break; case MIXNMATCH_KEY: // Don't support right now. Any need? + break; + case PREVIEWS: + rowsUpdated = sqlDB.update(PreviewsTable.TABLE_NAME, values, selection, selectionArgs); + getContext().getContentResolver().notifyChange(uri, null); + break; } return rowsUpdated; } /** + * Queries the currently applied components and creates a SQLite statement consisting + * of a series of (SELECT ...) statements + * @param db Readable database + * @return + */ + private Cursor getAppliedPreviews(SQLiteDatabase db) { + Cursor c = db.query(MixnMatchTable.TABLE_NAME, null, null, null, null, null, null); + if (c != null) { + StringBuilder sb = new StringBuilder("SELECT * FROM "); + String delimeter = ""; + while (c.moveToNext()) { + String key = c.getString(0); + String pkgName = c.getString(1); + String component = key != null ? MixnMatchColumns.mixNMatchKeyToComponent(key) : + null; + if (component != null && pkgName != null) { + // We need to get the theme's id using its package name + String[] columns = { ThemesColumns._ID }; + Cursor current = db.query(ThemesTable.TABLE_NAME, columns, + ThemesColumns.PKG_NAME + "='" + pkgName + "'", null, null, null, null); + int id = -1; + if (current != null) { + if (current.moveToFirst()) id = current.getInt(0); + current.close(); + } + if (id >= 0) { + if (ThemesColumns.MODIFIES_STATUS_BAR.equals(component)) { + sb.append(delimeter).append("(SELECT "); + sb.append(TextUtils.join(",", + PreviewsTable.STATUS_BAR_PREVIEW_COLUMNS)); + sb.append(String.format(" FROM previews WHERE %s=%d)", + PreviewColumns.THEME_ID, id)); + delimeter = ","; + } else if (ThemesColumns.MODIFIES_ICONS.equals(component)) { + sb.append(delimeter).append("(SELECT "); + sb.append(TextUtils.join(",", PreviewsTable.ICON_PREVIEW_COLUMNS)); + sb.append(String.format(" FROM previews WHERE %s=%d)", + PreviewColumns.THEME_ID, id)); + delimeter = ","; + } else if (ThemesColumns.MODIFIES_LAUNCHER.equals(component)) { + sb.append(delimeter).append("(SELECT "); + sb.append(String.format("%s", PreviewColumns.WALLPAPER_PREVIEW)); + sb.append(String.format(" FROM previews WHERE %s=%d)", + PreviewColumns.THEME_ID, id)); + delimeter = ","; + } else if (ThemesColumns.MODIFIES_NAVIGATION_BAR.equals(component)) { + sb.append(delimeter).append("(SELECT "); + sb.append(TextUtils.join(",", + PreviewsTable.NAVIGATION_BAR_PREVIEW_COLUMNS)); + sb.append(String.format(" FROM previews WHERE %s=%d)", + PreviewColumns.THEME_ID, id)); + delimeter = ","; + } else if (ThemesColumns.MODIFIES_OVERLAYS.equals(component)) { + sb.append(delimeter).append("(SELECT "); + sb.append(PreviewColumns.STYLE_PREVIEW); + sb.append(String.format(" FROM previews WHERE %s=%d)", + PreviewColumns.THEME_ID, id)); + delimeter = ","; + } + } + } + } + c.close(); + sb.append(";"); + return db.rawQuery(sb.toString(), null); + } + return null; + } + + /** * When there is an insert or update to a theme, an async service will kick off to update * several of the preview image columns. Since this service also calls a 2nd update on the * content resolver, we need to break the loop so that we don't kick off the service again. @@ -261,6 +394,31 @@ public class ThemesProvider extends ContentProvider { .containsKey(ThemesColumns.STYLE_URI)); } + private boolean getShouldUpdatePreviews(SQLiteDatabase db, String pkgName) { + if (pkgName != null) { + long lastUpdateTime = 0; + String[] columns = {ThemesColumns.LAST_UPDATE_TIME}; + String selection = ThemesColumns.PKG_NAME + "=?"; + String[] selectionArgs = {pkgName}; + Cursor c = + db.query(ThemesTable.TABLE_NAME, columns, selection, selectionArgs, null, null, + null); + if (c != null) { + c.moveToFirst(); + lastUpdateTime = c.getInt(0); + c.close(); + } + + try { + PackageInfo pi = getContext().getPackageManager().getPackageInfo(pkgName, 0); + return lastUpdateTime < pi.lastUpdateTime; + } catch (NameNotFoundException e) { + Log.w(TAG, "Unable to retrieve PackageInfo for " + pkgName, e); + } + } + return false; + } + /** * This class has been modified from its original source. Original Source: ThemesProvider.java * See https://github.com/tmobile/themes-platform-vendor-tmobile-providers-ThemeManager @@ -303,7 +461,7 @@ public class ThemesProvider extends ContentProvider { List<PackageInfo> themePackages = new ArrayList<PackageInfo>(); Map<String, PackageInfo> pmThemes = new HashMap<String, PackageInfo>(); for (PackageInfo info : packages) { - if (info.isThemeApk || info.isLegacyThemeApk || info.isLegacyIconPackApk) { + if (info.isThemeApk || info.isLegacyIconPackApk) { themePackages.add(info); pmThemes.put(info.packageName, info); } @@ -326,10 +484,10 @@ public class ThemesProvider extends ContentProvider { String pkgName = current.getString(pkgNameIdx); boolean isDefault = current.getInt(isDefaultIdx) == 1; - // Ignore holo theme - if (pkgName.equals(HOLO_DEFAULT)) { - if (defaultThemePkg.equals(HOLO_DEFAULT) != isDefault) { - updateList.add(HOLO_DEFAULT); + // Ignore system theme + if (pkgName.equals(SYSTEM_DEFAULT)) { + if (defaultThemePkg.equals(SYSTEM_DEFAULT) != isDefault) { + updateList.add(SYSTEM_DEFAULT); } continue; } @@ -374,7 +532,7 @@ public class ThemesProvider extends ContentProvider { } ThemeManager mService = (ThemeManager) getContext().getSystemService( Context.THEME_SERVICE); - mService.requestThemeChange(HOLO_DEFAULT, moveToDefault); + mService.requestThemeChange(SYSTEM_DEFAULT, moveToDefault); // Update the database after we revert to default deleteThemes(deleteList); @@ -395,7 +553,7 @@ public class ThemesProvider extends ContentProvider { private void insertThemes(Collection<PackageInfo> themesToInsert) { for (PackageInfo themeInfo : themesToInsert) { try { - ThemePackageHelper.insertPackage(getContext(), themeInfo.packageName); + ThemePackageHelper.insertPackage(getContext(), themeInfo.packageName, true); } catch (NameNotFoundException e) { Log.e(TAG, "Unable to insert theme " + themeInfo.packageName, e); } @@ -412,5 +570,4 @@ public class ThemesProvider extends ContentProvider { } } } - } |