From d2d2ffd0c08c748f1c4cb99c97d6e5ec7fc2beed Mon Sep 17 00:00:00 2001 From: Richard MacGregor Date: Mon, 18 May 2015 12:24:43 -0700 Subject: [2/3] Implement better legacy support for themes Move preview query construction to provider. This will allow for chooser to use older and newer versions of the provider and themes contract. Depends on: http://review.cyanogenmod.org/#/c/98708/ Change-Id: I8b350339c083935079baf9e2710ff4d9665507df --- .../themes/provider/PreviewGenerationService.java | 88 +++++++++++----------- .../themes/provider/ThemesOpenHelper.java | 35 +++++---- .../themes/provider/ThemesProvider.java | 14 ++-- .../themes/provider/util/ProviderUtils.java | 72 ++++++++++++++++++ 4 files changed, 142 insertions(+), 67 deletions(-) diff --git a/src/org/cyanogenmod/themes/provider/PreviewGenerationService.java b/src/org/cyanogenmod/themes/provider/PreviewGenerationService.java index bd48e63..e732c45 100644 --- a/src/org/cyanogenmod/themes/provider/PreviewGenerationService.java +++ b/src/org/cyanogenmod/themes/provider/PreviewGenerationService.java @@ -182,129 +182,129 @@ public class PreviewGenerationService extends IntentService { if (items != null) { path = compressAndSavePng(items.statusbarBackground, filesDir, pkgName, - PreviewColumns.KEY_STATUSBAR_BACKGROUND); - values = createPreviewEntryString(id, PreviewColumns.KEY_STATUSBAR_BACKGROUND, + PreviewColumns.STATUSBAR_BACKGROUND); + values = createPreviewEntryString(id, PreviewColumns.STATUSBAR_BACKGROUND, path); themeValues.add(values); path = compressAndSavePng(items.bluetoothIcon, filesDir, pkgName, - PreviewColumns.KEY_STATUSBAR_BLUETOOTH_ICON); - values = createPreviewEntryString(id, PreviewColumns.KEY_STATUSBAR_BLUETOOTH_ICON, + PreviewColumns.STATUSBAR_BLUETOOTH_ICON); + values = createPreviewEntryString(id, PreviewColumns.STATUSBAR_BLUETOOTH_ICON, path); themeValues.add(values); path = compressAndSavePng(items.wifiIcon, filesDir, pkgName, - PreviewColumns.KEY_STATUSBAR_WIFI_ICON); - values = createPreviewEntryString(id, PreviewColumns.KEY_STATUSBAR_WIFI_ICON, path); + PreviewColumns.STATUSBAR_WIFI_ICON); + values = createPreviewEntryString(id, PreviewColumns.STATUSBAR_WIFI_ICON, path); themeValues.add(values); path = compressAndSavePng(items.signalIcon, filesDir, pkgName, - PreviewColumns.KEY_STATUSBAR_SIGNAL_ICON); - values = createPreviewEntryString(id, PreviewColumns.KEY_STATUSBAR_SIGNAL_ICON, + PreviewColumns.STATUSBAR_SIGNAL_ICON); + values = createPreviewEntryString(id, PreviewColumns.STATUSBAR_SIGNAL_ICON, path); themeValues.add(values); path = compressAndSavePng(items.batteryPortrait, filesDir, pkgName, - PreviewColumns.KEY_STATUSBAR_BATTERY_PORTRAIT); - values = createPreviewEntryString(id, PreviewColumns.KEY_STATUSBAR_BATTERY_PORTRAIT, + PreviewColumns.STATUSBAR_BATTERY_PORTRAIT); + values = createPreviewEntryString(id, PreviewColumns.STATUSBAR_BATTERY_PORTRAIT, path); themeValues.add(values); path = compressAndSavePng(items.batteryLandscape, filesDir, pkgName, - PreviewColumns.KEY_STATUSBAR_BATTERY_LANDSCAPE); + PreviewColumns.STATUSBAR_BATTERY_LANDSCAPE); values = createPreviewEntryString(id, - PreviewColumns.KEY_STATUSBAR_BATTERY_LANDSCAPE, path); + PreviewColumns.STATUSBAR_BATTERY_LANDSCAPE, path); themeValues.add(values); path = compressAndSavePng(items.batteryCircle, filesDir, pkgName, - PreviewColumns.KEY_STATUSBAR_BATTERY_CIRCLE); - values = createPreviewEntryString(id, PreviewColumns.KEY_STATUSBAR_BATTERY_CIRCLE, + PreviewColumns.STATUSBAR_BATTERY_CIRCLE); + values = createPreviewEntryString(id, PreviewColumns.STATUSBAR_BATTERY_CIRCLE, path); themeValues.add(values); - values = createPreviewEntryInt(id, PreviewColumns.KEY_STATUSBAR_CLOCK_TEXT_COLOR, + values = createPreviewEntryInt(id, PreviewColumns.STATUSBAR_CLOCK_TEXT_COLOR, items.clockColor); themeValues.add(values); values = createPreviewEntryInt(id, - PreviewColumns.KEY_STATUSBAR_WIFI_COMBO_MARGIN_END, items.wifiMarginEnd); + PreviewColumns.STATUSBAR_WIFI_COMBO_MARGIN_END, items.wifiMarginEnd); themeValues.add(values); path = compressAndSavePng(items.navbarBackground, filesDir, pkgName, - PreviewColumns.KEY_NAVBAR_BACKGROUND); - values = createPreviewEntryString(id, PreviewColumns.KEY_NAVBAR_BACKGROUND, path); + PreviewColumns.NAVBAR_BACKGROUND); + values = createPreviewEntryString(id, PreviewColumns.NAVBAR_BACKGROUND, path); themeValues.add(values); path = compressAndSavePng(items.navbarBack, filesDir, pkgName, - PreviewColumns.KEY_NAVBAR_BACK_BUTTON); - values = createPreviewEntryString(id, PreviewColumns.KEY_NAVBAR_BACK_BUTTON, path); + PreviewColumns.NAVBAR_BACK_BUTTON); + values = createPreviewEntryString(id, PreviewColumns.NAVBAR_BACK_BUTTON, path); themeValues.add(values); path = compressAndSavePng(items.navbarHome, filesDir, pkgName, - PreviewColumns.KEY_NAVBAR_HOME_BUTTON); - values = createPreviewEntryString(id, PreviewColumns.KEY_NAVBAR_HOME_BUTTON, path); + PreviewColumns.NAVBAR_HOME_BUTTON); + values = createPreviewEntryString(id, PreviewColumns.NAVBAR_HOME_BUTTON, path); themeValues.add(values); path = compressAndSavePng(items.navbarRecent, filesDir, pkgName, - PreviewColumns.KEY_NAVBAR_RECENT_BUTTON); - values = createPreviewEntryString(id, PreviewColumns.KEY_NAVBAR_RECENT_BUTTON, + PreviewColumns.NAVBAR_RECENT_BUTTON); + values = createPreviewEntryString(id, PreviewColumns.NAVBAR_RECENT_BUTTON, path); themeValues.add(values); } if (icons != null) { path = compressAndSavePng(icons.icon1, filesDir, pkgName, - PreviewColumns.KEY_ICON_PREVIEW_1); - values = createPreviewEntryString(id, PreviewColumns.KEY_ICON_PREVIEW_1, path); + PreviewColumns.ICON_PREVIEW_1); + values = createPreviewEntryString(id, PreviewColumns.ICON_PREVIEW_1, path); themeValues.add(values); path = compressAndSavePng(icons.icon2, filesDir, pkgName, - PreviewColumns.KEY_ICON_PREVIEW_2); - values = createPreviewEntryString(id, PreviewColumns.KEY_ICON_PREVIEW_2, path); + PreviewColumns.ICON_PREVIEW_2); + values = createPreviewEntryString(id, PreviewColumns.ICON_PREVIEW_2, path); themeValues.add(values); path = compressAndSavePng(icons.icon3, filesDir, pkgName, - PreviewColumns.KEY_ICON_PREVIEW_3); - values = createPreviewEntryString(id, PreviewColumns.KEY_ICON_PREVIEW_3, path); + PreviewColumns.ICON_PREVIEW_3); + values = createPreviewEntryString(id, PreviewColumns.ICON_PREVIEW_3, path); themeValues.add(values); } if (wallpaperItems != null) { path = compressAndSaveJpg(wallpaperItems.wpPreview, filesDir, pkgName, - PreviewColumns.KEY_WALLPAPER_PREVIEW); - values = createPreviewEntryString(id, PreviewColumns.KEY_WALLPAPER_PREVIEW, path); + PreviewColumns.WALLPAPER_PREVIEW); + values = createPreviewEntryString(id, PreviewColumns.WALLPAPER_PREVIEW, path); themeValues.add(values); path = compressAndSavePng(wallpaperItems.wpThumbnail, filesDir, pkgName, - PreviewColumns.KEY_WALLPAPER_THUMBNAIL); - values = createPreviewEntryString(id, PreviewColumns.KEY_WALLPAPER_THUMBNAIL, path); + PreviewColumns.WALLPAPER_THUMBNAIL); + values = createPreviewEntryString(id, PreviewColumns.WALLPAPER_THUMBNAIL, path); themeValues.add(values); path = compressAndSaveJpg(wallpaperItems.lsPreview, filesDir, pkgName, - PreviewColumns.KEY_LOCK_WALLPAPER_PREVIEW); - values = createPreviewEntryString(id, PreviewColumns.KEY_LOCK_WALLPAPER_PREVIEW, + PreviewColumns.LOCK_WALLPAPER_PREVIEW); + values = createPreviewEntryString(id, PreviewColumns.LOCK_WALLPAPER_PREVIEW, path); themeValues.add(values); path = compressAndSavePng(wallpaperItems.lsThumbnail, filesDir, pkgName, - PreviewColumns.KEY_LOCK_WALLPAPER_THUMBNAIL); - values = createPreviewEntryString(id, PreviewColumns.KEY_LOCK_WALLPAPER_THUMBNAIL, + PreviewColumns.LOCK_WALLPAPER_THUMBNAIL); + values = createPreviewEntryString(id, PreviewColumns.LOCK_WALLPAPER_THUMBNAIL, path); themeValues.add(values); } if (styleItems != null) { path = compressAndSavePng(styleItems.thumbnail, filesDir, pkgName, - PreviewColumns.KEY_STYLE_THUMBNAIL); - values = createPreviewEntryString(id, PreviewColumns.KEY_STYLE_THUMBNAIL, path); + PreviewColumns.STYLE_THUMBNAIL); + values = createPreviewEntryString(id, PreviewColumns.STYLE_THUMBNAIL, path); themeValues.add(values); path = compressAndSavePng(styleItems.preview, filesDir, pkgName, - PreviewColumns.KEY_STYLE_PREVIEW); - values = createPreviewEntryString(id, PreviewColumns.KEY_STYLE_PREVIEW, path); + PreviewColumns.STYLE_PREVIEW); + values = createPreviewEntryString(id, PreviewColumns.STYLE_PREVIEW, path); themeValues.add(values); } if (bootAnim != null) { path = compressAndSavePng(bootAnim, filesDir, pkgName, - PreviewColumns.KEY_BOOTANIMATION_THUMBNAIL); - values = createPreviewEntryString(id, PreviewColumns.KEY_BOOTANIMATION_THUMBNAIL, + PreviewColumns.BOOTANIMATION_THUMBNAIL); + values = createPreviewEntryString(id, PreviewColumns.BOOTANIMATION_THUMBNAIL, path); themeValues.add(values); } diff --git a/src/org/cyanogenmod/themes/provider/ThemesOpenHelper.java b/src/org/cyanogenmod/themes/provider/ThemesOpenHelper.java index 3d02621..6353d15 100644 --- a/src/org/cyanogenmod/themes/provider/ThemesOpenHelper.java +++ b/src/org/cyanogenmod/themes/provider/ThemesOpenHelper.java @@ -31,7 +31,6 @@ import android.provider.ThemesContract; import android.provider.ThemesContract.ThemesColumns; import android.provider.ThemesContract.MixnMatchColumns; import android.provider.ThemesContract.PreviewColumns; -import android.provider.ThemesContract.LegacyPreviewColumns; import android.util.Log; public class ThemesOpenHelper extends SQLiteOpenHelper { @@ -253,7 +252,7 @@ public class ThemesOpenHelper extends SQLiteOpenHelper { private void upgradeToVersion8(SQLiteDatabase db) { String addNavBar = String.format("ALTER TABLE %s ADD COLUMN %s BLOB", - PreviewsTable.TABLE_NAME, LegacyPreviewColumns.NAVBAR_BACKGROUND); + PreviewsTable.TABLE_NAME, PreviewColumns.NAVBAR_BACKGROUND); db.execSQL(addNavBar); // we need to update any existing themes with the new NAVBAR_BACKGROUND @@ -541,26 +540,26 @@ public class ThemesOpenHelper extends SQLiteOpenHelper { ")"; public static final String[] STATUS_BAR_PREVIEW_KEYS = { - PreviewColumns.KEY_STATUSBAR_BACKGROUND, - PreviewColumns.KEY_STATUSBAR_BLUETOOTH_ICON, - PreviewColumns.KEY_STATUSBAR_WIFI_ICON, - PreviewColumns.KEY_STATUSBAR_SIGNAL_ICON, - PreviewColumns.KEY_STATUSBAR_BATTERY_PORTRAIT, - PreviewColumns.KEY_STATUSBAR_BATTERY_LANDSCAPE, - PreviewColumns.KEY_STATUSBAR_BATTERY_CIRCLE, - PreviewColumns.KEY_STATUSBAR_WIFI_COMBO_MARGIN_END, - PreviewColumns.KEY_STATUSBAR_CLOCK_TEXT_COLOR + PreviewColumns.STATUSBAR_BACKGROUND, + PreviewColumns.STATUSBAR_BLUETOOTH_ICON, + PreviewColumns.STATUSBAR_WIFI_ICON, + PreviewColumns.STATUSBAR_SIGNAL_ICON, + PreviewColumns.STATUSBAR_BATTERY_PORTRAIT, + PreviewColumns.STATUSBAR_BATTERY_LANDSCAPE, + PreviewColumns.STATUSBAR_BATTERY_CIRCLE, + PreviewColumns.STATUSBAR_WIFI_COMBO_MARGIN_END, + PreviewColumns.STATUSBAR_CLOCK_TEXT_COLOR }; public static final String[] NAVIGATION_BAR_PREVIEW_KEYS = { - PreviewColumns.KEY_NAVBAR_BACK_BUTTON, - PreviewColumns.KEY_NAVBAR_HOME_BUTTON, - PreviewColumns.KEY_NAVBAR_RECENT_BUTTON, - PreviewColumns.KEY_NAVBAR_BACKGROUND + PreviewColumns.NAVBAR_BACK_BUTTON, + PreviewColumns.NAVBAR_HOME_BUTTON, + PreviewColumns.NAVBAR_RECENT_BUTTON, + PreviewColumns.NAVBAR_BACKGROUND }; public static final String[] ICON_PREVIEW_KEYS = { - PreviewColumns.KEY_ICON_PREVIEW_1, - PreviewColumns.KEY_ICON_PREVIEW_2, - PreviewColumns.KEY_ICON_PREVIEW_3 + PreviewColumns.ICON_PREVIEW_1, + PreviewColumns.ICON_PREVIEW_2, + PreviewColumns.ICON_PREVIEW_3 }; public static void insertDefaults(Context context) { diff --git a/src/org/cyanogenmod/themes/provider/ThemesProvider.java b/src/org/cyanogenmod/themes/provider/ThemesProvider.java index 43cfc3e..8645bbc 100644 --- a/src/org/cyanogenmod/themes/provider/ThemesProvider.java +++ b/src/org/cyanogenmod/themes/provider/ThemesProvider.java @@ -236,10 +236,14 @@ public class ThemesProvider extends ContentProvider { queryBuilder.appendWhere(MixnMatchColumns.COL_KEY + "=" + uri.getLastPathSegment()); break; case COMPONENTS_PREVIEWS: - // COMPONENT_PREVIEWS has the same query behavior as PREVIEWS, however, it requires a - // groupBy parameter to be defined before doing so. Let it fall through after this. - groupBy = PreviewColumns.THEME_ID; + groupBy = PreviewColumns.THEME_ID + "," + PreviewColumns.COMPONENT_ID; + queryBuilder.setTables(THEMES_PREVIEWS_INNER_JOIN); + break; case PREVIEWS: + projection = ProviderUtils.modifyPreviewsProjection(projection); + selection = ProviderUtils.modifyPreviewsSelection(selection, projection); + selectionArgs = ProviderUtils.modifyPreviewsSelectionArgs(selectionArgs, projection); + groupBy = PreviewColumns.THEME_ID + "," + PreviewColumns.COMPONENT_ID; queryBuilder.setTables(THEMES_PREVIEWS_INNER_JOIN); break; case PREVIEWS_ID: @@ -365,7 +369,7 @@ public class ThemesProvider extends ContentProvider { delimeter = ","; } } else if (ThemesColumns.MODIFIES_LAUNCHER.equals(component)) { - String previewKey = PreviewColumns.KEY_WALLPAPER_PREVIEW; + String previewKey = PreviewColumns.WALLPAPER_PREVIEW; sb.append(delimeter).append(String.format( "(SELECT %s AS %s FROM previews WHERE %s=%d AND %s='%s')", PreviewColumns.COL_VALUE, previewKey, PreviewColumns.THEME_ID, @@ -381,7 +385,7 @@ public class ThemesProvider extends ContentProvider { delimeter = ","; } } else if (ThemesColumns.MODIFIES_OVERLAYS.equals(component)) { - String previewKey = PreviewColumns.KEY_STYLE_PREVIEW; + String previewKey = PreviewColumns.STYLE_PREVIEW; sb.append(delimeter).append(String.format( "(SELECT %s AS %s FROM previews WHERE %s=%d AND %s='%s')", PreviewColumns.COL_VALUE, previewKey, PreviewColumns.THEME_ID, diff --git a/src/org/cyanogenmod/themes/provider/util/ProviderUtils.java b/src/org/cyanogenmod/themes/provider/util/ProviderUtils.java index c2aeecf..065a1b0 100644 --- a/src/org/cyanogenmod/themes/provider/util/ProviderUtils.java +++ b/src/org/cyanogenmod/themes/provider/util/ProviderUtils.java @@ -24,9 +24,16 @@ import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.provider.ThemesContract; import android.provider.ThemesContract.MixnMatchColumns; +import android.provider.ThemesContract.PreviewColumns; import android.provider.ThemesContract.ThemesColumns; import org.cyanogenmod.themes.provider.ThemesOpenHelper; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + public class ProviderUtils { /** * Convenience method for determining if a theme exists in the provider @@ -106,6 +113,71 @@ public class ProviderUtils { return themePkgName; } + public static String[] modifyPreviewsProjection(String[] projection) { + Set validKeys = + new HashSet(Arrays.asList(ThemesContract.PreviewColumns.VALID_KEYS)); + ArrayList newProjection = new ArrayList(); + for (String item : projection) { + if (validKeys.contains(item)) { + newProjection.add(getProjectionFromKeyValue(item)); + } else { + newProjection.add(item); + } + } + return newProjection.toArray(new String[newProjection.size()]); + } + + public static String modifyPreviewsSelection(String selection, String[] projection) { + String newSelection = selection; + List projectionItems = getPreviewProjectionItems(projection); + if (projectionItems.size() > 0) { + newSelection += " AND ("; + for (int i = 0; i < projectionItems.size(); i++) { + newSelection += PreviewColumns.COL_KEY + "=?"; + if (i < projectionItems.size() - 1) { + newSelection += " OR "; + } + } + newSelection += ")"; + } + return newSelection; + } + + public static String[] modifyPreviewsSelectionArgs(String[] selectionArgs, + String[] projection) { + ArrayList newSelectionArgs = + new ArrayList(Arrays.asList(selectionArgs)); + List projectionItems = getPreviewProjectionItems(projection); + for (String item : projectionItems) { + newSelectionArgs.add(item); + } + return newSelectionArgs.toArray(new String[newSelectionArgs.size()]); + } + + public static List getPreviewProjectionItems(String[] projection) { + Set validKeys = + new HashSet(Arrays.asList(PreviewColumns.VALID_KEYS)); + ArrayList newProjection = new ArrayList(); + for (String item : projection) { + if (validKeys.contains(item)) { + newProjection.add(getProjectionFromKeyValue(item)); + } + } + return newProjection; + } + + /** + * This allows pivoting key/value pairs as column/entry pairs. + * This is only needed when querying multiple keys at a time. + * @param keyValue + * @return + */ + public static String getProjectionFromKeyValue(String keyValue) { + return String.format("MAX( CASE %s WHEN '%s' THEN %s ELSE NULL END) AS %s", + ThemesContract.PreviewColumns.COL_KEY, keyValue, + ThemesContract.PreviewColumns.COL_VALUE, keyValue); + } + /** * Sends the {@link android.provider.ThemesContract.Intent#ACTION_THEME_INSTALLED} action * @param context -- cgit v1.2.3