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

Commit 33db72b9 authored by Santiago Etchebehere's avatar Santiago Etchebehere Committed by Android (Google) Code Review
Browse files

Merge "Handle custom theme with default components" into ub-launcher3-master

parents c52bf568 97772353
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -71,8 +71,8 @@ public interface ResourceConstants {
    String THEME_SETTING = Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES;
    String CONFIG_BODY_FONT_FAMILY = "config_bodyFontFamily";
    String CONFIG_HEADLINE_FONT_FAMILY = "config_headlineFontFamily";
    String ICON_PREVIEW_DRAWABLE_NAME = "ic_wifi_signal_3";
    String[] SYSUI_ICONS_FOR_PREVIEW = {
    String[] ICONS_FOR_PREVIEW = {
            "ic_wifi_signal_3",
            "ic_qs_bluetooth_on",
            "ic_dnd",
            "ic_signal_flashlight",
+65 −51
Original line number Diff line number Diff line
@@ -19,14 +19,13 @@ import static com.android.customization.model.ResourceConstants.ACCENT_COLOR_DAR
import static com.android.customization.model.ResourceConstants.ACCENT_COLOR_LIGHT_NAME;
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.ICONS_FOR_PREVIEW;
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;

import android.content.Context;
@@ -235,27 +234,23 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB
    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));
            }
            addIconOverlay(builder, iconSysUiOverlayPackage, ICONS_FOR_PREVIEW);
        }
    }

    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));
            addIconOverlay(builder, iconAndroidOverlayPackage, ICONS_FOR_PREVIEW);
        } else {
            builder.addIcon(mContext.getResources().getDrawable(
                    Resources.getSystem().getIdentifier(
                            ICON_PREVIEW_DRAWABLE_NAME,
                            "drawable", ANDROID_PACKAGE), null));
            addSystemDefaultIcons(builder, ANDROID_PACKAGE, ICONS_FOR_PREVIEW);
        }
    }
    private void addIconOverlay(Builder builder, String packageName, String... previewIcons)
            throws NameNotFoundException {
        builder.addOverlayPackage(getOverlayCategory(packageName), packageName);
        for (String iconName : previewIcons) {
            builder.addIcon(loadIconPreviewDrawable(iconName, packageName, false));
        }
    }

@@ -270,6 +265,8 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB
                    .setHeadlineFontFamily(loadTypeface(
                            ResourceConstants.CONFIG_HEADLINE_FONT_FAMILY,
                            fontOverlayPackage));
        } else {
            addSystemDefaultFont(builder);
        }
    }

@@ -280,7 +277,6 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB
     */
    private void addDefaultTheme() {
        ThemeBundle.Builder builder = new Builder().asDefault();
        Resources system = Resources.getSystem();

        int titleId = mStubApkResources.getIdentifier(TITLE_PREFIX + DEFAULT_THEME_NAME,
                "string", mStubPackageName);
@@ -298,13 +294,7 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB
                    .setColorAccentDark(loadColor(ACCENT_COLOR_DARK_NAME, colorOverlayPackage));
        } catch (NameNotFoundException | NotFoundException e) {
            Log.d(TAG, "Didn't find color overlay for default theme, will use system default", e);
            int colorAccentLight = system.getColor(
                    system.getIdentifier(ACCENT_COLOR_LIGHT_NAME, "color", ANDROID_PACKAGE), null);
            builder.setColorAccentLight(colorAccentLight);

            int colorAccentDark = system.getColor(
                    system.getIdentifier(ACCENT_COLOR_DARK_NAME, "color", ANDROID_PACKAGE), null);
            builder.setColorAccentDark(colorAccentDark);
            addSystemDefaultColor(builder);
        }

        String fontOverlayPackage = getOverlayPackage(FONT_PREFIX, DEFAULT_THEME_NAME);
