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

Commit c218e77a authored by Anna Zappone's avatar Anna Zappone Committed by Automerger Merge Worker
Browse files

Merge "Prevent any SecurityExceptions on Uri resolution" into sc-dev am: d1952df3

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15262570

Change-Id: I10a873ffebdce88edc93832dbbf302ad21fbc39c
parents 7a68c409 d1952df3
Loading
Loading
Loading
Loading
+50 −4
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.ImageDecoder;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.graphics.text.LineBreaker;
@@ -59,6 +60,7 @@ import android.text.TextUtils;
import android.util.IconDrawableFactory;
import android.util.Log;
import android.util.Pair;
import android.util.Size;
import android.util.SizeF;
import android.util.TypedValue;
import android.view.Gravity;
@@ -79,6 +81,7 @@ import com.android.systemui.people.widget.LaunchConversationActivity;
import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
import com.android.systemui.people.widget.PeopleTileKey;

import java.io.IOException;
import java.text.NumberFormat;
import java.time.Duration;
import java.util.ArrayList;
@@ -679,15 +682,24 @@ public class PeopleTileViewHelper {
        RemoteViews views = setViewForContentLayout(new RemoteViews(mContext.getPackageName(),
                getLayoutForNotificationContent()));
        CharSequence sender = mTile.getNotificationSender();
        Uri image = mTile.getNotificationDataUri();
        if (image != null) {
            // TODO: Use NotificationInlineImageCache
            views.setImageViewUri(R.id.image, image);
        Uri imageUri = mTile.getNotificationDataUri();
        if (imageUri != null) {
            String newImageDescription = mContext.getString(
                    R.string.new_notification_image_content_description, mTile.getUserName());
            views.setContentDescription(R.id.image, newImageDescription);
            views.setViewVisibility(R.id.image, View.VISIBLE);
            views.setViewVisibility(R.id.text_content, View.GONE);
            try {
                Drawable drawable = resolveImage(imageUri, mContext);
                Bitmap bitmap = convertDrawableToBitmap(drawable);
                views.setImageViewBitmap(R.id.image, bitmap);
            } catch (IOException e) {
                Log.e(TAG, "Could not decode image: " + e);
                // If we couldn't load the image, show text that we have a new image.
                views.setTextViewText(R.id.text_content, newImageDescription);
                views.setViewVisibility(R.id.text_content, View.VISIBLE);
                views.setViewVisibility(R.id.image, View.GONE);
            }
        } else {
            setMaxLines(views, !TextUtils.isEmpty(sender));
            CharSequence content = mTile.getNotificationContent();
@@ -722,6 +734,40 @@ public class PeopleTileViewHelper {
        return views;
    }

    private Drawable resolveImage(Uri uri, Context context) throws IOException {
        final ImageDecoder.Source source =
                ImageDecoder.createSource(context.getContentResolver(), uri);
        final Drawable drawable =
                ImageDecoder.decodeDrawable(source, (decoder, info, s) -> {
                    onHeaderDecoded(decoder, info, s);
                });
        return drawable;
    }

    private static int getPowerOfTwoForSampleRatio(double ratio) {
        final int k = Integer.highestOneBit((int) Math.floor(ratio));
        return Math.max(1, k);
    }

    private void onHeaderDecoded(ImageDecoder decoder, ImageDecoder.ImageInfo info,
            ImageDecoder.Source source) {
        int widthInPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mWidth,
                mContext.getResources().getDisplayMetrics());
        int heightInPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mHeight,
                mContext.getResources().getDisplayMetrics());
        int maxIconSizeInPx = Math.max(widthInPx, heightInPx);
        int minDimen = (int) (1.5 * Math.min(widthInPx, heightInPx));
        if (minDimen < maxIconSizeInPx) {
            maxIconSizeInPx = minDimen;
        }
        final Size size = info.getSize();
        final int originalSize = Math.max(size.getHeight(), size.getWidth());
        final double ratio = (originalSize > maxIconSizeInPx)
                ? originalSize * 1f / maxIconSizeInPx
                : 1.0;
        decoder.setTargetSampleSize(getPowerOfTwoForSampleRatio(ratio));
    }

    private void setContentDescriptionForNotificationTextContent(RemoteViews views,
            CharSequence content, CharSequence sender) {
        String newTextDescriptionWithNotificationContent = mContext.getString(
+11 −6
Original line number Diff line number Diff line
@@ -375,7 +375,7 @@ public class PeopleSpaceWidgetManager {
                widgetSp.getInt(USER_ID, INVALID_USER_ID),
                widgetSp.getString(PACKAGE_NAME, EMPTY_STRING));

        return getTileFromPersistentStorage(key, appWidgetId);
        return getTileFromPersistentStorage(key, appWidgetId, /* supplementFromStorage= */ true);
    }

    /**
@@ -383,7 +383,8 @@ public class PeopleSpaceWidgetManager {
     * If a {@link PeopleTileKey} is not provided, fetch one from {@link SharedPreferences}.
     */
    @Nullable
    public PeopleSpaceTile getTileFromPersistentStorage(PeopleTileKey key, int appWidgetId) throws
    public PeopleSpaceTile getTileFromPersistentStorage(PeopleTileKey key, int appWidgetId,
            boolean supplementFromStorage) throws
            PackageManager.NameNotFoundException {
        if (!PeopleTileKey.isValid(key)) {
            Log.e(TAG, "PeopleTileKey invalid: " + key.toString());
@@ -412,7 +413,8 @@ public class PeopleSpaceWidgetManager {

            // Supplement with our storage.
            String contactUri = mSharedPrefs.getString(String.valueOf(appWidgetId), null);
            if (contactUri != null && storedTile.build().getContactUri() == null) {
            if (supplementFromStorage && contactUri != null
                    && storedTile.build().getContactUri() == null) {
                if (DEBUG) Log.d(TAG, "Restore contact uri from storage: " + contactUri);
                storedTile.setContactUri(Uri.parse(contactUri));
            }
@@ -811,7 +813,8 @@ public class PeopleSpaceWidgetManager {
        if (DEBUG) Log.d(TAG, "addNewWidget called with key for appWidgetId: " + appWidgetId);
        PeopleSpaceTile tile = null;
        try {
            tile = getTileFromPersistentStorage(key, appWidgetId);
            tile = getTileFromPersistentStorage(key, appWidgetId,  /* supplementFromStorage= */
                    false);
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "Cannot add widget since app was uninstalled");
            return;
@@ -850,7 +853,9 @@ public class PeopleSpaceWidgetManager {
        } catch (Exception e) {
            Log.w(TAG, "Exception caching shortcut:" + e);
        }
        updateAppWidgetOptionsAndView(appWidgetId, tile);
        PeopleSpaceTile finalTile = tile;
        mBgExecutor.execute(
                () -> updateAppWidgetOptionsAndView(appWidgetId, finalTile));
    }

    /** Registers a conversation listener for {@code appWidgetId} if not already registered. */
+4 −2
Original line number Diff line number Diff line
@@ -1125,7 +1125,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
                new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A));
        when(mIPeopleManager.getConversation(TEST_PACKAGE_A, 0, SHORTCUT_ID)).thenReturn(channel);
        PeopleTileKey key = new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A);
        PeopleSpaceTile tile = mManager.getTileFromPersistentStorage(key, WIDGET_ID_WITH_SHORTCUT);
        PeopleSpaceTile tile = mManager
                .getTileFromPersistentStorage(key, WIDGET_ID_WITH_SHORTCUT, true);
        assertThat(tile.getId()).isEqualTo(key.getShortcutId());
    }

@@ -1133,7 +1134,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
    public void testGetPeopleTileFromPersistentStorageNoConversation() throws Exception {
        when(mIPeopleManager.getConversation(TEST_PACKAGE_A, 0, SHORTCUT_ID)).thenReturn(null);
        PeopleTileKey key = new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A);
        PeopleSpaceTile tile = mManager.getTileFromPersistentStorage(key, WIDGET_ID_WITH_SHORTCUT);
        PeopleSpaceTile tile = mManager
                .getTileFromPersistentStorage(key, WIDGET_ID_WITH_SHORTCUT, false);
        assertThat(tile).isNull();
    }