diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/DeleteImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/DeleteImageInBackgroundTask.java
new file mode 100644
index 0000000..8c48655
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/DeleteImageInBackgroundTask.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.screenshot;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.net.Uri;
+import android.os.AsyncTask;
+
+/**
+ * An AsyncTask that deletes an image from the media store in the background.
+ */
+class DeleteImageInBackgroundTask extends AsyncTask<Uri, Void, Void> {
+    private Context mContext;
+
+    DeleteImageInBackgroundTask(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    protected Void doInBackground(Uri... params) {
+        if (params.length != 1) return null;
+
+        Uri screenshotUri = params[0];
+        ContentResolver resolver = mContext.getContentResolver();
+        resolver.delete(screenshotUri, null, null);
+        return null;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 7dc3236..7963203 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -32,52 +32,31 @@
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
-import android.app.ActivityTaskManager;
 import android.app.Notification;
-import android.app.Notification.BigPictureStyle;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
-import android.content.ClipData;
-import android.content.ClipDescription;
 import android.content.ComponentName;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Picture;
 import android.graphics.PixelFormat;
 import android.graphics.PointF;
 import android.graphics.Rect;
-import android.media.ExifInterface;
 import android.media.MediaActionSound;
 import android.net.Uri;
 import android.os.AsyncTask;
-import android.os.Build;
-import android.os.Environment;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.ParcelFileDescriptor;
 import android.os.PowerManager;
-import android.os.Process;
-import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.provider.DeviceConfig;
-import android.provider.MediaStore;
-import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.Slog;
@@ -93,32 +72,16 @@
 import android.widget.Toast;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
-import com.android.systemui.SystemUIFactory;
 import com.android.systemui.dagger.qualifiers.MainResources;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.util.NotificationChannels;
 
-import libcore.io.IoUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.time.Instant;
-import java.time.ZoneId;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
 import java.util.Collections;
-import java.util.Date;
 import java.util.List;
-import java.util.Objects;
 import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
@@ -140,7 +103,7 @@
     /**
      * POD used in the AsyncTask which saves an image in the background.
      */
-    private static class SaveImageInBackgroundData {
+    static class SaveImageInBackgroundData {
         public Context context;
         public Bitmap image;
         public Uri imageUri;
@@ -156,426 +119,12 @@
             imageUri = null;
             iconSize = 0;
         }
+
         void clearContext() {
             context = null;
         }
     }
 
-    /**
-     * An AsyncTask that saves an image to the media store in the background.
-     */
-    private static class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
-        private static final String TAG = "SaveImageInBackgroundTask";
-
-        private static final String SCREENSHOT_FILE_NAME_TEMPLATE = "Screenshot_%s.png";
-        private static final String SCREENSHOT_SHARE_SUBJECT_TEMPLATE = "Screenshot (%s)";
-
-        private final SaveImageInBackgroundData mParams;
-        private final NotificationManager mNotificationManager;
-        private final Notification.Builder mNotificationBuilder, mPublicNotificationBuilder;
-        private final String mImageFileName;
-        private final long mImageTime;
-        private final BigPictureStyle mNotificationStyle;
-        private final int mImageWidth;
-        private final int mImageHeight;
-        private final Handler mHandler;
-        private final ScreenshotNotificationSmartActionsProvider mSmartActionsProvider;
-
-        SaveImageInBackgroundTask(Context context, SaveImageInBackgroundData data,
-                NotificationManager nManager) {
-            Resources r = context.getResources();
-
-            // Prepare all the output metadata
-            mParams = data;
-            mImageTime = System.currentTimeMillis();
-            String imageDate = new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(mImageTime));
-            mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, imageDate);
-
-            // Initialize screenshot notification smart actions provider.
-            mHandler = new Handler();
-            mSmartActionsProvider =
-                SystemUIFactory.getInstance().createScreenshotNotificationSmartActionsProvider();
-
-            // Create the large notification icon
-            mImageWidth = data.image.getWidth();
-            mImageHeight = data.image.getHeight();
-            int iconSize = data.iconSize;
-            int previewWidth = data.previewWidth;
-            int previewHeight = data.previewheight;
-
-            Paint paint = new Paint();
-            ColorMatrix desat = new ColorMatrix();
-            desat.setSaturation(0.25f);
-            paint.setColorFilter(new ColorMatrixColorFilter(desat));
-            Matrix matrix = new Matrix();
-            int overlayColor = 0x40FFFFFF;
-
-            matrix.setTranslate((previewWidth - mImageWidth) / 2,
-                    (previewHeight - mImageHeight) / 2);
-            Bitmap picture = generateAdjustedHwBitmap(data.image, previewWidth, previewHeight,
-                    matrix, paint, overlayColor);
-
-            // Note, we can't use the preview for the small icon, since it is non-square
-            float scale = (float) iconSize / Math.min(mImageWidth, mImageHeight);
-            matrix.setScale(scale, scale);
-            matrix.postTranslate((iconSize - (scale * mImageWidth)) / 2,
-                    (iconSize - (scale * mImageHeight)) / 2);
-            Bitmap icon = generateAdjustedHwBitmap(data.image, iconSize, iconSize, matrix, paint,
-                    overlayColor);
-
-            mNotificationManager = nManager;
-            final long now = System.currentTimeMillis();
-
-            // Setup the notification
-            mNotificationStyle = new Notification.BigPictureStyle()
-                    .bigPicture(picture.createAshmemBitmap());
-
-            // The public notification will show similar info but with the actual screenshot omitted
-            mPublicNotificationBuilder =
-                    new Notification.Builder(context, NotificationChannels.SCREENSHOTS_HEADSUP)
-                            .setContentTitle(r.getString(R.string.screenshot_saving_title))
-                            .setSmallIcon(R.drawable.stat_notify_image)
-                            .setCategory(Notification.CATEGORY_PROGRESS)
-                            .setWhen(now)
-                            .setShowWhen(true)
-                            .setColor(r.getColor(
-                                    com.android.internal.R.color.system_notification_accent_color));
-            SystemUI.overrideNotificationAppName(context, mPublicNotificationBuilder, true);
-
-            mNotificationBuilder = new Notification.Builder(context,
-                    NotificationChannels.SCREENSHOTS_HEADSUP)
-                    .setContentTitle(r.getString(R.string.screenshot_saving_title))
-                    .setSmallIcon(R.drawable.stat_notify_image)
-                    .setWhen(now)
-                    .setShowWhen(true)
-                    .setColor(r.getColor(
-                            com.android.internal.R.color.system_notification_accent_color))
-                    .setStyle(mNotificationStyle)
-                    .setPublicVersion(mPublicNotificationBuilder.build());
-            mNotificationBuilder.setFlag(Notification.FLAG_NO_CLEAR, true);
-            SystemUI.overrideNotificationAppName(context, mNotificationBuilder, true);
-
-            mNotificationManager.notify(SystemMessage.NOTE_GLOBAL_SCREENSHOT,
-                    mNotificationBuilder.build());
-
-            /**
-             * NOTE: The following code prepares the notification builder for updating the
-             * notification after the screenshot has been written to disk.
-             */
-
-            // On the tablet, the large icon makes the notification appear as if it is clickable
-            // (and on small devices, the large icon is not shown) so defer showing the large icon
-            // until we compose the final post-save notification below.
-            mNotificationBuilder.setLargeIcon(icon.createAshmemBitmap());
-            // But we still don't set it for the expanded view, allowing the smallIcon to show here.
-            mNotificationStyle.bigLargeIcon((Bitmap) null);
-        }
-
-        private int getUserHandleOfForegroundApplication(Context context) {
-            // This logic matches
-            // com.android.systemui.statusbar.phone.PhoneStatusBarPolicy#updateManagedProfile
-            try {
-                return ActivityTaskManager.getService().getLastResumedActivityUserId();
-            } catch (RemoteException e) {
-                Slog.w(TAG, "getUserHandleOfForegroundApplication: ", e);
-                return context.getUserId();
-            }
-        }
-
-        private boolean isManagedProfile(Context context) {
-            UserManager manager = UserManager.get(context);
-            UserInfo info = manager.getUserInfo(getUserHandleOfForegroundApplication(context));
-            return info.isManagedProfile();
-        }
-
-        /**
-         * Generates a new hardware bitmap with specified values, copying the content from the
-         * passed in bitmap.
-         */
-        private Bitmap generateAdjustedHwBitmap(Bitmap bitmap, int width, int height, Matrix matrix,
-                Paint paint, int color) {
-            Picture picture = new Picture();
-            Canvas canvas = picture.beginRecording(width, height);
-            canvas.drawColor(color);
-            canvas.drawBitmap(bitmap, matrix, paint);
-            picture.endRecording();
-            return Bitmap.createBitmap(picture);
-        }
-
-        @Override
-        protected Void doInBackground(Void... paramsUnused) {
-            if (isCancelled()) {
-                return null;
-            }
-
-            // By default, AsyncTask sets the worker thread to have background thread priority,
-            // so bump it back up so that we save a little quicker.
-            Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
-
-            Context context = mParams.context;
-            Bitmap image = mParams.image;
-            boolean smartActionsEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
-                    SystemUiDeviceConfigFlags.ENABLE_SCREENSHOT_NOTIFICATION_SMART_ACTIONS, true);
-            CompletableFuture<List<Notification.Action>> smartActionsFuture = getSmartActionsFuture(
-                    context, image, mSmartActionsProvider, mHandler, smartActionsEnabled,
-                    isManagedProfile(context));
-
-            Resources r = context.getResources();
-
-            try {
-                // Save the screenshot to the MediaStore
-                final MediaStore.PendingParams params = new MediaStore.PendingParams(
-                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, mImageFileName, "image/png");
-                params.setRelativePath(Environment.DIRECTORY_PICTURES + File.separator
-                        + Environment.DIRECTORY_SCREENSHOTS);
-
-                final Uri uri = MediaStore.createPending(context, params);
-                final MediaStore.PendingSession session = MediaStore.openPending(context, uri);
-                try {
-                    // First, write the actual data for our screenshot
-                    try (OutputStream out = session.openOutputStream()) {
-                        if (!image.compress(Bitmap.CompressFormat.PNG, 100, out)) {
-                            throw new IOException("Failed to compress");
-                        }
-                    }
-
-                    // Next, write metadata to help index the screenshot
-                    try (ParcelFileDescriptor pfd = session.open()) {
-                        final ExifInterface exif = new ExifInterface(pfd.getFileDescriptor());
-
-                        exif.setAttribute(ExifInterface.TAG_SOFTWARE,
-                                "Android " + Build.DISPLAY);
-
-                        exif.setAttribute(ExifInterface.TAG_IMAGE_WIDTH,
-                                Integer.toString(image.getWidth()));
-                        exif.setAttribute(ExifInterface.TAG_IMAGE_LENGTH,
-                                Integer.toString(image.getHeight()));
-
-                        final ZonedDateTime time = ZonedDateTime.ofInstant(
-                                Instant.ofEpochMilli(mImageTime), ZoneId.systemDefault());
-                        exif.setAttribute(ExifInterface.TAG_DATETIME_ORIGINAL,
-                                DateTimeFormatter.ofPattern("yyyy:MM:dd HH:mm:ss").format(time));
-                        exif.setAttribute(ExifInterface.TAG_SUBSEC_TIME_ORIGINAL,
-                                DateTimeFormatter.ofPattern("SSS").format(time));
-
-                        if (Objects.equals(time.getOffset(), ZoneOffset.UTC)) {
-                            exif.setAttribute(ExifInterface.TAG_OFFSET_TIME_ORIGINAL, "+00:00");
-                        } else {
-                            exif.setAttribute(ExifInterface.TAG_OFFSET_TIME_ORIGINAL,
-                                    DateTimeFormatter.ofPattern("XXX").format(time));
-                        }
-
-                        exif.saveAttributes();
-                    }
-                    session.publish();
-                } catch (Exception e) {
-                    session.abandon();
-                    throw e;
-                } finally {
-                    IoUtils.closeQuietly(session);
-                }
-
-                // Note: Both the share and edit actions are proxied through ActionProxyReceiver in
-                // order to do some common work like dismissing the keyguard and sending
-                // closeSystemWindows
-
-                // Create a share intent, this will always go through the chooser activity first
-                // which should not trigger auto-enter PiP
-                String subjectDate = DateFormat.getDateTimeInstance().format(new Date(mImageTime));
-                String subject = String.format(SCREENSHOT_SHARE_SUBJECT_TEMPLATE, subjectDate);
-                Intent sharingIntent = new Intent(Intent.ACTION_SEND);
-                sharingIntent.setType("image/png");
-                sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
-                // Include URI in ClipData also, so that grantPermission picks it up.
-                // We don't use setData here because some apps interpret this as "to:".
-                ClipData clipdata = new ClipData(new ClipDescription("content",
-                        new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN}),
-                        new ClipData.Item(uri));
-                sharingIntent.setClipData(clipdata);
-                sharingIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
-                sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-
-                // Make sure pending intents for the system user are still unique across users
-                // by setting the (otherwise unused) request code to the current user id.
-                int requestCode = context.getUserId();
-
-                PendingIntent chooserAction = PendingIntent.getBroadcast(context, requestCode,
-                        new Intent(context, GlobalScreenshot.TargetChosenReceiver.class),
-                        PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
-                Intent sharingChooserIntent = Intent.createChooser(sharingIntent, null,
-                        chooserAction.getIntentSender())
-                        .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK)
-                        .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-
-                // Create a share action for the notification
-                PendingIntent shareAction = PendingIntent.getBroadcastAsUser(context, requestCode,
-                        new Intent(context, GlobalScreenshot.ActionProxyReceiver.class)
-                                .putExtra(EXTRA_ACTION_INTENT, sharingChooserIntent)
-                                .putExtra(EXTRA_DISALLOW_ENTER_PIP, true)
-                                .setAction(Intent.ACTION_SEND),
-                        PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.SYSTEM);
-                Notification.Action.Builder shareActionBuilder = new Notification.Action.Builder(
-                        R.drawable.ic_screenshot_share,
-                        r.getString(com.android.internal.R.string.share), shareAction);
-                mNotificationBuilder.addAction(shareActionBuilder.build());
-
-                // Create an edit intent, if a specific package is provided as the editor, then
-                // launch that directly
-                String editorPackage = context.getString(R.string.config_screenshotEditor);
-                Intent editIntent = new Intent(Intent.ACTION_EDIT);
-                if (!TextUtils.isEmpty(editorPackage)) {
-                    editIntent.setComponent(ComponentName.unflattenFromString(editorPackage));
-                }
-                editIntent.setType("image/png");
-                editIntent.setData(uri);
-                editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-                editIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
-
-                // Create a edit action
-                PendingIntent editAction = PendingIntent.getBroadcastAsUser(context, requestCode,
-                        new Intent(context, GlobalScreenshot.ActionProxyReceiver.class)
-                                .putExtra(EXTRA_ACTION_INTENT, editIntent)
-                                .putExtra(EXTRA_CANCEL_NOTIFICATION,
-                                        editIntent.getComponent() != null)
-                                .setAction(Intent.ACTION_EDIT),
-                        PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.SYSTEM);
-                Notification.Action.Builder editActionBuilder = new Notification.Action.Builder(
-                        R.drawable.ic_screenshot_edit,
-                        r.getString(com.android.internal.R.string.screenshot_edit), editAction);
-                mNotificationBuilder.addAction(editActionBuilder.build());
-                if (editAction != null && mParams.onEditReady != null) {
-                    mParams.onEditReady.apply(editAction);
-                }
-
-                // Create a delete action for the notification
-                PendingIntent deleteAction = PendingIntent.getBroadcast(context, requestCode,
-                        new Intent(context, GlobalScreenshot.DeleteScreenshotReceiver.class)
-                                .putExtra(GlobalScreenshot.SCREENSHOT_URI_ID, uri.toString()),
-                        PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
-                Notification.Action.Builder deleteActionBuilder = new Notification.Action.Builder(
-                        R.drawable.ic_screenshot_delete,
-                        r.getString(com.android.internal.R.string.delete), deleteAction);
-                mNotificationBuilder.addAction(deleteActionBuilder.build());
-
-                mParams.imageUri = uri;
-                mParams.image = null;
-                mParams.errorMsgResId = 0;
-
-                if (smartActionsEnabled) {
-                    int timeoutMs = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
-                            SystemUiDeviceConfigFlags
-                                    .SCREENSHOT_NOTIFICATION_SMART_ACTIONS_TIMEOUT_MS,
-                            1000);
-                    List<Notification.Action> smartActions = getSmartActions(smartActionsFuture,
-                            timeoutMs);
-                    for (Notification.Action action : smartActions) {
-                        mNotificationBuilder.addAction(action);
-                    }
-                }
-            } catch (Exception e) {
-                // IOException/UnsupportedOperationException may be thrown if external storage is
-                // not mounted
-                Slog.e(TAG, "unable to save screenshot", e);
-                mParams.clearImage();
-                mParams.errorMsgResId = R.string.screenshot_failed_to_save_text;
-            }
-
-            // Recycle the bitmap data
-            if (image != null) {
-                image.recycle();
-            }
-
-            return null;
-        }
-
-        @Override
-        protected void onPostExecute(Void params) {
-            if (mParams.errorMsgResId != 0) {
-                // Show a message that we've failed to save the image to disk
-                GlobalScreenshot.notifyScreenshotError(mParams.context, mNotificationManager,
-                        mParams.errorMsgResId);
-            } else {
-                if (mParams.onEditReady != null) {
-                    // Cancel the "saving screenshot" notification
-                    mNotificationManager.cancel(SystemMessage.NOTE_GLOBAL_SCREENSHOT);
-                } else {
-                    // Show the final notification to indicate screenshot saved
-                    Context context = mParams.context;
-                    Resources r = context.getResources();
-
-                    // Create the intent to show the screenshot in gallery
-                    Intent launchIntent = new Intent(Intent.ACTION_VIEW);
-                    launchIntent.setDataAndType(mParams.imageUri, "image/png");
-                    launchIntent.setFlags(
-                            Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
-
-                    final long now = System.currentTimeMillis();
-
-                    // Update the text and the icon for the existing notification
-                    mPublicNotificationBuilder
-                            .setContentTitle(r.getString(R.string.screenshot_saved_title))
-                            .setContentText(r.getString(R.string.screenshot_saved_text))
-                            .setContentIntent(
-                                    PendingIntent.getActivity(mParams.context, 0, launchIntent, 0))
-                            .setWhen(now)
-                            .setAutoCancel(true)
-                            .setColor(context.getColor(
-                                    com.android.internal.R.color.system_notification_accent_color));
-                    mNotificationBuilder
-                            .setContentTitle(r.getString(R.string.screenshot_saved_title))
-                            .setContentText(r.getString(R.string.screenshot_saved_text))
-                            .setContentIntent(PendingIntent.getActivity(mParams.context, 0,
-                                    launchIntent, 0))
-                            .setWhen(now)
-                            .setAutoCancel(true)
-                            .setColor(context.getColor(
-                                    com.android.internal.R.color.system_notification_accent_color))
-                            .setPublicVersion(mPublicNotificationBuilder.build())
-                            .setFlag(Notification.FLAG_NO_CLEAR, false);
-
-                    mNotificationManager.notify(SystemMessage.NOTE_GLOBAL_SCREENSHOT,
-                            mNotificationBuilder.build());
-                }
-            }
-            mParams.finisher.run();
-            mParams.clearContext();
-        }
-
-        @Override
-        protected void onCancelled(Void params) {
-            // If we are cancelled while the task is running in the background, we may get null
-            // params. The finisher is expected to always be called back, so just use the baked-in
-            // params from the ctor in any case.
-            mParams.finisher.run();
-            mParams.clearImage();
-            mParams.clearContext();
-
-            // Cancel the posted notification
-            mNotificationManager.cancel(SystemMessage.NOTE_GLOBAL_SCREENSHOT);
-        }
-    }
-
-    /**
-     * An AsyncTask that deletes an image from the media store in the background.
-     */
-    private static class DeleteImageInBackgroundTask extends AsyncTask<Uri, Void, Void> {
-        private Context mContext;
-
-        DeleteImageInBackgroundTask(Context context) {
-            mContext = context;
-        }
-
-        @Override
-        protected Void doInBackground(Uri... params) {
-            if (params.length != 1) return null;
-
-            Uri screenshotUri = params[0];
-            ContentResolver resolver = mContext.getContentResolver();
-            resolver.delete(screenshotUri, null, null);
-            return null;
-        }
-    }
-
     static final String SCREENSHOT_URI_ID = "android:screenshot_uri_id";
     static final String EXTRA_ACTION_INTENT = "android:screenshot_action_intent";
     static final String EXTRA_CANCEL_NOTIFICATION = "android:screenshot_cancel_notification";
