Loading packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java +50 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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( Loading packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java +11 −6 Original line number Diff line number Diff line Loading @@ -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); } /** Loading @@ -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()); Loading Loading @@ -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)); } Loading Loading @@ -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; Loading Loading @@ -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. */ Loading packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java +4 −2 Original line number Diff line number Diff line Loading @@ -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()); } Loading @@ -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(); } Loading Loading
packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java +50 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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( Loading
packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java +11 −6 Original line number Diff line number Diff line Loading @@ -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); } /** Loading @@ -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()); Loading Loading @@ -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)); } Loading Loading @@ -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; Loading Loading @@ -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. */ Loading
packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java +4 −2 Original line number Diff line number Diff line Loading @@ -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()); } Loading @@ -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(); } Loading