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

Commit f9275345 authored by Mehdi Alizadeh's avatar Mehdi Alizadeh Committed by Android (Google) Code Review
Browse files

Merge changes Ibfb3cf6f,I9a4bd220 into rvc-dev

* changes:
  Load Uri based shortcut drawable in LauncherApps
  Adds icon URI field to shortcutInfo
parents 6d6ddf45 98ffa48a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -103,4 +103,7 @@ interface ILauncherApps {
            in UserHandle user);
    void uncacheShortcuts(String callingPackage, String packageName, in List<String> shortcutIds,
            in UserHandle user);

    String getShortcutIconUri(String callingPackage, String packageName, String shortcutId,
            int userId);
}
+59 −20
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -67,8 +68,10 @@ import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Pair;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.function.pooled.PooledLambda;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -1197,6 +1200,35 @@ public class LauncherApps {
        }
    }

    /**
     * @hide internal/unit tests only
     */
    @VisibleForTesting
    public ParcelFileDescriptor getUriShortcutIconFd(@NonNull ShortcutInfo shortcut) {
        return getUriShortcutIconFd(shortcut.getPackage(), shortcut.getId(), shortcut.getUserId());
    }

    private ParcelFileDescriptor getUriShortcutIconFd(@NonNull String packageName,
            @NonNull String shortcutId, int userId) {
        String uri = null;
        try {
            uri = mService.getShortcutIconUri(mContext.getPackageName(), packageName, shortcutId,
                    userId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }

        if (uri == null) {
            return null;
        }
        try {
            return mContext.getContentResolver().openFileDescriptor(Uri.parse(uri), "r");
        } catch (FileNotFoundException e) {
            Log.e(TAG, "Icon file not found: " + uri);
            return null;
        }
    }

    /**
     * Returns the icon for this shortcut, without any badging for the profile.
     *
@@ -1217,26 +1249,10 @@ public class LauncherApps {
    public Drawable getShortcutIconDrawable(@NonNull ShortcutInfo shortcut, int density) {
        if (shortcut.hasIconFile()) {
            final ParcelFileDescriptor pfd = getShortcutIconFd(shortcut);
            if (pfd == null) {
                return null;
            }
            try {
                final Bitmap bmp = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor());
                if (bmp != null) {
                    BitmapDrawable dr = new BitmapDrawable(mContext.getResources(), bmp);
                    if (shortcut.hasAdaptiveBitmap()) {
                        return new AdaptiveIconDrawable(null, dr);
                    } else {
                        return dr;
                    }
                }
                return null;
            } finally {
                try {
                    pfd.close();
                } catch (IOException ignore) {
                }
            }
            return loadDrawableFromFileDescriptor(pfd, shortcut.hasAdaptiveBitmap());
        } else if (shortcut.hasIconUri()) {
            final ParcelFileDescriptor pfd = getUriShortcutIconFd(shortcut);
            return loadDrawableFromFileDescriptor(pfd, shortcut.hasAdaptiveBitmap());
        } else if (shortcut.hasIconResource()) {
            return loadDrawableResourceFromPackage(shortcut.getPackage(),
                    shortcut.getIconResourceId(), shortcut.getUserHandle(), density);
@@ -1260,6 +1276,29 @@ public class LauncherApps {
        }
    }

    private Drawable loadDrawableFromFileDescriptor(ParcelFileDescriptor pfd, boolean adaptive) {
        if (pfd == null) {
            return null;
        }
        try {
            final Bitmap bmp = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor());
            if (bmp != null) {
                BitmapDrawable dr = new BitmapDrawable(mContext.getResources(), bmp);
                if (adaptive) {
                    return new AdaptiveIconDrawable(null, dr);
                } else {
                    return dr;
                }
            }
            return null;
        } finally {
            try {
                pfd.close();
            } catch (IOException ignore) {
            }
        }
    }

    private Drawable loadDrawableResourceFromPackage(String packageName, int resId,
            UserHandle user, int density) {
        try {
+47 −2
Original line number Diff line number Diff line
@@ -122,6 +122,9 @@ public final class ShortcutInfo implements Parcelable {
    /** @hide */
    public static final int FLAG_CACHED = 1 << 14;

    /** @hide */
    public static final int FLAG_HAS_ICON_URI = 1 << 15;

    /** @hide */
    @IntDef(flag = true, prefix = { "FLAG_" }, value = {
            FLAG_DYNAMIC,
@@ -139,6 +142,7 @@ public final class ShortcutInfo implements Parcelable {
            FLAG_SHADOW,
            FLAG_LONG_LIVED,
            FLAG_CACHED,
            FLAG_HAS_ICON_URI,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ShortcutFlags {}
@@ -400,6 +404,9 @@ public final class ShortcutInfo implements Parcelable {

    private String mIconResName;

    // Internal use only.
    private String mIconUri;

    // Internal use only.
    @Nullable
    private String mBitmapPath;
@@ -554,6 +561,7 @@ public final class ShortcutInfo implements Parcelable {
            if ((cloneFlags & CLONE_REMOVE_ICON) == 0) {
                mIcon = source.mIcon;
                mBitmapPath = source.mBitmapPath;
                mIconUri = source.mIconUri;
            }

            mTitle = source.mTitle;
@@ -856,6 +864,7 @@ public final class ShortcutInfo implements Parcelable {
            mIconResId = 0;
            mIconResName = null;
            mBitmapPath = null;
            mIconUri = null;
        }
        if (source.mTitle != null) {
            mTitle = source.mTitle;
@@ -916,6 +925,8 @@ public final class ShortcutInfo implements Parcelable {
            case Icon.TYPE_RESOURCE:
            case Icon.TYPE_BITMAP:
            case Icon.TYPE_ADAPTIVE_BITMAP:
            case Icon.TYPE_URI:
            case Icon.TYPE_URI_ADAPTIVE_BITMAP:
                break; // OK
            default:
                throw getInvalidIconException();
@@ -1792,6 +1803,15 @@ public final class ShortcutInfo implements Parcelable {
        return hasFlags(FLAG_HAS_ICON_RES);
    }

    /**
     * Return whether a shortcut's icon is provided via a URI.
     *
     * @hide internal/unit tests only
     */
    public boolean hasIconUri() {
        return hasFlags(FLAG_HAS_ICON_URI);
    }

    /** @hide */
    public boolean hasStringResources() {
        return (mTitleResId != 0) || (mTextResId != 0) || (mDisabledMessageResId != 0);
@@ -1911,6 +1931,19 @@ public final class ShortcutInfo implements Parcelable {
        return mIconResId;
    }

    /** @hide */
    public void setIconUri(String iconUri) {
        mIconUri = iconUri;
    }

    /**
     * Get the Uri for the icon, valid only when {@link #hasIconUri()} } is true.
     * @hide internal / tests only.
     */
    public String getIconUri() {
        return mIconUri;
    }

    /**
     * Bitmap path.  Note this will be null even if {@link #hasIconFile()} is set when the save
     * is pending.  Use {@link #isIconPendingSave()} to check it.
@@ -2062,6 +2095,7 @@ public final class ShortcutInfo implements Parcelable {

        mPersons = source.readParcelableArray(cl, Person.class);
        mLocusId = source.readParcelable(cl);
        mIconUri = source.readString();
    }

    @Override
@@ -2112,6 +2146,7 @@ public final class ShortcutInfo implements Parcelable {

        dest.writeParcelableArray(mPersons, flags);
        dest.writeParcelable(mLocusId, flags);
        dest.writeString(mIconUri);
    }

    public static final @android.annotation.NonNull Creator<ShortcutInfo> CREATOR =
@@ -2203,6 +2238,12 @@ public final class ShortcutInfo implements Parcelable {
        if (hasIconResource()) {
            sb.append("Ic-r");
        }
        if (hasIconUri()) {
            sb.append("Ic-u");
        }
        if (hasAdaptiveBitmap()) {
            sb.append("Ic-a");
        }
        if (hasKeyFieldsOnly()) {
            sb.append("Key");
        }
@@ -2325,6 +2366,9 @@ public final class ShortcutInfo implements Parcelable {

            sb.append(", bitmapPath=");
            sb.append(mBitmapPath);

            sb.append(", iconUri=");
            sb.append(mIconUri);
        }

        if (mLocusId != null) {
@@ -2343,8 +2387,8 @@ public final class ShortcutInfo implements Parcelable {
            CharSequence disabledMessage, int disabledMessageResId, String disabledMessageResName,
            Set<String> categories, Intent[] intentsWithExtras, int rank, PersistableBundle extras,
            long lastChangedTimestamp,
            int flags, int iconResId, String iconResName, String bitmapPath, int disabledReason,
            Person[] persons, LocusId locusId) {
            int flags, int iconResId, String iconResName, String bitmapPath, String iconUri,
            int disabledReason, Person[] persons, LocusId locusId) {
        mUserId = userId;
        mId = id;
        mPackageName = packageName;
@@ -2369,6 +2413,7 @@ public final class ShortcutInfo implements Parcelable {
        mIconResId = iconResId;
        mIconResName = iconResName;
        mBitmapPath = bitmapPath;
        mIconUri = iconUri;
        mDisabledReason = disabledReason;
        mPersons = persons;
        mLocusId = locusId;
+6 −0
Original line number Diff line number Diff line
@@ -103,4 +103,10 @@ public abstract class ShortcutServiceInternal {
     */
    public abstract List<ShortcutManager.ShareShortcutInfo> getShareTargets(
            @NonNull String callingPackage, @NonNull IntentFilter intentFilter, int userId);

    /**
     * Returns the icon Uri of the shortcut, and grants Uri read permission to the caller.
     */
    public abstract String getShortcutIconUri(int launcherUserId, @NonNull String launcherPackage,
            @NonNull String packageName, @NonNull String shortcutId, int userId);
}
+12 −0
Original line number Diff line number Diff line
@@ -818,6 +818,18 @@ public class LauncherAppsService extends SystemService {
                    callingPackage, packageName, id, targetUserId);
        }

        @Override
        public String getShortcutIconUri(String callingPackage, String packageName,
                String shortcutId, int userId) {
            ensureShortcutPermission(callingPackage);
            if (!canAccessProfile(userId, "Cannot access shortcuts")) {
                return null;
            }

            return mShortcutServiceInternal.getShortcutIconUri(getCallingUserId(), callingPackage,
                    packageName, shortcutId, userId);
        }

        @Override
        public boolean hasShortcutHostPermission(String callingPackage) {
            verifyCallingPackage(callingPackage);
Loading