Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab639850 authored by Santiago Etchebehere's avatar Santiago Etchebehere
Browse files

Custom Theme 5/n: apply custom theme

Bug: 124796742
Change-Id: I9ec8d029c2fd1598753ea0fed471831c3cf692a6
parent bfdd0f42
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          package="com.android.wallpaper">

    <uses-sdk android:targetSdkVersion="Q" android:minSdkVersion="28"/>
@@ -15,7 +16,9 @@
        android:requiredForAllUsers="true"
        android:restoreAnyVersion="true"
        android:supportsRtl="true"
        android:theme="@style/CustomizationTheme">
        android:name="com.android.customization.picker.CustomizationPickerApplication"
        android:theme="@style/CustomizationTheme"
        tools:replace="android:name">
        <activity
            android:name="com.android.customization.picker.CustomizationPickerActivity"
            android:label="@string/app_name"
+2 −0
Original line number Diff line number Diff line
@@ -25,4 +25,6 @@
        corresponding to a ContentProvider in launcher to provide available grids and
        allow for changing them -->
    <string name="grid_control_metadata_name" translatable="false">com.android.launcher3.grid.control</string>

    <string name="launcher_overlayable_package" translatable="false">com.android.launcher3</string>
</resources>
 No newline at end of file
+22 −2
Original line number Diff line number Diff line
@@ -15,8 +15,14 @@
 */
package com.android.customization.model;

import android.content.Context;
import android.provider.Settings.Secure;

import com.android.wallpaper.R;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * Holds common strings used to reference system resources.
 */