@@ -639,7 +188,6 @@
         }
     };
 
-
     /**
      * @param context everything needs a context :(
      */
@@ -670,25 +218,25 @@
                 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0, 0,
                 WindowManager.LayoutParams.TYPE_SCREENSHOT,
                 WindowManager.LayoutParams.FLAG_FULLSCREEN
-                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                    | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
+                        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
                 PixelFormat.TRANSLUCENT);
         mWindowLayoutParams.setTitle("ScreenshotAnimation");
         mWindowLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
         mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
         mNotificationManager =
-            (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
+                (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
         mDisplay = mWindowManager.getDefaultDisplay();
         mDisplayMetrics = new DisplayMetrics();
         mDisplay.getRealMetrics(mDisplayMetrics);
 
         // Get the various target sizes
         mNotificationIconSize =
-            resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_height);
+                resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_height);
 
         // Scale has to account for both sides of the bg
         mBgPadding = (float) resources.getDimensionPixelSize(R.dimen.global_screenshot_bg_padding);
-        mBgPaddingScale = mBgPadding /  mDisplayMetrics.widthPixels;
+        mBgPaddingScale = mBgPadding / mDisplayMetrics.widthPixels;
 
         // determine the optimal preview size
         int panelWidth = 0;
@@ -916,6 +464,7 @@
             mScreenshotAnimation.start();
         });
     }
