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

Commit d1952df3 authored by Anna Zappone's avatar Anna Zappone Committed by Android (Google) Code Review
Browse files

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

parents ede93e77 cdc15d70
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();
    }