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

Commit 7ceba027 authored by chihhangchuang's avatar chihhangchuang
Browse files

Creates ShapeAppIcon class to represent a shape app icon and its name

Test: Manually
Fixes: 157535141
Change-Id: I971e37768734b1cc623ce690f5f5bdc494357cd4
parent 6cbdde99
Loading
Loading
Loading
Loading
+5 −7
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import androidx.annotation.Nullable;
import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
import com.android.customization.model.ResourcesApkProvider;
import com.android.customization.model.theme.ThemeBundle.Builder;
import com.android.customization.model.theme.ThemeBundle.PreviewInfo.ShapeAppIcon;
import com.android.customization.model.theme.custom.CustomTheme;
import com.android.customization.module.CustomizationPreferences;
import com.android.wallpaper.R;
@@ -211,28 +212,25 @@ public class DefaultThemeProvider extends ResourcesApkProvider implements ThemeB
            mOverlayProvider.addSystemDefaultShape(builder);
        }

        List<Drawable> icons = new ArrayList<>();
        List<String> names = new ArrayList<>();
        List<ShapeAppIcon> icons = new ArrayList<>();
        for (String packageName : mOverlayProvider.getShapePreviewIconPackages()) {
            Drawable icon = null;
            String name = null;
            CharSequence name = null;
            try {
                icon = mContext.getPackageManager().getApplicationIcon(packageName);
                ApplicationInfo appInfo = mContext.getPackageManager()
                        .getApplicationInfo(packageName, /* flag= */ 0);
                name = String.valueOf(mContext.getPackageManager().getApplicationLabel(appInfo));
                name = mContext.getPackageManager().getApplicationLabel(appInfo);
            } catch (NameNotFoundException e) {
                Log.d(TAG, "Couldn't find app " + packageName + ", won't use it for icon shape"
                        + "preview");
            } finally {
                if (icon != null && !TextUtils.isEmpty(name)) {
                    icons.add(icon);
                    names.add(name);
                    icons.add(new ShapeAppIcon(icon, name));
                }
            }
        }
        builder.setShapePreviewIcons(icons);
        builder.setShapePreviewIconNames(names);

        try {
            String iconAndroidOverlayPackage = getOverlayPackage(ICON_ANDROID_PREFIX,
+5 −7
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import androidx.annotation.Nullable;

import com.android.customization.model.ResourceConstants;
import com.android.customization.model.theme.ThemeBundle.Builder;
import com.android.customization.model.theme.ThemeBundle.PreviewInfo.ShapeAppIcon;
import com.android.wallpaper.R;

import java.util.ArrayList;
@@ -100,29 +101,26 @@ class OverlayThemeExtractor {
    }

    private void addShapePreviewIcons(Builder builder) {
        List<Drawable> icons = new ArrayList<>();
        List<String> names = new ArrayList<>();
        List<ShapeAppIcon> icons = new ArrayList<>();
        for (String packageName : mShapePreviewIconPackages) {
            Drawable icon = null;
            String name = null;
            CharSequence name = null;
            try {
                icon = mContext.getPackageManager().getApplicationIcon(packageName);
                // Add the shape icon app name.
                ApplicationInfo appInfo = mContext.getPackageManager()
                        .getApplicationInfo(packageName, /* flag= */ 0);
                name = String.valueOf(mContext.getPackageManager().getApplicationLabel(appInfo));
                name = mContext.getPackageManager().getApplicationLabel(appInfo);
            } catch (NameNotFoundException e) {
                Log.d(TAG, "Couldn't find app " + packageName
                        + ", won't use it for icon shape preview");
            } finally {
                if (icon != null && !TextUtils.isEmpty(name)) {
                    icons.add(icon);
                    names.add(name);
                    icons.add(new ShapeAppIcon(icon, name));
                }
            }
        }
        builder.setShapePreviewIcons(icons);
        builder.setShapePreviewIconNames(names);
    }

    void addNoPreviewIconOverlay(Builder builder, String overlayPackage) {
+37 −27
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import androidx.core.graphics.PathParser;

import com.android.customization.model.CustomizationManager;
import com.android.customization.model.CustomizationOption;
import com.android.customization.model.theme.ThemeBundle.PreviewInfo.ShapeAppIcon;
import com.android.customization.widget.DynamicAdaptiveIconDrawable;
import com.android.wallpaper.R;
import com.android.wallpaper.asset.Asset;
@@ -250,14 +251,34 @@ public class ThemeBundle implements CustomizationOption<ThemeBundle> {
        @ColorInt public final int colorAccentDark;
        public final List<Drawable> icons;
        public final Drawable shapeDrawable;
        public final List<Drawable> shapeAppIcons;
        public final List<String> shapeAppIconNames;
        public final List<ShapeAppIcon> shapeAppIcons;
        @Dimension public final int bottomSheeetCornerRadius;

        /** A class to represent an App icon and its name. */
        public static class ShapeAppIcon {
            private Drawable mIconDrawable;
            private CharSequence mAppName;

            public ShapeAppIcon(Drawable icon, CharSequence appName) {
                mIconDrawable = icon;
                mAppName = appName;
            }

            /** Returns the app icon drawable. */
            public Drawable getDrawable() {
                return mIconDrawable;
            }

            /** Returns the app name. */
            public CharSequence getAppName() {
                return mAppName;
            }
        }

        private PreviewInfo(Context context, Typeface bodyFontFamily, Typeface headlineFontFamily,
                int colorAccentLight, int colorAccentDark, List<Drawable> icons,
                Drawable shapeDrawable, @Dimension int cornerRadius,
                List<Drawable> shapeAppIcons, List<String> shapeAppIconNames) {
                List<ShapeAppIcon> shapeAppIcons) {
            this.bodyFontFamily = bodyFontFamily;
            this.headlineFontFamily = headlineFontFamily;
            this.colorAccentLight = colorAccentLight;
@@ -266,7 +287,6 @@ public class ThemeBundle implements CustomizationOption<ThemeBundle> {
            this.shapeDrawable = shapeDrawable;
            this.bottomSheeetCornerRadius = cornerRadius;
            this.shapeAppIcons = shapeAppIcons;
            this.shapeAppIconNames = shapeAppIconNames;
        }

        /**
@@ -293,8 +313,7 @@ public class ThemeBundle implements CustomizationOption<ThemeBundle> {
        private boolean mIsDefault;
        @Dimension private int mCornerRadius;
        protected Map<String, String> mPackages = new HashMap<>();
        private List<Drawable> mAppIcons = new ArrayList<>();
        private List<String> mAppIconNames = new ArrayList<>();
        private List<ShapeAppIcon> mAppIcons = new ArrayList<>();

        public ThemeBundle build(Context context) {
            return new ThemeBundle(mTitle, mPackages, mIsDefault, createPreviewInfo(context));
@@ -302,8 +321,7 @@ public class ThemeBundle implements CustomizationOption<ThemeBundle> {

        public PreviewInfo createPreviewInfo(Context context) {
            ShapeDrawable shapeDrawable = null;
            List<Drawable> shapeIcons = new ArrayList<>();
            List<String> shapeIconNames = new ArrayList<>();
            List<ShapeAppIcon> shapeIcons = new ArrayList<>();
            Path path = mShapePath;
            if (!TextUtils.isEmpty(mPathString)) {
                path = PathParser.createPathFromPathData(mPathString);
@@ -313,25 +331,23 @@ public class ThemeBundle implements CustomizationOption<ThemeBundle> {
                shapeDrawable = new ShapeDrawable(shape);
                shapeDrawable.setIntrinsicHeight((int) PATH_SIZE);
                shapeDrawable.setIntrinsicWidth((int) PATH_SIZE);
                for (int i = 0; i < mAppIcons.size(); i++) {
                    Drawable icon = mAppIcons.get(i);
                    String name = mAppIconNames.get(i);
                    if (icon instanceof AdaptiveIconDrawable) {
                        AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) icon;
                        shapeIcons.add(new DynamicAdaptiveIconDrawable(adaptiveIcon.getBackground(),
                                adaptiveIcon.getForeground(), path));
                        shapeIconNames.add(name);
                    } else if (icon instanceof DynamicAdaptiveIconDrawable) {
                for (ShapeAppIcon icon : mAppIcons) {
                    Drawable drawable = icon.getDrawable();
                    if (drawable instanceof AdaptiveIconDrawable) {
                        AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) drawable;
                        shapeIcons.add(new ShapeAppIcon(
                                new DynamicAdaptiveIconDrawable(adaptiveIcon.getBackground(),
                                        adaptiveIcon.getForeground(), path),
                                icon.getAppName()));
                    } else if (drawable instanceof DynamicAdaptiveIconDrawable) {
                        shapeIcons.add(icon);
                        shapeIconNames.add(name);
                    }
                    // TODO: add iconloader library's legacy treatment helper methods for
                    //  non-adaptive icons
                }
            }
            return new PreviewInfo(context, mBodyFontFamily, mHeadlineFontFamily, mColorAccentLight,
                    mColorAccentDark, mIcons, shapeDrawable, mCornerRadius, shapeIcons,
                    shapeIconNames);
                    mColorAccentDark, mIcons, shapeDrawable, mCornerRadius, shapeIcons);
        }

        public Map<String, String> getPackages() {
@@ -392,18 +408,12 @@ public class ThemeBundle implements CustomizationOption<ThemeBundle> {
            return this;
        }

        public Builder setShapePreviewIcons(List<Drawable> appIcons) {
        public Builder setShapePreviewIcons(List<ShapeAppIcon> appIcons) {
            mAppIcons.clear();
            mAppIcons.addAll(appIcons);
            return this;
        }

        public Builder setShapePreviewIconNames(List<String> appIconNames) {
            mAppIconNames.clear();
            mAppIconNames.addAll(appIconNames);
            return this;
        }

        public Builder setBottomSheetCornerRadius(@Dimension int radius) {
            mCornerRadius = radius;
            return this;
+12 −20
Original line number Diff line number Diff line
@@ -37,10 +37,10 @@ import android.util.Log;

import androidx.annotation.Dimension;
import androidx.core.graphics.PathParser;
import androidx.core.util.Pair;

import com.android.customization.model.ResourceConstants;
import com.android.customization.model.theme.OverlayManagerCompat;
import com.android.customization.model.theme.ThemeBundle.PreviewInfo.ShapeAppIcon;
import com.android.customization.model.theme.custom.ThemeComponentOption.ShapeOption;
import com.android.customization.widget.DynamicAdaptiveIconDrawable;
import com.android.wallpaper.R;
@@ -73,14 +73,11 @@ public class ShapeOptionsProvider extends ThemeComponentOptionProvider<ShapeOpti
            try {
                Path path = loadPath(mContext.getPackageManager()
                        .getResourcesForApplication(overlayPackage), overlayPackage);
                ShapeDrawable shapeDrawable = createShapeDrawable(path);
                PackageManager pm = mContext.getPackageManager();
                String label = pm.getApplicationInfo(overlayPackage, 0).loadLabel(pm).toString();
                Pair<List<Drawable>, List<String>> shapedIconsAndNames =
                        getShapedIconsAndNames(path);
                mOptions.add(new ShapeOption(overlayPackage, label, path,
                        loadCornerRadius(overlayPackage), shapeDrawable, shapedIconsAndNames.first,
                        shapedIconsAndNames.second));
                        loadCornerRadius(overlayPackage), createShapeDrawable(path),
                        getShapedAppIcons(path)));
            } catch (NameNotFoundException | NotFoundException e) {
                Log.w(TAG, String.format("Couldn't load shape overlay %s, will skip it",
                        overlayPackage), e);
@@ -91,13 +88,11 @@ public class ShapeOptionsProvider extends ThemeComponentOptionProvider<ShapeOpti
    private void addDefault() {
        Resources system = Resources.getSystem();
        Path path = loadPath(system, ANDROID_PACKAGE);
        ShapeDrawable shapeDrawable = createShapeDrawable(path);
        Pair<List<Drawable>, List<String>> shapedIconsAndNames = getShapedIconsAndNames(path);
        mOptions.add(new ShapeOption(null, mContext.getString(R.string.default_theme_title), path,
                system.getDimensionPixelOffset(
                        system.getIdentifier(ResourceConstants.CONFIG_CORNERRADIUS,
                                "dimen", ResourceConstants.ANDROID_PACKAGE)),
                shapeDrawable, shapedIconsAndNames.first, shapedIconsAndNames.second));
                createShapeDrawable(path), getShapedAppIcons(path)));
    }

    private ShapeDrawable createShapeDrawable(Path path) {
@@ -108,12 +103,11 @@ public class ShapeOptionsProvider extends ThemeComponentOptionProvider<ShapeOpti
        return shapeDrawable;
    }

    private Pair<List<Drawable>, List<String>> getShapedIconsAndNames(Path path) {
        List<Drawable> icons = new ArrayList<>();
        List<String> names = new ArrayList<>();
    private List<ShapeAppIcon> getShapedAppIcons(Path path) {
        List<ShapeAppIcon> shapedAppIcons = new ArrayList<>();
        for (String packageName : mShapePreviewIconPackages) {
            Drawable icon = null;
            String name = null;
            CharSequence name = null;
            try {
                Drawable appIcon = mContext.getPackageManager().getApplicationIcon(packageName);
                if (appIcon instanceof AdaptiveIconDrawable) {
@@ -123,20 +117,18 @@ public class ShapeOptionsProvider extends ThemeComponentOptionProvider<ShapeOpti

                    ApplicationInfo appInfo = mContext.getPackageManager()
                            .getApplicationInfo(packageName, /* flag= */ 0);
                    name = String.valueOf(
                            mContext.getPackageManager().getApplicationLabel(appInfo));
                    name = mContext.getPackageManager().getApplicationLabel(appInfo);
                }
            } catch (NameNotFoundException e) {
                Log.d(TAG, "Couldn't find app " + packageName
                        + ", won't use it for icon shape preview");
            } finally {
                if (icon != null && !TextUtils.isEmpty(name)) {
                    icons.add(icon);
                    names.add(name);
                    shapedAppIcons.add(new ShapeAppIcon(icon, name));
                }
            }
        }
        return Pair.create(icons, names);
        return shapedAppIcons;
    }

    private Path loadPath(Resources overlayRes, String packageName) {
+5 −7
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import androidx.core.graphics.ColorUtils;
import com.android.customization.model.CustomizationManager;
import com.android.customization.model.CustomizationOption;
import com.android.customization.model.ResourceConstants;
import com.android.customization.model.theme.ThemeBundle.PreviewInfo.ShapeAppIcon;
import com.android.customization.model.theme.custom.CustomTheme.Builder;
import com.android.wallpaper.R;

@@ -416,8 +417,7 @@ public abstract class ThemeComponentOption implements CustomizationOption<ThemeC
    public static class ShapeOption extends ThemeComponentOption {

        private final LayerDrawable mShape;
        private final List<Drawable> mAppIcons;
        private final List<String> mAppIconNames;
        private final List<ShapeAppIcon> mAppIcons;
        private final String mLabel;
        private final Path mPath;
        private final int mCornerRadius;
@@ -428,11 +428,10 @@ public abstract class ThemeComponentOption implements CustomizationOption<ThemeC

        ShapeOption(String packageName, String label, Path path,
                @Dimension int cornerRadius, Drawable shapeDrawable,
                List<Drawable> appIcons, List<String> appIconNames) {
                List<ShapeAppIcon> appIcons) {
            addOverlayPackage(OVERLAY_CATEGORY_SHAPE, packageName);
            mLabel = label;
            mAppIcons = appIcons;
            mAppIconNames = appIconNames;
            mPath = path;
            mCornerRadius = cornerRadius;
            Drawable background = shapeDrawable.getConstantState().newDrawable();
@@ -491,7 +490,7 @@ public abstract class ThemeComponentOption implements CustomizationOption<ThemeC
            }
            for (int i = 0; i < mShapeIconIds.length && i < mAppIcons.size(); i++) {
                ImageView iconView = cardBody.findViewById(mShapeIconIds[i]);
                iconView.setBackground(mAppIcons.get(i));
                iconView.setBackground(mAppIcons.get(i).getDrawable());
            }
        }

@@ -499,8 +498,7 @@ public abstract class ThemeComponentOption implements CustomizationOption<ThemeC
        public Builder buildStep(Builder builder) {
            builder.setShapePath(mPath)
                    .setBottomSheetCornerRadius(mCornerRadius)
                    .setShapePreviewIcons(mAppIcons)
                    .setShapePreviewIconNames(mAppIconNames);
                    .setShapePreviewIcons(mAppIcons);
            return super.buildStep(builder);
        }
    }
Loading