+
     private ValueAnimator createScreenshotDropInAnimation() {
         final float flashPeakDurationPct = ((float) (SCREENSHOT_FLASH_TO_PEAK_DURATION)
                 / SCREENSHOT_DROP_IN_DURATION);
@@ -965,6 +514,7 @@
                 mScreenshotFlash.setAlpha(0f);
                 mScreenshotFlash.setVisibility(View.VISIBLE);
             }
+
             @Override
             public void onAnimationEnd(android.animation.Animator animation) {
                 mScreenshotFlash.setVisibility(View.GONE);
@@ -975,7 +525,7 @@
             public void onAnimationUpdate(ValueAnimator animation) {
                 float t = (Float) animation.getAnimatedValue();
                 float scaleT = (SCREENSHOT_SCALE + mBgPaddingScale)
-                    - scaleInterpolator.getInterpolation(t)
+                        - scaleInterpolator.getInterpolation(t)
                         * (SCREENSHOT_SCALE - SCREENSHOT_DROP_IN_MIN_SCALE);
                 mBackgroundView.setAlpha(scaleInterpolator.getInterpolation(t) * BACKGROUND_ALPHA);
                 mScreenshotView.setAlpha(t);
@@ -986,6 +536,7 @@
         });
         return anim;
     }
+
     private ValueAnimator createScreenshotDropOutAnimation(int w, int h, boolean statusBarVisible,
             boolean navBarVisible) {
         ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
@@ -1007,7 +558,8 @@
                 public void onAnimationUpdate(ValueAnimator animation) {
                     float t = (Float) animation.getAnimatedValue();
                     float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale)
-                            - t * (SCREENSHOT_DROP_IN_MIN_SCALE - SCREENSHOT_FAST_DROP_OUT_MIN_SCALE);
+                            - t * (SCREENSHOT_DROP_IN_MIN_SCALE
+                            - SCREENSHOT_FAST_DROP_OUT_MIN_SCALE);
                     mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
                     mScreenshotView.setAlpha(1f - t);
                     mScreenshotView.setScaleX(scaleT);
@@ -1034,8 +586,10 @@
             float halfScreenHeight = (h - 2f * mBgPadding) / 2f;
             final float offsetPct = SCREENSHOT_DROP_OUT_MIN_SCALE_OFFSET;
             final PointF finalPos = new PointF(
-                -halfScreenWidth + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenWidth,
-                -halfScreenHeight + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenHeight);
+                    -halfScreenWidth
+                            + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenWidth,
+                    -halfScreenHeight
+                            + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenHeight);
 
             // Animate the screenshot to the status bar
             anim.setDuration(SCREENSHOT_DROP_OUT_DURATION);
