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

Commit 73300b8a authored by Lucas Silva's avatar Lucas Silva
Browse files

Add logic to parse previewImage from dreams.

Test: locally on device
Bug: 211662811
Change-Id: Icb782d87f7c83853ce5a746c94ee47621d56d207
parent 42739c0b
Loading
Loading
Loading
Loading
+59 −30
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.settingslib.dream;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -59,6 +60,7 @@ public class DreamBackend {
        public ComponentName componentName;
        public ComponentName settingsComponentName;
        public CharSequence description;
        public Drawable previewImage;

        @Override
        public String toString() {
@@ -120,15 +122,22 @@ public class DreamBackend {
                PackageManager.GET_META_DATA);
        List<DreamInfo> dreamInfos = new ArrayList<>(resolveInfos.size());
        for (ResolveInfo resolveInfo : resolveInfos) {
            if (resolveInfo.serviceInfo == null)
            if (resolveInfo.serviceInfo == null) {
                continue;
            }
            DreamInfo dreamInfo = new DreamInfo();
            dreamInfo.caption = resolveInfo.loadLabel(pm);
            dreamInfo.icon = resolveInfo.loadIcon(pm);
            dreamInfo.description = getDescription(resolveInfo, pm);
            dreamInfo.componentName = getDreamComponentName(resolveInfo);
            dreamInfo.isActive = dreamInfo.componentName.equals(activeDream);
            dreamInfo.settingsComponentName = getSettingsComponentName(pm, resolveInfo);

            final DreamMetadata dreamMetadata = getDreamMetadata(pm, resolveInfo);
            if (dreamMetadata != null) {
                dreamInfo.settingsComponentName = dreamMetadata.mSettingsActivity;
                dreamInfo.previewImage = dreamMetadata.mPreviewImage;
            }

            dreamInfos.add(dreamInfo);
        }
        Collections.sort(dreamInfos, mComparator);
@@ -325,58 +334,78 @@ public class DreamBackend {
    }

    private static ComponentName getDreamComponentName(ResolveInfo resolveInfo) {
        if (resolveInfo == null || resolveInfo.serviceInfo == null)
        if (resolveInfo == null || resolveInfo.serviceInfo == null) {
            return null;
        }
        return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
    }

    private static ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) {
        if (resolveInfo == null
                || resolveInfo.serviceInfo == null
                || resolveInfo.serviceInfo.metaData == null)
    private static final class DreamMetadata {
        @Nullable
        Drawable mPreviewImage;
        @Nullable
        ComponentName mSettingsActivity;
    }

    @Nullable
    private static TypedArray readMetadata(PackageManager pm, ServiceInfo serviceInfo) {
        if (serviceInfo == null || serviceInfo.metaData == null) {
            return null;
        String cn = null;
        XmlResourceParser parser = null;
        Exception caughtException = null;
        try {
            parser = resolveInfo.serviceInfo.loadXmlMetaData(pm, DreamService.DREAM_META_DATA);
        }
        try (XmlResourceParser parser =
                     serviceInfo.loadXmlMetaData(pm, DreamService.DREAM_META_DATA)) {
            if (parser == null) {
                Log.w(TAG, "No " + DreamService.DREAM_META_DATA + " meta-data");
                return null;
            }
            Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
            Resources res = pm.getResourcesForApplication(serviceInfo.applicationInfo);
            AttributeSet attrs = Xml.asAttributeSet(parser);
            int type;
            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
                    && type != XmlPullParser.START_TAG) {
            while (true) {
                final int type = parser.next();
                if (type == XmlPullParser.END_DOCUMENT || type == XmlPullParser.START_TAG) {
                    break;
                }
            }
            String nodeName = parser.getName();
            if (!"dream".equals(nodeName)) {
                Log.w(TAG, "Meta-data does not start with dream tag");
                return null;
            }
            TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.Dream);
            cn = sa.getString(com.android.internal.R.styleable.Dream_settingsActivity);
            sa.recycle();
            return res.obtainAttributes(attrs, com.android.internal.R.styleable.Dream);
        } catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) {
            caughtException = e;
        } finally {
            if (parser != null) parser.close();
        }
        if (caughtException != null) {
            Log.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
            Log.w(TAG, "Error parsing : " + serviceInfo.packageName, e);
            return null;
        }
        if (cn != null && cn.indexOf('/') < 0) {
            cn = resolveInfo.serviceInfo.packageName + "/" + cn;
    }
        return cn == null ? null : ComponentName.unflattenFromString(cn);

    private static ComponentName convertToComponentName(String flattenedString,
            ServiceInfo serviceInfo) {
        if (flattenedString == null) return null;

        if (flattenedString.indexOf('/') < 0) {
            flattenedString = serviceInfo.packageName + "/" + flattenedString;
        }
        return ComponentName.unflattenFromString(flattenedString);
    }

    private static DreamMetadata getDreamMetadata(PackageManager pm, ResolveInfo resolveInfo) {
        DreamMetadata result = new DreamMetadata();
        if (resolveInfo == null) return result;
        TypedArray rawMetadata = readMetadata(pm, resolveInfo.serviceInfo);
        if (rawMetadata == null) return result;
        result.mSettingsActivity = convertToComponentName(rawMetadata.getString(
                com.android.internal.R.styleable.Dream_settingsActivity), resolveInfo.serviceInfo);
        result.mPreviewImage = rawMetadata.getDrawable(
                com.android.internal.R.styleable.Dream_previewImage);
        rawMetadata.recycle();
        return result;
    }

    private static void logd(String msg, Object... args) {
        if (DEBUG)
        if (DEBUG) {
            Log.d(TAG, args == null || args.length == 0 ? msg : String.format(msg, args));
        }
    }

    private static class DreamInfoComparator implements Comparator<DreamInfo> {
        private final ComponentName mDefaultDream;