Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java +14 −1 Original line number Diff line number Diff line Loading @@ -443,6 +443,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder CancellationSignal cancellationSignal = new CancellationSignal(); cancellationSignal.setOnCancelListener( () -> runningInflations.values().forEach(CancellationSignal::cancel)); return cancellationSignal; } Loading Loading @@ -783,6 +784,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder public static class AsyncInflationTask extends AsyncTask<Void, Void, InflationProgress> implements InflationCallback, InflationTask { private static final long IMG_PRELOAD_TIMEOUT_MS = 1000L; private final NotificationEntry mEntry; private final Context mContext; private final boolean mInflateSynchronously; Loading Loading @@ -876,7 +878,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder recoveredBuilder, mIsLowPriority, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight, packageContext); InflatedSmartReplyState previousSmartReplyState = mRow.getExistingSmartReplyState(); return inflateSmartReplyViews( InflationProgress result = inflateSmartReplyViews( inflationProgress, mReInflateFlags, mEntry, Loading @@ -884,6 +886,11 @@ public class NotificationContentInflater implements NotificationRowContentBinder packageContext, previousSmartReplyState, mSmartRepliesInflater); // wait for image resolver to finish preloading mRow.getImageResolver().waitForPreloadedImages(IMG_PRELOAD_TIMEOUT_MS); return result; } catch (Exception e) { mError = e; return null; Loading Loading @@ -918,6 +925,9 @@ public class NotificationContentInflater implements NotificationRowContentBinder mCallback.handleInflationException(mRow.getEntry(), new InflationException("Couldn't inflate contentViews" + e)); } // Cancel any image loading tasks, not useful any more mRow.getImageResolver().cancelRunningTasks(); } @Override Loading @@ -944,6 +954,9 @@ public class NotificationContentInflater implements NotificationRowContentBinder // Notify the resolver that the inflation task has finished, // try to purge unnecessary cached entries. mRow.getImageResolver().purgeCache(); // Cancel any image loading tasks that have not completed at this point mRow.getImageResolver().cancelRunningTasks(); } private static class RtlEnabledContext extends ContextWrapper { Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java +17 −4 Original line number Diff line number Diff line Loading @@ -22,8 +22,11 @@ import android.os.AsyncTask; import android.util.Log; import java.util.Set; import java.util.concurrent.CancellationException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * A cache for inline images of image messages. Loading Loading @@ -56,12 +59,13 @@ public class NotificationInlineImageCache implements NotificationInlineImageReso } @Override public Drawable get(Uri uri) { public Drawable get(Uri uri, long timeoutMs) { Drawable result = null; try { result = mCache.get(uri).get(); } catch (InterruptedException | ExecutionException ex) { Log.d(TAG, "get: Failed get image from " + uri); result = mCache.get(uri).get(timeoutMs, TimeUnit.MILLISECONDS); } catch (InterruptedException | ExecutionException | TimeoutException | CancellationException ex) { Log.d(TAG, "get: Failed get image from " + uri + " " + ex); } return result; } Loading @@ -72,6 +76,15 @@ public class NotificationInlineImageCache implements NotificationInlineImageReso mCache.entrySet().removeIf(entry -> !wantedSet.contains(entry.getKey())); } @Override public void cancelRunningTasks() { mCache.forEach((key, value) -> { if (value.getStatus() != AsyncTask.Status.FINISHED) { value.cancel(true); } }); } private static class PreloadImageTask extends AsyncTask<Uri, Void, Drawable> { private final NotificationInlineImageResolver mResolver; Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java +45 −4 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.Parcelable; import android.os.SystemClock; import android.util.Log; import com.android.internal.R; Loading @@ -45,6 +46,9 @@ import java.util.Set; public class NotificationInlineImageResolver implements ImageResolver { private static final String TAG = NotificationInlineImageResolver.class.getSimpleName(); // Timeout for loading images from ImageCache when calling from UI thread private static final long MAX_UI_THREAD_TIMEOUT_MS = 100L; private final Context mContext; private final ImageCache mImageCache; private Set<Uri> mWantedUriSet; Loading Loading @@ -123,17 +127,25 @@ public class NotificationInlineImageResolver implements ImageResolver { return null; } /** * Loads an image from the Uri. * This method is synchronous and is usually called from the Main thread. * It will time-out after MAX_UI_THREAD_TIMEOUT_MS. * * @param uri Uri of the target image. * @return drawable of the image, null if loading failed/timeout */ @Override public Drawable loadImage(Uri uri) { return hasCache() ? loadImageFromCache(uri) : resolveImage(uri); return hasCache() ? loadImageFromCache(uri, MAX_UI_THREAD_TIMEOUT_MS) : resolveImage(uri); } private Drawable loadImageFromCache(Uri uri) { private Drawable loadImageFromCache(Uri uri, long timeoutMs) { // if the uri isn't currently cached, try caching it first if (!mImageCache.hasEntry(uri)) { mImageCache.preload((uri)); } return mImageCache.get(uri); return mImageCache.get(uri, timeoutMs); } /** Loading Loading @@ -207,6 +219,30 @@ public class NotificationInlineImageResolver implements ImageResolver { return mWantedUriSet; } /** * Wait for a maximum timeout for images to finish preloading * @param timeoutMs total timeout time */ void waitForPreloadedImages(long timeoutMs) { if (!hasCache()) { return; } Set<Uri> preloadedUris = getWantedUriSet(); if (preloadedUris != null) { // Decrement remaining timeout after each image check long endTimeMs = SystemClock.elapsedRealtime() + timeoutMs; preloadedUris.forEach( uri -> loadImageFromCache(uri, endTimeMs - SystemClock.elapsedRealtime())); } } void cancelRunningTasks() { if (!hasCache()) { return; } mImageCache.cancelRunningTasks(); } /** * A interface for internal cache implementation of this resolver. */ Loading @@ -216,7 +252,7 @@ public class NotificationInlineImageResolver implements ImageResolver { * @param uri The uri of the image. * @return Drawable of the image. */ Drawable get(Uri uri); Drawable get(Uri uri, long timeoutMs); /** * Set the image resolver that actually resolves image from specified uri. Loading @@ -241,6 +277,11 @@ public class NotificationInlineImageResolver implements ImageResolver { * Purge unnecessary entries in the cache. */ void purge(); /** * Cancel all unfinished image loading tasks */ void cancelRunningTasks(); } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java +14 −1 Original line number Diff line number Diff line Loading @@ -443,6 +443,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder CancellationSignal cancellationSignal = new CancellationSignal(); cancellationSignal.setOnCancelListener( () -> runningInflations.values().forEach(CancellationSignal::cancel)); return cancellationSignal; } Loading Loading @@ -783,6 +784,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder public static class AsyncInflationTask extends AsyncTask<Void, Void, InflationProgress> implements InflationCallback, InflationTask { private static final long IMG_PRELOAD_TIMEOUT_MS = 1000L; private final NotificationEntry mEntry; private final Context mContext; private final boolean mInflateSynchronously; Loading Loading @@ -876,7 +878,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder recoveredBuilder, mIsLowPriority, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight, packageContext); InflatedSmartReplyState previousSmartReplyState = mRow.getExistingSmartReplyState(); return inflateSmartReplyViews( InflationProgress result = inflateSmartReplyViews( inflationProgress, mReInflateFlags, mEntry, Loading @@ -884,6 +886,11 @@ public class NotificationContentInflater implements NotificationRowContentBinder packageContext, previousSmartReplyState, mSmartRepliesInflater); // wait for image resolver to finish preloading mRow.getImageResolver().waitForPreloadedImages(IMG_PRELOAD_TIMEOUT_MS); return result; } catch (Exception e) { mError = e; return null; Loading Loading @@ -918,6 +925,9 @@ public class NotificationContentInflater implements NotificationRowContentBinder mCallback.handleInflationException(mRow.getEntry(), new InflationException("Couldn't inflate contentViews" + e)); } // Cancel any image loading tasks, not useful any more mRow.getImageResolver().cancelRunningTasks(); } @Override Loading @@ -944,6 +954,9 @@ public class NotificationContentInflater implements NotificationRowContentBinder // Notify the resolver that the inflation task has finished, // try to purge unnecessary cached entries. mRow.getImageResolver().purgeCache(); // Cancel any image loading tasks that have not completed at this point mRow.getImageResolver().cancelRunningTasks(); } private static class RtlEnabledContext extends ContextWrapper { Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java +17 −4 Original line number Diff line number Diff line Loading @@ -22,8 +22,11 @@ import android.os.AsyncTask; import android.util.Log; import java.util.Set; import java.util.concurrent.CancellationException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * A cache for inline images of image messages. Loading Loading @@ -56,12 +59,13 @@ public class NotificationInlineImageCache implements NotificationInlineImageReso } @Override public Drawable get(Uri uri) { public Drawable get(Uri uri, long timeoutMs) { Drawable result = null; try { result = mCache.get(uri).get(); } catch (InterruptedException | ExecutionException ex) { Log.d(TAG, "get: Failed get image from " + uri); result = mCache.get(uri).get(timeoutMs, TimeUnit.MILLISECONDS); } catch (InterruptedException | ExecutionException | TimeoutException | CancellationException ex) { Log.d(TAG, "get: Failed get image from " + uri + " " + ex); } return result; } Loading @@ -72,6 +76,15 @@ public class NotificationInlineImageCache implements NotificationInlineImageReso mCache.entrySet().removeIf(entry -> !wantedSet.contains(entry.getKey())); } @Override public void cancelRunningTasks() { mCache.forEach((key, value) -> { if (value.getStatus() != AsyncTask.Status.FINISHED) { value.cancel(true); } }); } private static class PreloadImageTask extends AsyncTask<Uri, Void, Drawable> { private final NotificationInlineImageResolver mResolver; Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java +45 −4 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.Parcelable; import android.os.SystemClock; import android.util.Log; import com.android.internal.R; Loading @@ -45,6 +46,9 @@ import java.util.Set; public class NotificationInlineImageResolver implements ImageResolver { private static final String TAG = NotificationInlineImageResolver.class.getSimpleName(); // Timeout for loading images from ImageCache when calling from UI thread private static final long MAX_UI_THREAD_TIMEOUT_MS = 100L; private final Context mContext; private final ImageCache mImageCache; private Set<Uri> mWantedUriSet; Loading Loading @@ -123,17 +127,25 @@ public class NotificationInlineImageResolver implements ImageResolver { return null; } /** * Loads an image from the Uri. * This method is synchronous and is usually called from the Main thread. * It will time-out after MAX_UI_THREAD_TIMEOUT_MS. * * @param uri Uri of the target image. * @return drawable of the image, null if loading failed/timeout */ @Override public Drawable loadImage(Uri uri) { return hasCache() ? loadImageFromCache(uri) : resolveImage(uri); return hasCache() ? loadImageFromCache(uri, MAX_UI_THREAD_TIMEOUT_MS) : resolveImage(uri); } private Drawable loadImageFromCache(Uri uri) { private Drawable loadImageFromCache(Uri uri, long timeoutMs) { // if the uri isn't currently cached, try caching it first if (!mImageCache.hasEntry(uri)) { mImageCache.preload((uri)); } return mImageCache.get(uri); return mImageCache.get(uri, timeoutMs); } /** Loading Loading @@ -207,6 +219,30 @@ public class NotificationInlineImageResolver implements ImageResolver { return mWantedUriSet; } /** * Wait for a maximum timeout for images to finish preloading * @param timeoutMs total timeout time */ void waitForPreloadedImages(long timeoutMs) { if (!hasCache()) { return; } Set<Uri> preloadedUris = getWantedUriSet(); if (preloadedUris != null) { // Decrement remaining timeout after each image check long endTimeMs = SystemClock.elapsedRealtime() + timeoutMs; preloadedUris.forEach( uri -> loadImageFromCache(uri, endTimeMs - SystemClock.elapsedRealtime())); } } void cancelRunningTasks() { if (!hasCache()) { return; } mImageCache.cancelRunningTasks(); } /** * A interface for internal cache implementation of this resolver. */ Loading @@ -216,7 +252,7 @@ public class NotificationInlineImageResolver implements ImageResolver { * @param uri The uri of the image. * @return Drawable of the image. */ Drawable get(Uri uri); Drawable get(Uri uri, long timeoutMs); /** * Set the image resolver that actually resolves image from specified uri. Loading @@ -241,6 +277,11 @@ public class NotificationInlineImageResolver implements ImageResolver { * Purge unnecessary entries in the cache. */ void purge(); /** * Cancel all unfinished image loading tasks */ void cancelRunningTasks(); } }