summaryrefslogtreecommitdiffstats
path: root/src/org/cyanogenmod/themes/provider/ThemesProvider.java
diff options
context:
space:
mode:
authorClark Scheff <clark@cyngn.com>2014-06-13 17:50:28 -0700
committerAndy Mast <andy@cyngn.com>2015-01-15 09:47:45 -0800
commit3c1b6dd43a9f53bb55c0c1fd8ab52da0989facaf (patch)
tree5e9253dd240c4c81d501b0a5a7240732ebd61bbc /src/org/cyanogenmod/themes/provider/ThemesProvider.java
parent7ccb6305880d89f7ab10356dbe1a9f4ba34796ce (diff)
downloadandroid_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.java229
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 {
}
}
}
-
}