@@ -37,8 +43,6 @@ public interface ResourceConstants {
     */
    String SYSUI_PACKAGE = "com.android.systemui";

    String [] DEFAULT_TARGET_PACKAGES = {ANDROID_PACKAGE, SETTINGS_PACKAGE, SYSUI_PACKAGE};

    /**
     * Name of the system resource for icon mask
     */
@@ -53,6 +57,7 @@ public interface ResourceConstants {
    String OVERLAY_CATEGORY_ICON_ANDROID = "android.theme.customization.icon_pack.android";
    String OVERLAY_CATEGORY_ICON_SETTINGS = "android.theme.customization.icon_pack.settings";
    String OVERLAY_CATEGORY_ICON_SYSUI = "android.theme.customization.icon_pack.systemui";
    String OVERLAY_CATEGORY_ICON_LAUNCHER = "android.theme.customization.icon_pack.launcher";

    /**
     * Secure Setting used to store the currently set theme.
@@ -68,4 +73,19 @@ public interface ResourceConstants {
            "ic_qs_auto_rotate",
            "ic_signal_airplane"
    };

    ArrayList<String> sTargetPackages = new ArrayList<>();

    static String[] getPackagesToOverlay(Context context) {
        if (sTargetPackages.isEmpty()) {
            sTargetPackages.addAll(Arrays.asList(ANDROID_PACKAGE, SETTINGS_PACKAGE,
                    SYSUI_PACKAGE));
            sTargetPackages.add(getLauncherPackage(context));
        }
        return sTargetPackages.toArray(new String[0]);
    }

    static String getLauncherPackage(Context context) {
        return context.getString(R.string.launcher_overlayable_package);
    }
}
+103 −47
Original line number Diff line number Diff line
@@ -18,6 +18,11 @@ package com.android.customization.model.theme;
import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE;
import static com.android.customization.model.ResourceConstants.CONFIG_ICON_MASK;
import static com.android.customization.model.ResourceConstants.ICON_PREVIEW_DRAWABLE_NAME;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_FONT;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_ANDROID;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_LAUNCHER;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SETTINGS;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SYSUI;
import static com.android.customization.model.ResourceConstants.SETTINGS_PACKAGE;
import static com.android.customization.model.ResourceConstants.SYSUI_ICONS_FOR_PREVIEW;
import static com.android.customization.model.ResourceConstants.SYSUI_PACKAGE;
@@ -41,13 +46,18 @@ import com.android.customization.model.ResourceConstants;
import com.android.customization.model.ResourcesApkProvider;
import com.android.customization.model.theme.ThemeBundle.Builder;
import com.android.customization.model.theme.custom.CustomTheme;
import com.android.customization.module.CustomizationPreferences;
import com.android.wallpaper.R;
import com.android.wallpaper.asset.ResourceAsset;

import com.bumptech.glide.request.RequestOptions;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
@@ -84,10 +94,12 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB

    private List<ThemeBundle> mThemes;
    private Map<String, OverlayInfo> mOverlayInfos;
    private final CustomizationPreferences mCustomizationPreferences;

    public DefaultThemeProvider(Context context) {
    public DefaultThemeProvider(Context context, CustomizationPreferences customizationPrefs) {
        super(context, context.getString(R.string.themes_stub_package));
        OverlayManager om = context.getSystemService(OverlayManager.class);
        mCustomizationPreferences = customizationPrefs;
        mOverlayInfos = new HashMap<>();

        Consumer<OverlayInfo> addToMap = overlayInfo -> mOverlayInfos.put(
@@ -95,6 +107,8 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB
        om.getOverlayInfosForTarget(ANDROID_PACKAGE, UserHandle.myUserId()).forEach(addToMap);
        om.getOverlayInfosForTarget(SYSUI_PACKAGE, UserHandle.myUserId()).forEach(addToMap);
        om.getOverlayInfosForTarget(SETTINGS_PACKAGE, UserHandle.myUserId()).forEach(addToMap);
        om.getOverlayInfosForTarget(ResourceConstants.getLauncherPackage(context),
                UserHandle.myUserId()).forEach(addToMap);
    }

    @Override
@@ -127,16 +141,7 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB

                String fontOverlayPackage = getOverlayPackage(FONT_PREFIX, themeName);

                if (!TextUtils.isEmpty(fontOverlayPackage)) {
                    builder.addOverlayPackage(getOverlayCategory(fontOverlayPackage),
                                fontOverlayPackage)
                            .setBodyFontFamily(loadTypeface(
                                    ResourceConstants.CONFIG_BODY_FONT_FAMILY,
                                    fontOverlayPackage))
                            .setHeadlineFontFamily(loadTypeface(
                                    ResourceConstants.CONFIG_HEADLINE_FONT_FAMILY,
                                    fontOverlayPackage));
                }
                addFontOverlay(builder, fontOverlayPackage);

                String colorOverlayPackage = getOverlayPackage(COLOR_PREFIX, themeName);

@@ -168,43 +173,20 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB
                String iconAndroidOverlayPackage = getOverlayPackage(ICON_ANDROID_PREFIX,
                        themeName);

                if (!TextUtils.isEmpty(iconAndroidOverlayPackage)) {
                    builder.addOverlayPackage(getOverlayCategory(iconAndroidOverlayPackage),
                                iconAndroidOverlayPackage)
                            .addIcon(loadIconPreviewDrawable(
                                    ICON_PREVIEW_DRAWABLE_NAME,
                                    iconAndroidOverlayPackage));
                } else {
                    builder.addIcon(mContext.getResources().getDrawable(
                            Resources.getSystem().getIdentifier(
                                    ICON_PREVIEW_DRAWABLE_NAME,
                                    "drawable", ANDROID_PACKAGE), null));
                }
                addAndroidIconOverlay(builder, iconAndroidOverlayPackage);

                String iconSysUiOverlayPackage = getOverlayPackage(ICON_SYSUI_PREFIX, themeName);

                if (!TextUtils.isEmpty(iconSysUiOverlayPackage)) {
                    builder.addOverlayPackage(getOverlayCategory(iconSysUiOverlayPackage),
                            iconSysUiOverlayPackage);
                    for (String iconName : SYSUI_ICONS_FOR_PREVIEW) {
                        builder.addIcon(loadIconPreviewDrawable(iconName, iconSysUiOverlayPackage));
                    }
                }
                addSysUiIconOverlay(builder, iconSysUiOverlayPackage);

                String iconLauncherOverlayPackage = getOverlayPackage(ICON_LAUNCHER_PREFIX,
                        themeName);
                if (!TextUtils.isEmpty(iconLauncherOverlayPackage)) {
                    builder.addOverlayPackage(getOverlayCategory(iconLauncherOverlayPackage),
                            iconLauncherOverlayPackage);
                }
                addNoPreviewIconOverlay(builder,iconLauncherOverlayPackage);

                String iconSettingsOverlayPackage = getOverlayPackage(ICON_SETTINGS_PREFIX,
                        themeName);

                if (!TextUtils.isEmpty(iconSettingsOverlayPackage)) {
                    builder.addOverlayPackage(getOverlayCategory(iconSettingsOverlayPackage),
                            iconSettingsOverlayPackage);
                }
                addNoPreviewIconOverlay(builder, iconSettingsOverlayPackage);

                try {
                    String wallpaperResName = WALLPAPER_PREFIX + themeName;
@@ -239,6 +221,54 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB
        }
    }

    private void addNoPreviewIconOverlay(Builder builder, String overlayPackage) {
        if (!TextUtils.isEmpty(overlayPackage)) {
            builder.addOverlayPackage(getOverlayCategory(overlayPackage),
                    overlayPackage);
        }
    }

    private void addSysUiIconOverlay(Builder builder, String iconSysUiOverlayPackage)
            throws NameNotFoundException {
        if (!TextUtils.isEmpty(iconSysUiOverlayPackage)) {
            builder.addOverlayPackage(getOverlayCategory(iconSysUiOverlayPackage),
                    iconSysUiOverlayPackage);
            for (String iconName : SYSUI_ICONS_FOR_PREVIEW) {
                builder.addIcon(loadIconPreviewDrawable(iconName, iconSysUiOverlayPackage));
            }
        }
    }

    private void addAndroidIconOverlay(Builder builder, String iconAndroidOverlayPackage)
            throws NameNotFoundException {
        if (!TextUtils.isEmpty(iconAndroidOverlayPackage)) {
            builder.addOverlayPackage(getOverlayCategory(iconAndroidOverlayPackage),
                        iconAndroidOverlayPackage)
                    .addIcon(loadIconPreviewDrawable(
                            ICON_PREVIEW_DRAWABLE_NAME,
                            iconAndroidOverlayPackage));
        } else {
            builder.addIcon(mContext.getResources().getDrawable(
                    Resources.getSystem().getIdentifier(
                            ICON_PREVIEW_DRAWABLE_NAME,
                            "drawable", ANDROID_PACKAGE), null));
        }
    }

    private void addFontOverlay(Builder builder, String fontOverlayPackage)
            throws NameNotFoundException {
        if (!TextUtils.isEmpty(fontOverlayPackage)) {
            builder.addOverlayPackage(getOverlayCategory(fontOverlayPackage),
                        fontOverlayPackage)
                    .setBodyFontFamily(loadTypeface(
                            ResourceConstants.CONFIG_BODY_FONT_FAMILY,
                            fontOverlayPackage))
                    .setHeadlineFontFamily(loadTypeface(
                            ResourceConstants.CONFIG_HEADLINE_FONT_FAMILY,
                            fontOverlayPackage));
        }
    }

    /**
     * Default theme requires different treatment: if there are overlay packages specified in the
     * stub apk, we'll use those, otherwise we'll get the System default values. But we cannot skip
@@ -331,13 +361,7 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB
        try {
            String iconSysUiOverlayPackage = getOverlayPackage(ICON_SYSUI_PREFIX,
                    DEFAULT_THEME_NAME);
            if (!TextUtils.isEmpty(iconSysUiOverlayPackage)) {
                builder.addOverlayPackage(getOverlayCategory(iconSysUiOverlayPackage),
                        iconSysUiOverlayPackage);
                for (String iconName : SYSUI_ICONS_FOR_PREVIEW) {
                    builder.addIcon(loadIconPreviewDrawable(iconName, iconSysUiOverlayPackage));
                }
            }
            addSysUiIconOverlay(builder, iconSysUiOverlayPackage);
        } catch (NameNotFoundException | NotFoundException e) {
            Log.d(TAG, "Didn't find SystemUi icons overlay for default theme, using system default",
                    e);
@@ -377,9 +401,41 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB
        mThemes.add(builder.build());
    }

    @Override
    public void storeCustomTheme(CustomTheme theme) {
        mCustomizationPreferences.storeCustomTheme(theme.getSerializedPackages());
    }

    private void addCustomTheme() {
        String serializedTheme = mCustomizationPreferences.getSerializedCustomTheme();
        if (TextUtils.isEmpty(serializedTheme)) {
            mThemes.add(new CustomTheme(mContext.getString(R.string.custom_theme_title),
                    new HashMap<>(), null));
            return;
        }
        Map<String, String> customPackages = new HashMap<>();
        try {
            JSONObject theme = new JSONObject(serializedTheme);
            Iterator<String> keysIterator = theme.keys();

            while (keysIterator.hasNext()) {
                String category = keysIterator.next();
                customPackages.put(category, theme.getString(category));
            }
            CustomTheme.Builder builder = new CustomTheme.Builder();
            builder.setTitle(mContext.getString(R.string.custom_theme_title));
            addFontOverlay(builder, customPackages.get(OVERLAY_CATEGORY_FONT));
            addAndroidIconOverlay(builder, customPackages.get(OVERLAY_CATEGORY_ICON_ANDROID));
            addSysUiIconOverlay(builder, customPackages.get(OVERLAY_CATEGORY_ICON_SYSUI));
            addNoPreviewIconOverlay(builder, customPackages.get(OVERLAY_CATEGORY_ICON_SETTINGS));
            addNoPreviewIconOverlay(builder, customPackages.get(OVERLAY_CATEGORY_ICON_LAUNCHER));

            mThemes.add(builder.build());
        } catch (JSONException | NameNotFoundException | NotFoundException e) {
            Log.w(TAG, "Couldn't read stored custom theme, resetting", e);
            mThemes.add(new CustomTheme(mContext.getString(R.string.custom_theme_title),
                    new HashMap<>(), null));
        }
    }

    private String getOverlayPackage(String prefix, String themeName) {
+3 −1
Original line number Diff line number Diff line
@@ -36,10 +36,12 @@ import java.util.Map;
 */
public class OverlayManagerCompat {
    private final OverlayManager mOverlayManager;
    private final String[] mTargetPackages;
    private Map<Integer, Map<String, List<OverlayInfo>>> mOverlayByUser;

    public OverlayManagerCompat(Context context) {
        mOverlayManager = context.getSystemService(OverlayManager.class);
        mTargetPackages = ResourceConstants.getPackagesToOverlay(context);
    }

    /**
@@ -108,7 +110,7 @@ public class OverlayManagerCompat {
        }
        if (!mOverlayByUser.containsKey(userId)) {
            Map<String, List<OverlayInfo>> overlaysByTarget = new HashMap<>();
            for (String target : ResourceConstants.DEFAULT_TARGET_PACKAGES) {
            for (String target : mTargetPackages) {
                overlaysByTarget.put(target, getOverlayInfosForTarget(target, userId));
            }
            mOverlayByUser.put(userId, overlaysByTarget);
Loading