@@ -1044,7 +598,7 @@
                 public void onAnimationUpdate(ValueAnimator animation) {
                     float t = (Float) animation.getAnimatedValue();
                     float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale)
-                        - scaleInterpolator.getInterpolation(t)
+                            - scaleInterpolator.getInterpolation(t)
                             * (SCREENSHOT_DROP_IN_MIN_SCALE - SCREENSHOT_DROP_OUT_MIN_SCALE);
                     mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
                     mScreenshotView.setAlpha(1f - scaleInterpolator.getInterpolation(t));
@@ -1105,15 +659,15 @@
 
         // Repurpose the existing notification to notify the user of the error
         Notification.Builder b = new Notification.Builder(context, NotificationChannels.ALERTS)
-            .setTicker(r.getString(R.string.screenshot_failed_title))
-            .setContentTitle(r.getString(R.string.screenshot_failed_title))
-            .setContentText(errorMsg)
-            .setSmallIcon(R.drawable.stat_notify_image_error)
-            .setWhen(System.currentTimeMillis())
-            .setVisibility(Notification.VISIBILITY_PUBLIC) // ok to show outside lockscreen
-            .setCategory(Notification.CATEGORY_ERROR)
-            .setAutoCancel(true)
-            .setColor(context.getColor(
+                .setTicker(r.getString(R.string.screenshot_failed_title))
+                .setContentTitle(r.getString(R.string.screenshot_failed_title))
+                .setContentText(errorMsg)
+                .setSmallIcon(R.drawable.stat_notify_image_error)
+                .setWhen(System.currentTimeMillis())
+                .setVisibility(Notification.VISIBILITY_PUBLIC) // ok to show outside lockscreen
+                .setCategory(Notification.CATEGORY_ERROR)
+                .setAutoCancel(true)
+                .setColor(context.getColor(
                         com.android.internal.R.color.system_notification_accent_color));
         final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
new file mode 100644
index 0000000..083f971
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
@@ -0,0 +1,472 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.screenshot;
+
+import android.app.ActivityTaskManager;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Picture;
+import android.media.ExifInterface;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.DeviceConfig;
+import android.provider.MediaStore;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+import com.android.internal.messages.nano.SystemMessageProto;
+import com.android.systemui.R;
+import com.android.systemui.SystemUI;
+import com.android.systemui.SystemUIFactory;
+import com.android.systemui.util.NotificationChannels;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * An AsyncTask that saves an image to the media store in the background.
+ */
+class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
+    private static final String TAG = "SaveImageInBackgroundTask";
+
+    private static final String SCREENSHOT_FILE_NAME_TEMPLATE = "Screenshot_%s.png";
+    private static final String SCREENSHOT_SHARE_SUBJECT_TEMPLATE = "Screenshot (%s)";
+
+    private final GlobalScreenshot.SaveImageInBackgroundData mParams;
+    private final NotificationManager mNotificationManager;
+    private final Notification.Builder mNotificationBuilder, mPublicNotificationBuilder;
+    private final String mImageFileName;
+    private final long mImageTime;
+    private final Notification.BigPictureStyle mNotificationStyle;
+    private final int mImageWidth;
+    private final int mImageHeight;
+    private final Handler mHandler;
+    private final ScreenshotNotificationSmartActionsProvider mSmartActionsProvider;
+
+    SaveImageInBackgroundTask(Context context, GlobalScreenshot.SaveImageInBackgroundData data,
+            NotificationManager nManager) {
+        Resources r = context.getResources();
+
+        // Prepare all the output metadata
+        mParams = data;
+        mImageTime = System.currentTimeMillis();
+        String imageDate = new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(mImageTime));
+        mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, imageDate);
+
+        // Initialize screenshot notification smart actions provider.
+        mHandler = new Handler();
+        mSmartActionsProvider =
+                SystemUIFactory.getInstance().createScreenshotNotificationSmartActionsProvider();
+
+        // Create the large notification icon
+        mImageWidth = data.image.getWidth();
+        mImageHeight = data.image.getHeight();
+        int iconSize = data.iconSize;
+        int previewWidth = data.previewWidth;
+        int previewHeight = data.previewheight;
+
+        Paint paint = new Paint();
+        ColorMatrix desat = new ColorMatrix();
+        desat.setSaturation(0.25f);
+        paint.setColorFilter(new ColorMatrixColorFilter(desat));
+        Matrix matrix = new Matrix();
+        int overlayColor = 0x40FFFFFF;
+
+        matrix.setTranslate((previewWidth - mImageWidth) / 2,
+                (previewHeight - mImageHeight) / 2);
+        Bitmap picture = generateAdjustedHwBitmap(data.image, previewWidth, previewHeight,
+                matrix, paint, overlayColor);
+
+        // Note, we can't use the preview for the small icon, since it is non-square
+        float scale = (float) iconSize / Math.min(mImageWidth, mImageHeight);
+        matrix.setScale(scale, scale);
+        matrix.postTranslate((iconSize - (scale * mImageWidth)) / 2,
+                (iconSize - (scale * mImageHeight)) / 2);
+        Bitmap icon = generateAdjustedHwBitmap(data.image, iconSize, iconSize, matrix, paint,
+                overlayColor);
+
+        mNotificationManager = nManager;
+        final long now = System.currentTimeMillis();
+
+        // Setup the notification
+        mNotificationStyle = new Notification.BigPictureStyle()
+                .bigPicture(picture.createAshmemBitmap());
+
+        // The public notification will show similar info but with the actual screenshot omitted
+        mPublicNotificationBuilder =
+                new Notification.Builder(context, NotificationChannels.SCREENSHOTS_HEADSUP)
+                        .setContentTitle(r.getString(R.string.screenshot_saving_title))
+                        .setSmallIcon(R.drawable.stat_notify_image)
+                        .setCategory(Notification.CATEGORY_PROGRESS)
+                        .setWhen(now)
+                        .setShowWhen(true)
+                        .setColor(r.getColor(
+                                com.android.internal.R.color.system_notification_accent_color));
+        SystemUI.overrideNotificationAppName(context, mPublicNotificationBuilder, true);
+
+        mNotificationBuilder = new Notification.Builder(context,
+                NotificationChannels.SCREENSHOTS_HEADSUP)
+                .setContentTitle(r.getString(R.string.screenshot_saving_title))
+                .setSmallIcon(R.drawable.stat_notify_image)
+                .setWhen(now)
+                .setShowWhen(true)
+                .setColor(r.getColor(
+                        com.android.internal.R.color.system_notification_accent_color))
+                .setStyle(mNotificationStyle)
+                .setPublicVersion(mPublicNotificationBuilder.build());
+        mNotificationBuilder.setFlag(Notification.FLAG_NO_CLEAR, true);
+        SystemUI.overrideNotificationAppName(context, mNotificationBuilder, true);
+
+        mNotificationManager.notify(SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT,
+                mNotificationBuilder.build());
+
+        /**
+         * NOTE: The following code prepares the notification builder for updating the
+         * notification after the screenshot has been written to disk.
+         */
+
+        // On the tablet, the large icon makes the notification appear as if it is clickable
+        // (and on small devices, the large icon is not shown) so defer showing the large icon
+        // until we compose the final post-save notification below.
+        mNotificationBuilder.setLargeIcon(icon.createAshmemBitmap());
+        // But we still don't set it for the expanded view, allowing the smallIcon to show here.
+        mNotificationStyle.bigLargeIcon((Bitmap) null);
+    }
+
+    private int getUserHandleOfForegroundApplication(Context context) {
+        // This logic matches
+        // com.android.systemui.statusbar.phone.PhoneStatusBarPolicy#updateManagedProfile
+        try {
+            return ActivityTaskManager.getService().getLastResumedActivityUserId();
+        } catch (RemoteException e) {
+            Slog.w(TAG, "getUserHandleOfForegroundApplication: ", e);
+            return context.getUserId();
+        }
+    }
+
+    private boolean isManagedProfile(Context context) {
+        UserManager manager = UserManager.get(context);
+        UserInfo info = manager.getUserInfo(getUserHandleOfForegroundApplication(context));
+        return info.isManagedProfile();
+    }
+
+    /**
+     * Generates a new hardware bitmap with specified values, copying the content from the
+     * passed in bitmap.
+     */
+    private Bitmap generateAdjustedHwBitmap(Bitmap bitmap, int width, int height, Matrix matrix,
+            Paint paint, int color) {
+        Picture picture = new Picture();
+        Canvas canvas = picture.beginRecording(width, height);
+        canvas.drawColor(color);
+        canvas.drawBitmap(bitmap, matrix, paint);
+        picture.endRecording();
+        return Bitmap.createBitmap(picture);
+    }
+
+    @Override
+    protected Void doInBackground(Void... paramsUnused) {
+        if (isCancelled()) {
+            return null;
+        }
+
+        // By default, AsyncTask sets the worker thread to have background thread priority,
+        // so bump it back up so that we save a little quicker.
+        Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
+
+        Context context = mParams.context;
+        Bitmap image = mParams.image;
+        boolean smartActionsEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.ENABLE_SCREENSHOT_NOTIFICATION_SMART_ACTIONS, true);
+        CompletableFuture<List<Notification.Action>>
+                smartActionsFuture = GlobalScreenshot.getSmartActionsFuture(
+                context, image, mSmartActionsProvider, mHandler, smartActionsEnabled,
+                isManagedProfile(context));
+
+        Resources r = context.getResources();
+
+        try {
+            // Save the screenshot to the MediaStore
+            final MediaStore.PendingParams params = new MediaStore.PendingParams(
+                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, mImageFileName, "image/png");
+            params.setRelativePath(Environment.DIRECTORY_PICTURES + File.separator
+                    + Environment.DIRECTORY_SCREENSHOTS);
+
+            final Uri uri = MediaStore.createPending(context, params);
+            final MediaStore.PendingSession session = MediaStore.openPending(context, uri);
+            try {
+                // First, write the actual data for our screenshot
+                try (OutputStream out = session.openOutputStream()) {
+                    if (!image.compress(Bitmap.CompressFormat.PNG, 100, out)) {
+                        throw new IOException("Failed to compress");
+                    }
+                }
+
+                // Next, write metadata to help index the screenshot
+                try (ParcelFileDescriptor pfd = session.open()) {
+                    final ExifInterface exif = new ExifInterface(pfd.getFileDescriptor());
+
+                    exif.setAttribute(ExifInterface.TAG_SOFTWARE,
+                            "Android " + Build.DISPLAY);
+
+                    exif.setAttribute(ExifInterface.TAG_IMAGE_WIDTH,
+                            Integer.toString(image.getWidth()));
+                    exif.setAttribute(ExifInterface.TAG_IMAGE_LENGTH,
+                            Integer.toString(image.getHeight()));
+
+                    final ZonedDateTime time = ZonedDateTime.ofInstant(
+                            Instant.ofEpochMilli(mImageTime), ZoneId.systemDefault());
+                    exif.setAttribute(ExifInterface.TAG_DATETIME_ORIGINAL,
+                            DateTimeFormatter.ofPattern("yyyy:MM:dd HH:mm:ss").format(time));
+                    exif.setAttribute(ExifInterface.TAG_SUBSEC_TIME_ORIGINAL,
+                            DateTimeFormatter.ofPattern("SSS").format(time));
+
+                    if (Objects.equals(time.getOffset(), ZoneOffset.UTC)) {
+                        exif.setAttribute(ExifInterface.TAG_OFFSET_TIME_ORIGINAL, "+00:00");
+                    } else {
+                        exif.setAttribute(ExifInterface.TAG_OFFSET_TIME_ORIGINAL,
+                                DateTimeFormatter.ofPattern("XXX").format(time));
+                    }
+
+                    exif.saveAttributes();
+                }
+                session.publish();
+            } catch (Exception e) {
+                session.abandon();
+                throw e;
+            } finally {
+                IoUtils.closeQuietly(session);
+            }
+
+            // Note: Both the share and edit actions are proxied through ActionProxyReceiver in
+            // order to do some common work like dismissing the keyguard and sending
+            // closeSystemWindows
+
+            // Create a share intent, this will always go through the chooser activity first
+            // which should not trigger auto-enter PiP
+            String subjectDate = DateFormat.getDateTimeInstance().format(new Date(mImageTime));
+            String subject = String.format(SCREENSHOT_SHARE_SUBJECT_TEMPLATE, subjectDate);
+            Intent sharingIntent = new Intent(Intent.ACTION_SEND);
+            sharingIntent.setType("image/png");
+            sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
+            // Include URI in ClipData also, so that grantPermission picks it up.
+            // We don't use setData here because some apps interpret this as "to:".
+            ClipData clipdata = new ClipData(new ClipDescription("content",
+                    new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN}),
+                    new ClipData.Item(uri));
+            sharingIntent.setClipData(clipdata);
+            sharingIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
+            sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+            // Make sure pending intents for the system user are still unique across users
+            // by setting the (otherwise unused) request code to the current user id.
+            int requestCode = context.getUserId();
+
+            PendingIntent chooserAction = PendingIntent.getBroadcast(context, requestCode,
+                    new Intent(context, GlobalScreenshot.TargetChosenReceiver.class),
+                    PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
+            Intent sharingChooserIntent = Intent.createChooser(sharingIntent, null,
+                    chooserAction.getIntentSender())
+                    .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK)
+                    .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+            // Create a share action for the notification
+            PendingIntent shareAction = PendingIntent.getBroadcastAsUser(context, requestCode,
+                    new Intent(context, GlobalScreenshot.ActionProxyReceiver.class)
+                            .putExtra(GlobalScreenshot.EXTRA_ACTION_INTENT, sharingChooserIntent)
+                            .putExtra(GlobalScreenshot.EXTRA_DISALLOW_ENTER_PIP, true)
+                            .setAction(Intent.ACTION_SEND),
+                    PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.SYSTEM);
+            Notification.Action.Builder shareActionBuilder = new Notification.Action.Builder(
+                    R.drawable.ic_screenshot_share,
+                    r.getString(com.android.internal.R.string.share), shareAction);
+            mNotificationBuilder.addAction(shareActionBuilder.build());
+
+            // Create an edit intent, if a specific package is provided as the editor, then
+            // launch that directly
+            String editorPackage = context.getString(R.string.config_screenshotEditor);
+            Intent editIntent = new Intent(Intent.ACTION_EDIT);
+            if (!TextUtils.isEmpty(editorPackage)) {
+                editIntent.setComponent(ComponentName.unflattenFromString(editorPackage));
+            }
+            editIntent.setType("image/png");
+            editIntent.setData(uri);
+            editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            editIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+
+            // Create a edit action
+            PendingIntent editAction = PendingIntent.getBroadcastAsUser(context, requestCode,
+                    new Intent(context, GlobalScreenshot.ActionProxyReceiver.class)
+                            .putExtra(GlobalScreenshot.EXTRA_ACTION_INTENT, editIntent)
+                            .putExtra(GlobalScreenshot.EXTRA_CANCEL_NOTIFICATION,
+                                    editIntent.getComponent() != null)
+                            .setAction(Intent.ACTION_EDIT),
+                    PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.SYSTEM);
+            Notification.Action.Builder editActionBuilder = new Notification.Action.Builder(
+                    R.drawable.ic_screenshot_edit,
+                    r.getString(com.android.internal.R.string.screenshot_edit), editAction);
+            mNotificationBuilder.addAction(editActionBuilder.build());
+            if (editAction != null && mParams.onEditReady != null) {
+                mParams.onEditReady.apply(editAction);
+            }
+
+            // Create a delete action for the notification
+            PendingIntent deleteAction = PendingIntent.getBroadcast(context, requestCode,
+                    new Intent(context, GlobalScreenshot.DeleteScreenshotReceiver.class)
+                            .putExtra(GlobalScreenshot.SCREENSHOT_URI_ID, uri.toString()),
+                    PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
+            Notification.Action.Builder deleteActionBuilder = new Notification.Action.Builder(
+                    R.drawable.ic_screenshot_delete,
+                    r.getString(com.android.internal.R.string.delete), deleteAction);
+            mNotificationBuilder.addAction(deleteActionBuilder.build());
+
+            mParams.imageUri = uri;
+            mParams.image = null;
+            mParams.errorMsgResId = 0;
+
+            if (smartActionsEnabled) {
+                int timeoutMs = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
+                        SystemUiDeviceConfigFlags
+                                .SCREENSHOT_NOTIFICATION_SMART_ACTIONS_TIMEOUT_MS,
+                        1000);
+                List<Notification.Action> smartActions = GlobalScreenshot.getSmartActions(
+                        smartActionsFuture,
+                        timeoutMs);
+                for (Notification.Action action : smartActions) {
+                    mNotificationBuilder.addAction(action);
+                }
+            }
+        } catch (Exception e) {
+            // IOException/UnsupportedOperationException may be thrown if external storage is
+            // not mounted
+            Slog.e(TAG, "unable to save screenshot", e);
+            mParams.clearImage();
+            mParams.errorMsgResId = R.string.screenshot_failed_to_save_text;
+        }
+
+        // Recycle the bitmap data
+        if (image != null) {
+            image.recycle();
+        }
+
+        return null;
+    }
+
+    @Override
+    protected void onPostExecute(Void params) {
+        if (mParams.errorMsgResId != 0) {
+            // Show a message that we've failed to save the image to disk
+            GlobalScreenshot.notifyScreenshotError(mParams.context, mNotificationManager,
+                    mParams.errorMsgResId);
+        } else {
+            if (mParams.onEditReady != null) {
+                // Cancel the "saving screenshot" notification
+                mNotificationManager.cancel(
+                        SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT);
+            } else {
+                // Show the final notification to indicate screenshot saved
+                Context context = mParams.context;
+                Resources r = context.getResources();
+
+                // Create the intent to show the screenshot in gallery
+                Intent launchIntent = new Intent(Intent.ACTION_VIEW);
+                launchIntent.setDataAndType(mParams.imageUri, "image/png");
+                launchIntent.setFlags(
+                        Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+                final long now = System.currentTimeMillis();
+
+                // Update the text and the icon for the existing notification
+                mPublicNotificationBuilder
+                        .setContentTitle(r.getString(R.string.screenshot_saved_title))
+                        .setContentText(r.getString(R.string.screenshot_saved_text))
+                        .setContentIntent(
+                                PendingIntent.getActivity(mParams.context, 0, launchIntent, 0))
+                        .setWhen(now)
+                        .setAutoCancel(true)
+                        .setColor(context.getColor(
+                                com.android.internal.R.color.system_notification_accent_color));
+                mNotificationBuilder
+                        .setContentTitle(r.getString(R.string.screenshot_saved_title))
+                        .setContentText(r.getString(R.string.screenshot_saved_text))
+                        .setContentIntent(PendingIntent.getActivity(mParams.context, 0,
+                                launchIntent, 0))
+                        .setWhen(now)
+                        .setAutoCancel(true)
+                        .setColor(context.getColor(
+                                com.android.internal.R.color.system_notification_accent_color))
+                        .setPublicVersion(mPublicNotificationBuilder.build())
+                        .setFlag(Notification.FLAG_NO_CLEAR, false);
+
+                mNotificationManager.notify(SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT,
+                        mNotificationBuilder.build());
+            }
+        }
+        mParams.finisher.run();
+        mParams.clearContext();
+    }
+
+    @Override
+    protected void onCancelled(Void params) {
+        // If we are cancelled while the task is running in the background, we may get null
+        // params. The finisher is expected to always be called back, so just use the baked-in
+        // params from the ctor in any case.
+        mParams.finisher.run();
+        mParams.clearImage();
+        mParams.clearContext();
+
+        // Cancel the posted notification
+        mNotificationManager.cancel(SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT);
+    }
+}