@@ -318,24 +308,16 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB
                            fontOverlayPackage));
        } catch (NameNotFoundException | NotFoundException e) {
            Log.d(TAG, "Didn't find font overlay for default theme, will use system default", e);
            String headlineFontFamily = system.getString(system.getIdentifier(
                    ResourceConstants.CONFIG_HEADLINE_FONT_FAMILY,"string", ANDROID_PACKAGE));
            String bodyFontFamily = system.getString(system.getIdentifier(
                    ResourceConstants.CONFIG_BODY_FONT_FAMILY,
                    "string", ANDROID_PACKAGE));
            builder.setHeadlineFontFamily(Typeface.create(headlineFontFamily, Typeface.NORMAL))
                    .setBodyFontFamily(Typeface.create(bodyFontFamily, Typeface.NORMAL));
            addSystemDefaultFont(builder);
        }

        try {
            String shapeOverlayPackage = getOverlayPackage(SHAPE_PREFIX, DEFAULT_THEME_NAME);
            builder.addOverlayPackage(getOverlayCategory(shapeOverlayPackage), shapeOverlayPackage)
                    .setShapePath(loadString(ICON_PREVIEW_DRAWABLE_NAME, colorOverlayPackage));
                    .setShapePath(loadString(CONFIG_ICON_MASK, shapeOverlayPackage));
        } catch (NameNotFoundException | NotFoundException e) {
            Log.d(TAG, "Didn't find shape overlay for default theme, will use system default", e);
            String iconMaskPath = system.getString(system.getIdentifier(CONFIG_ICON_MASK,
                    "string", ANDROID_PACKAGE));
            builder.setShapePath(iconMaskPath);
            addSystemDefaultShape(builder);
        }
        for (String packageName : mShapePreviewIconPackages) {
            try {
@@ -353,13 +335,11 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB
            builder.addOverlayPackage(getOverlayCategory(iconAndroidOverlayPackage),
                        iconAndroidOverlayPackage)
                    .addIcon(loadIconPreviewDrawable(ICON_ANDROID_PREFIX,
                            iconAndroidOverlayPackage));
                            iconAndroidOverlayPackage, false));
        } catch (NameNotFoundException | NotFoundException e) {
            Log.d(TAG, "Didn't find Android icons overlay for default theme, using system default",
                    e);
            builder.addIcon(system.getDrawable(system.getIdentifier(
                    ICON_PREVIEW_DRAWABLE_NAME,
                            "drawable", ANDROID_PACKAGE), null));
            addSystemDefaultIcons(builder, ANDROID_PACKAGE, ICONS_FOR_PREVIEW);
        }

        try {
@@ -369,13 +349,7 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB
        } catch (NameNotFoundException | NotFoundException e) {
            Log.d(TAG, "Didn't find SystemUi icons overlay for default theme, using system default",
                    e);
            try {
                for (String iconName : SYSUI_ICONS_FOR_PREVIEW) {
                    builder.addIcon(loadIconPreviewDrawable(iconName, SYSUI_PACKAGE));
                }
            } catch (NameNotFoundException | NotFoundException e2) {
                Log.w(TAG, "Didn't find SystemUi package icons, will skip preview", e);
            }
            addSystemDefaultIcons(builder, SYSUI_PACKAGE, ICONS_FOR_PREVIEW);
        }

        try {
@@ -405,6 +379,45 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB
        mThemes.add(builder.build());
    }

    private void addSystemDefaultIcons(Builder builder, String packageName, String... previewIcons) {
        try {
            for (String iconName : previewIcons) {
                builder.addIcon(loadIconPreviewDrawable(iconName, packageName, true));
            }
        } catch (NameNotFoundException | NotFoundException e) {
            Log.w(TAG, "Didn't find android package icons, will skip preview", e);
        }
    }

    private void addSystemDefaultShape(Builder builder) {
        Resources system = Resources.getSystem();
        String iconMaskPath = system.getString(system.getIdentifier(CONFIG_ICON_MASK,
                "string", ANDROID_PACKAGE));
        builder.setShapePath(iconMaskPath);
    }

    private void addSystemDefaultColor(Builder builder) {
        Resources system = Resources.getSystem();
        int colorAccentLight = system.getColor(
                system.getIdentifier(ACCENT_COLOR_LIGHT_NAME, "color", ANDROID_PACKAGE), null);
        builder.setColorAccentLight(colorAccentLight);

        int colorAccentDark = system.getColor(
                system.getIdentifier(ACCENT_COLOR_DARK_NAME, "color", ANDROID_PACKAGE), null);
        builder.setColorAccentDark(colorAccentDark);
    }

    private void addSystemDefaultFont(Builder builder) {
        Resources system = Resources.getSystem();
        String headlineFontFamily = system.getString(system.getIdentifier(
                ResourceConstants.CONFIG_HEADLINE_FONT_FAMILY,"string", ANDROID_PACKAGE));
        String bodyFontFamily = system.getString(system.getIdentifier(
                ResourceConstants.CONFIG_BODY_FONT_FAMILY,
                "string", ANDROID_PACKAGE));
        builder.setHeadlineFontFamily(Typeface.create(headlineFontFamily, Typeface.NORMAL))
                .setBodyFontFamily(Typeface.create(bodyFontFamily, Typeface.NORMAL));
    }

    @Override
    public void storeCustomTheme(CustomTheme theme) {
        mCustomizationPreferences.storeCustomTheme(theme.getSerializedPackages());
@@ -501,12 +514,13 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB
        return overlayRes.getString(overlayRes.getIdentifier(stringName, "string", packageName));
    }

    private Drawable loadIconPreviewDrawable(String drawableName, String packageName)
         throws NameNotFoundException, NotFoundException {
    private Drawable loadIconPreviewDrawable(String drawableName, String packageName,
            boolean fromSystem) throws NameNotFoundException, NotFoundException {

        Resources overlayRes = mContext.getPackageManager().getResourcesForApplication(packageName);
        return overlayRes.getDrawable(
                overlayRes.getIdentifier(drawableName, "drawable", packageName), null);
        Resources packageRes = mContext.getPackageManager().getResourcesForApplication(packageName);
        Resources res = fromSystem ? Resources.getSystem() : packageRes;
        return res.getDrawable(
                packageRes.getIdentifier(drawableName, "drawable", packageName), null);
    }

    @Nullable
+22 −3
Original line number Diff line number Diff line
@@ -52,8 +52,11 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Represents a Theme component available in the system as a "persona" bundle.
@@ -148,16 +151,32 @@ public class ThemeBundle implements CustomizationOption<ThemeBundle> {
        return mIsDefault;
    }

    Collection<String> getAllPackages() {
        return mPackagesByCategory.values();
    public Map<String, String> getPackagesByCategory() {
        return mPackagesByCategory;
    }

    public String getSerializedPackages() {
        if (isDefault()) {
            return "";
        }
        JSONObject json = new JSONObject(mPackagesByCategory);
        // Remove items with null values to avoid deserialization issues.
        removeNullValues(json);
        return json.toString();
    }

        return new JSONObject(mPackagesByCategory).toString();
    private void removeNullValues(JSONObject json) {
        Iterator<String> keys = json.keys();
        Set<String> keysToRemove = new HashSet<>();
        while(keys.hasNext()) {
            String key = keys.next();
            if (json.isNull(key)) {
                keysToRemove.add(key);
            }
        }
        for (String key : keysToRemove) {
            json.remove(key);
        }
    }


+23 −7
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import static com.android.customization.model.ResourceConstants.SYSUI_PACKAGE;
import android.graphics.Point;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;

import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
@@ -151,21 +152,26 @@ public class ThemeManager implements CustomizationManager<ThemeBundle> {
    private void applyOverlays(ThemeBundle theme, Callback callback) {
        boolean allApplied = true;
        if (theme.isDefault()) {
            allApplied &= disableCurrentOverlay(ANDROID_PACKAGE, OVERLAY_CATEGORY_SHAPE);
            allApplied &= disableCurrentOverlay(ANDROID_PACKAGE, OVERLAY_CATEGORY_COLOR);
            allApplied &= disableCurrentOverlay(ANDROID_PACKAGE, OVERLAY_CATEGORY_FONT);
            allApplied &= disableCurrentOverlay(ANDROID_PACKAGE, OVERLAY_CATEGORY_SHAPE);
            allApplied &= disableCurrentOverlay(ANDROID_PACKAGE, OVERLAY_CATEGORY_ICON_ANDROID);
            allApplied &= disableCurrentOverlay(SYSUI_PACKAGE, OVERLAY_CATEGORY_ICON_SYSUI);
            allApplied &= disableCurrentOverlay(SETTINGS_PACKAGE, OVERLAY_CATEGORY_ICON_SETTINGS);
            allApplied &= disableCurrentOverlay(ResourceConstants.getLauncherPackage(mActivity),
                    OVERLAY_CATEGORY_ICON_LAUNCHER);
        } else {
            for (String packageName : theme.getAllPackages()) {
                if (packageName != null) {
                    allApplied &= mOverlayManagerCompat.setEnabledExclusiveInCategory(packageName,
                            UserHandle.myUserId());
                }
            }
            allApplied &= applyOverlayOrDefault(theme, ANDROID_PACKAGE, OVERLAY_CATEGORY_SHAPE);
            allApplied &= applyOverlayOrDefault(theme, ANDROID_PACKAGE, OVERLAY_CATEGORY_COLOR);
            allApplied &= applyOverlayOrDefault(theme, ANDROID_PACKAGE, OVERLAY_CATEGORY_FONT);
            allApplied &= applyOverlayOrDefault(theme, ANDROID_PACKAGE,
                    OVERLAY_CATEGORY_ICON_ANDROID);
            allApplied &= applyOverlayOrDefault(theme, SYSUI_PACKAGE, OVERLAY_CATEGORY_ICON_SYSUI);
            allApplied &= applyOverlayOrDefault(theme, SETTINGS_PACKAGE,
                    OVERLAY_CATEGORY_ICON_SETTINGS);
            allApplied &= applyOverlayOrDefault(theme,
                    ResourceConstants.getLauncherPackage(mActivity),
                    OVERLAY_CATEGORY_ICON_LAUNCHER);
        }
        allApplied &= Settings.Secure.putString(mActivity.getContentResolver(),
                ResourceConstants.THEME_SETTING, theme.getSerializedPackages());
@@ -198,6 +204,16 @@ public class ThemeManager implements CustomizationManager<ThemeBundle> {
        return true;
    }

    private boolean applyOverlayOrDefault(ThemeBundle theme, String targetPkg, String category) {
        String themePackage = theme.getPackagesByCategory().get(category);
        if (!TextUtils.isEmpty(themePackage)) {
            return mOverlayManagerCompat.setEnabledExclusiveInCategory(themePackage,
                    UserHandle.myUserId());
        } else {
            return disableCurrentOverlay(targetPkg, category);
        }
    }

    public Map<String, String> getCurrentOverlays() {
        if (mCurrentOverlays == null) {
            mCurrentOverlays = mOverlayManagerCompat.getEnabledOverlaysForTargets(
+2 −2
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_ICON_SYSUI;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SHAPE;
import static com.android.customization.model.ResourceConstants.PATH_SIZE;
import static com.android.customization.model.ResourceConstants.SYSUI_ICONS_FOR_PREVIEW;
import static com.android.customization.model.ResourceConstants.ICONS_FOR_PREVIEW;
import static com.android.customization.model.ResourceConstants.SYSUI_PACKAGE;
import static com.android.customization.model.theme.custom.ThemeComponentOption.ColorOption.COLOR_TILES_ICON_IDS;

@@ -77,7 +77,7 @@ public class ColorOptionsProvider extends ThemeComponentOptionProvider<ColorOpti
        if (TextUtils.isEmpty(iconPackage)) {
            iconPackage = SYSUI_PACKAGE;
        }
        for (String iconName : SYSUI_ICONS_FOR_PREVIEW) {
        for (String iconName : ICONS_FOR_PREVIEW) {
            try {
                if (previewIcons.size() == COLOR_TILES_ICON_IDS.length) {
                    break;
Loading