Merge "Remove legacy screenshot notifications flow" into rvc-dev

This commit is contained in:
Miranda Kephart
2020-06-11 17:28:46 +00:00
committed by Android (Google) Code Review
5 changed files with 5 additions and 680 deletions

View File

@@ -120,7 +120,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
public Consumer<Uri> finisher;
public GlobalScreenshot.ActionsReadyListener mActionsReadyListener;
public int errorMsgResId;
public boolean createDeleteAction;
void clearImage() {
image = null;
@@ -437,7 +436,6 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
data.image = mScreenBitmap;
data.finisher = finisher;
data.mActionsReadyListener = actionsReadyListener;
data.createDeleteAction = false;
if (mSaveInBgTask != null) {
// just log success/failure for the pre-existing screenshot

View File

@@ -1,567 +0,0 @@
/*
* Copyright (C) 2011 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 static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.PointF;
import android.graphics.Rect;
import android.media.MediaActionSound;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.PowerManager;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Interpolator;
import android.widget.ImageView;
import android.widget.Toast;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Main;
import java.util.function.Consumer;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* Class for handling device screen shots
*
* @deprecated will be removed when corner flow is complete and tested
*/
@Singleton
@Deprecated
public class GlobalScreenshotLegacy {
// These strings are used for communicating the action invoked to
// ScreenshotNotificationSmartActionsProvider.
static final String EXTRA_ACTION_TYPE = "android:screenshot_action_type";
static final String EXTRA_ID = "android:screenshot_id";
static final String ACTION_TYPE_DELETE = "Delete";
static final String ACTION_TYPE_SHARE = "Share";
static final String ACTION_TYPE_EDIT = "Edit";
static final String EXTRA_SMART_ACTIONS_ENABLED = "android:smart_actions_enabled";
static final String EXTRA_ACTION_INTENT = "android:screenshot_action_intent";
static final String SCREENSHOT_URI_ID = "android:screenshot_uri_id";
static final String EXTRA_CANCEL_NOTIFICATION = "android:screenshot_cancel_notification";
static final String EXTRA_DISALLOW_ENTER_PIP = "android:screenshot_disallow_enter_pip";
private static final String TAG = "GlobalScreenshot";
private static final int SCREENSHOT_FLASH_TO_PEAK_DURATION = 130;
private static final int SCREENSHOT_DROP_IN_DURATION = 430;
private static final int SCREENSHOT_DROP_OUT_DELAY = 500;
private static final int SCREENSHOT_DROP_OUT_DURATION = 430;
private static final int SCREENSHOT_DROP_OUT_SCALE_DURATION = 370;
private static final int SCREENSHOT_FAST_DROP_OUT_DURATION = 320;
private static final float BACKGROUND_ALPHA = 0.5f;
private static final float SCREENSHOT_SCALE = 1f;
private static final float SCREENSHOT_DROP_IN_MIN_SCALE = SCREENSHOT_SCALE * 0.725f;
private static final float SCREENSHOT_DROP_OUT_MIN_SCALE = SCREENSHOT_SCALE * 0.45f;
private static final float SCREENSHOT_FAST_DROP_OUT_MIN_SCALE = SCREENSHOT_SCALE * 0.6f;
private static final float SCREENSHOT_DROP_OUT_MIN_SCALE_OFFSET = 0f;
private final ScreenshotNotificationsController mNotificationsController;
private Context mContext;
private WindowManager mWindowManager;
private WindowManager.LayoutParams mWindowLayoutParams;
private Display mDisplay;
private DisplayMetrics mDisplayMetrics;
private Bitmap mScreenBitmap;
private View mScreenshotLayout;
private ScreenshotSelectorView mScreenshotSelectorView;
private ImageView mBackgroundView;
private ImageView mScreenshotView;
private ImageView mScreenshotFlash;
private AnimatorSet mScreenshotAnimation;
private float mBgPadding;
private float mBgPaddingScale;
private AsyncTask<Void, Void, Void> mSaveInBgTask;
private MediaActionSound mCameraSound;
/**
* @param context everything needs a context :(
*/
@Inject
public GlobalScreenshotLegacy(
Context context, @Main Resources resources, LayoutInflater layoutInflater,
ScreenshotNotificationsController screenshotNotificationsController) {
mContext = context;
mNotificationsController = screenshotNotificationsController;
// Inflate the screenshot layout
mScreenshotLayout = layoutInflater.inflate(R.layout.global_screenshot_legacy, null);
mBackgroundView = mScreenshotLayout.findViewById(R.id.global_screenshot_legacy_background);
mScreenshotView = mScreenshotLayout.findViewById(R.id.global_screenshot_legacy);
mScreenshotFlash = mScreenshotLayout.findViewById(R.id.global_screenshot_legacy_flash);
mScreenshotSelectorView = mScreenshotLayout.findViewById(
R.id.global_screenshot_legacy_selector);
mScreenshotLayout.setFocusable(true);
mScreenshotSelectorView.setFocusable(true);
mScreenshotSelectorView.setFocusableInTouchMode(true);
mScreenshotLayout.setOnTouchListener((v, event) -> {
// Intercept and ignore all touch events
return true;
});
// Setup the window that we are going to use
mWindowLayoutParams = new WindowManager.LayoutParams(
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,
PixelFormat.TRANSLUCENT);
mWindowLayoutParams.setTitle("ScreenshotAnimation");
mWindowLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
mWindowLayoutParams.setFitInsetsTypes(0 /* types */);
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mDisplay = mWindowManager.getDefaultDisplay();
mDisplayMetrics = new DisplayMetrics();
mDisplay.getRealMetrics(mDisplayMetrics);
// Scale has to account for both sides of the bg
mBgPadding = (float) resources.getDimensionPixelSize(
R.dimen.global_screenshot_legacy_bg_padding);
mBgPaddingScale = mBgPadding / mDisplayMetrics.widthPixels;
// Setup the Camera shutter sound
mCameraSound = new MediaActionSound();
mCameraSound.load(MediaActionSound.SHUTTER_CLICK);
}
/**
* Creates a new worker thread and saves the screenshot to the media store.
*/
private void saveScreenshotInWorkerThread(
Consumer<Uri> finisher,
@Nullable GlobalScreenshot.ActionsReadyListener actionsReadyListener) {
GlobalScreenshot.SaveImageInBackgroundData data =
new GlobalScreenshot.SaveImageInBackgroundData();
data.image = mScreenBitmap;
data.finisher = finisher;
data.mActionsReadyListener = actionsReadyListener;
data.createDeleteAction = true;
if (mSaveInBgTask != null) {
mSaveInBgTask.cancel(false);
}
mNotificationsController.reset();
mNotificationsController.setImage(mScreenBitmap);
mNotificationsController.showSavingScreenshotNotification();
mSaveInBgTask = new SaveImageInBackgroundTask(mContext, data).execute();
}
/**
* Takes a screenshot of the current display and shows an animation.
*/
private void takeScreenshot(Consumer<Uri> finisher, boolean statusBarVisible,
boolean navBarVisible, Rect crop) {
int rot = mDisplay.getRotation();
int width = crop.width();
int height = crop.height();
takeScreenshot(SurfaceControl.screenshot(crop, width, height, rot), finisher,
statusBarVisible, navBarVisible, null);
}
private void takeScreenshot(Bitmap screenshot, Consumer<Uri> finisher, boolean statusBarVisible,
boolean navBarVisible, Rect screenboundsOfBitmap) {
mScreenBitmap = screenshot;
if (mScreenBitmap == null) {
mNotificationsController.notifyScreenshotError(
R.string.screenshot_failed_to_capture_text);
finisher.accept(null);
return;
}
// Optimizations
mScreenBitmap.setHasAlpha(false);
mScreenBitmap.prepareToDraw();
// Start the post-screenshot animation
startAnimation(finisher, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels,
statusBarVisible, navBarVisible, screenboundsOfBitmap);
}
void takeScreenshot(Consumer<Uri> finisher, boolean statusBarVisible, boolean navBarVisible) {
mDisplay.getRealMetrics(mDisplayMetrics);
takeScreenshot(finisher, statusBarVisible, navBarVisible,
new Rect(0, 0, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
}
void handleImageAsScreenshot(Bitmap screenshot, Rect screenshotScreenBounds,
Insets visibleInsets, int taskId, int userId, ComponentName topComponent,
Consumer<Uri> finisher) {
// TODO: use task Id, userId, topComponent for smart handler
// TODO: use visibleInsets for animation
takeScreenshot(screenshot, finisher, false, false, screenshotScreenBounds);
}
/**
* Displays a screenshot selector
*/
void takeScreenshotPartial(final Consumer<Uri> finisher, final boolean statusBarVisible,
final boolean navBarVisible) {
mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
mScreenshotSelectorView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
ScreenshotSelectorView view = (ScreenshotSelectorView) v;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
view.startSelection((int) event.getX(), (int) event.getY());
return true;
case MotionEvent.ACTION_MOVE:
view.updateSelection((int) event.getX(), (int) event.getY());
return true;
case MotionEvent.ACTION_UP:
view.setVisibility(View.GONE);
mWindowManager.removeView(mScreenshotLayout);
final Rect rect = view.getSelectionRect();
if (rect != null) {
if (rect.width() != 0 && rect.height() != 0) {
// Need mScreenshotLayout to handle it after the view disappears
mScreenshotLayout.post(() -> takeScreenshot(
finisher, statusBarVisible, navBarVisible, rect));
}
}
view.stopSelection();
return true;
}
return false;
}
});
mScreenshotLayout.post(() -> {
mScreenshotSelectorView.setVisibility(View.VISIBLE);
mScreenshotSelectorView.requestFocus();
});
}
/**
* Cancels screenshot request
*/
void stopScreenshot() {
// If the selector layer still presents on screen, we remove it and resets its state.
if (mScreenshotSelectorView.getSelectionRect() != null) {
mWindowManager.removeView(mScreenshotLayout);
mScreenshotSelectorView.stopSelection();
}
}
/**
* Clears current screenshot
*/
private void clearScreenshot() {
if (mScreenshotLayout.isAttachedToWindow()) {
mWindowManager.removeView(mScreenshotLayout);
}
// Clear any references to the bitmap
mScreenBitmap = null;
mScreenshotView.setImageBitmap(null);
mBackgroundView.setVisibility(View.GONE);
mScreenshotView.setVisibility(View.GONE);
mScreenshotView.setLayerType(View.LAYER_TYPE_NONE, null);
}
/**
* Starts the animation after taking the screenshot
*/
private void startAnimation(final Consumer<Uri> finisher, int w, int h,
boolean statusBarVisible, boolean navBarVisible, @Nullable Rect screenBoundsOfBitmap) {
// If power save is on, show a toast so there is some visual indication that a screenshot
// has been taken.
PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
if (powerManager.isPowerSaveMode()) {
Toast.makeText(mContext, R.string.screenshot_saved_title, Toast.LENGTH_SHORT).show();
}
// Add the view for the animation
mScreenshotView.setImageBitmap(mScreenBitmap);
mScreenshotLayout.requestFocus();
// Setup the animation with the screenshot just taken
if (mScreenshotAnimation != null) {
if (mScreenshotAnimation.isStarted()) {
mScreenshotAnimation.end();
}
mScreenshotAnimation.removeAllListeners();
}
mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
ValueAnimator screenshotDropInAnim = screenBoundsOfBitmap != null
? createRectAnimation(screenBoundsOfBitmap) : createScreenshotDropInAnimation();
ValueAnimator screenshotFadeOutAnim =
createScreenshotDropOutAnimation(w, h, statusBarVisible, navBarVisible);
mScreenshotAnimation = new AnimatorSet();
mScreenshotAnimation.playSequentially(screenshotDropInAnim, screenshotFadeOutAnim);
mScreenshotAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
// Save the screenshot once we have a bit of time now
saveScreenshotInWorkerThread(finisher, new GlobalScreenshot.ActionsReadyListener() {
@Override
void onActionsReady(GlobalScreenshot.SavedImageData actionData) {
if (actionData.uri == null) {
mNotificationsController.notifyScreenshotError(
R.string.screenshot_failed_to_capture_text);
} else {
mNotificationsController
.showScreenshotActionsNotification(actionData);
}
}
});
clearScreenshot();
}
});
mScreenshotLayout.post(() -> {
// Play the shutter sound to notify that we've taken a screenshot
mCameraSound.play(MediaActionSound.SHUTTER_CLICK);
mScreenshotView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
mScreenshotView.buildLayer();
mScreenshotAnimation.start();
});
}
private ValueAnimator createScreenshotDropInAnimation() {
final float flashPeakDurationPct = ((float) (SCREENSHOT_FLASH_TO_PEAK_DURATION)
/ SCREENSHOT_DROP_IN_DURATION);
final float flashDurationPct = 2f * flashPeakDurationPct;
final Interpolator flashAlphaInterpolator = new Interpolator() {
@Override
public float getInterpolation(float x) {
// Flash the flash view in and out quickly
if (x <= flashDurationPct) {
return (float) Math.sin(Math.PI * (x / flashDurationPct));
}
return 0;
}
};
final Interpolator scaleInterpolator = new Interpolator() {
@Override
public float getInterpolation(float x) {
// We start scaling when the flash is at it's peak
if (x < flashPeakDurationPct) {
return 0;
}
return (x - flashDurationPct) / (1f - flashDurationPct);
}
};
Resources r = mContext.getResources();
if ((r.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK)
== Configuration.UI_MODE_NIGHT_YES) {
mScreenshotView.getBackground().setTint(Color.BLACK);
} else {
mScreenshotView.getBackground().setTintList(null);
}
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(SCREENSHOT_DROP_IN_DURATION);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mBackgroundView.setAlpha(0f);
mBackgroundView.setVisibility(View.VISIBLE);
mScreenshotView.setAlpha(0f);
mScreenshotView.setTranslationX(0f);
mScreenshotView.setTranslationY(0f);
mScreenshotView.setScaleX(SCREENSHOT_SCALE + mBgPaddingScale);
mScreenshotView.setScaleY(SCREENSHOT_SCALE + mBgPaddingScale);
mScreenshotView.setVisibility(View.VISIBLE);
mScreenshotFlash.setAlpha(0f);
mScreenshotFlash.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(android.animation.Animator animation) {
mScreenshotFlash.setVisibility(View.GONE);
}
});
anim.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float t = (Float) animation.getAnimatedValue();
float scaleT = (SCREENSHOT_SCALE + mBgPaddingScale)
- scaleInterpolator.getInterpolation(t)
* (SCREENSHOT_SCALE - SCREENSHOT_DROP_IN_MIN_SCALE);
mBackgroundView.setAlpha(scaleInterpolator.getInterpolation(t) * BACKGROUND_ALPHA);
mScreenshotView.setAlpha(t);
mScreenshotView.setScaleX(scaleT);
mScreenshotView.setScaleY(scaleT);
mScreenshotFlash.setAlpha(flashAlphaInterpolator.getInterpolation(t));
}
});
return anim;
}
/**
* If a bitmap was supplied to be used as the screenshot, animated from where that bitmap was
* on screen, rather than using the whole screen.
*/
private ValueAnimator createRectAnimation(Rect rect) {
mScreenshotView.setAdjustViewBounds(true);
mScreenshotView.setMaxHeight(rect.height());
mScreenshotView.setMaxWidth(rect.width());
final float flashPeakDurationPct = ((float) (SCREENSHOT_FLASH_TO_PEAK_DURATION)
/ SCREENSHOT_DROP_IN_DURATION);
final float flashDurationPct = 2f * flashPeakDurationPct;
final Interpolator scaleInterpolator = x -> {
// We start scaling when the flash is at it's peak
if (x < flashPeakDurationPct) {
return 0;
}
return (x - flashDurationPct) / (1f - flashDurationPct);
};
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(SCREENSHOT_DROP_IN_DURATION);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mBackgroundView.setAlpha(0f);
mBackgroundView.setVisibility(View.VISIBLE);
mScreenshotView.setAlpha(0f);
mScreenshotView.setElevation(0f);
mScreenshotView.setTranslationX(0f);
mScreenshotView.setTranslationY(0f);
mScreenshotView.setScaleX(SCREENSHOT_SCALE + mBgPaddingScale);
mScreenshotView.setScaleY(SCREENSHOT_SCALE + mBgPaddingScale);
mScreenshotView.setVisibility(View.VISIBLE);
}
});
anim.addUpdateListener(animation -> {
float t = (Float) animation.getAnimatedValue();
float scaleT = (SCREENSHOT_SCALE + mBgPaddingScale)
- scaleInterpolator.getInterpolation(t)
* (SCREENSHOT_SCALE - SCREENSHOT_DROP_IN_MIN_SCALE);
mBackgroundView.setAlpha(scaleInterpolator.getInterpolation(t) * BACKGROUND_ALPHA);
mScreenshotView.setAlpha(t);
});
return anim;
}
private ValueAnimator createScreenshotDropOutAnimation(int w, int h, boolean statusBarVisible,
boolean navBarVisible) {
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setStartDelay(SCREENSHOT_DROP_OUT_DELAY);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mBackgroundView.setVisibility(View.GONE);
mScreenshotView.setVisibility(View.GONE);
mScreenshotView.setLayerType(View.LAYER_TYPE_NONE, null);
}
});
if (!statusBarVisible || !navBarVisible) {
// There is no status bar/nav bar, so just fade the screenshot away in place
anim.setDuration(SCREENSHOT_FAST_DROP_OUT_DURATION);
anim.addUpdateListener(new AnimatorUpdateListener() {
@Override
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);
mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
mScreenshotView.setAlpha(1f - t);
mScreenshotView.setScaleX(scaleT);
mScreenshotView.setScaleY(scaleT);
}
});
} else {
// In the case where there is a status bar, animate to the origin of the bar (top-left)
final float scaleDurationPct = (float) SCREENSHOT_DROP_OUT_SCALE_DURATION
/ SCREENSHOT_DROP_OUT_DURATION;
final Interpolator scaleInterpolator = new Interpolator() {
@Override
public float getInterpolation(float x) {
if (x < scaleDurationPct) {
// Decelerate, and scale the input accordingly
return (float) (1f - Math.pow(1f - (x / scaleDurationPct), 2f));
}
return 1f;
}
};
// Determine the bounds of how to scale
float halfScreenWidth = (w - 2f * mBgPadding) / 2f;
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);
// Animate the screenshot to the status bar
anim.setDuration(SCREENSHOT_DROP_OUT_DURATION);
anim.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float t = (Float) animation.getAnimatedValue();
float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale)
- 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));
mScreenshotView.setScaleX(scaleT);
mScreenshotView.setScaleY(scaleT);
mScreenshotView.setTranslationX(t * finalPos.x);
mScreenshotView.setTranslationY(t * finalPos.y);
}
});
}
return anim;
}
}

View File

@@ -88,7 +88,6 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
private final ScreenshotNotificationSmartActionsProvider mSmartActionsProvider;
private final String mScreenshotId;
private final boolean mSmartActionsEnabled;
private final boolean mCreateDeleteAction;
private final Random mRandom = new Random();
SaveImageInBackgroundTask(Context context, GlobalScreenshot.SaveImageInBackgroundData data) {
@@ -102,8 +101,6 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, imageDate);
mScreenshotId = String.format(SCREENSHOT_ID_TEMPLATE, UUID.randomUUID());
mCreateDeleteAction = data.createDeleteAction;
// Initialize screenshot notification smart actions provider.
mSmartActionsEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.ENABLE_SCREENSHOT_NOTIFICATION_SMART_ACTIONS, true);

View File

@@ -147,84 +147,6 @@ public class ScreenshotNotificationsController {
mNotificationStyle.bigLargeIcon((Bitmap) null);
}
/**
* Shows a notification to inform the user that a screenshot is currently being saved.
*/
public void showSavingScreenshotNotification() {
final long now = System.currentTimeMillis();
mPublicNotificationBuilder
.setContentTitle(mResources.getString(R.string.screenshot_saving_title))
.setSmallIcon(R.drawable.stat_notify_image)
.setCategory(Notification.CATEGORY_PROGRESS)
.setWhen(now)
.setShowWhen(true)
.setColor(mResources.getColor(
com.android.internal.R.color.system_notification_accent_color));
SystemUI.overrideNotificationAppName(mContext, mPublicNotificationBuilder, true);
mNotificationBuilder
.setContentTitle(mResources.getString(R.string.screenshot_saving_title))
.setSmallIcon(R.drawable.stat_notify_image)
.setWhen(now)
.setShowWhen(true)
.setColor(mResources.getColor(
com.android.internal.R.color.system_notification_accent_color))
.setStyle(mNotificationStyle)
.setPublicVersion(mPublicNotificationBuilder.build());
mNotificationBuilder.setFlag(Notification.FLAG_NO_CLEAR, true);
SystemUI.overrideNotificationAppName(mContext, mNotificationBuilder, true);
mNotificationManager.notify(SystemMessageProto.SystemMessage.NOTE_GLOBAL_SCREENSHOT,
mNotificationBuilder.build());
}
/**
* Shows a notification with the saved screenshot and actions that can be taken with it.
*
* @param actionData SavedImageData struct with image URI and actions
*/
public void showScreenshotActionsNotification(
GlobalScreenshot.SavedImageData actionData) {
mNotificationBuilder.addAction(actionData.shareAction);
mNotificationBuilder.addAction(actionData.editAction);
mNotificationBuilder.addAction(actionData.deleteAction);
for (Notification.Action smartAction : actionData.smartActions) {
mNotificationBuilder.addAction(smartAction);
}
// Create the intent to show the screenshot in gallery
Intent launchIntent = new Intent(Intent.ACTION_VIEW);
launchIntent.setDataAndType(actionData.uri, "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(mResources.getString(R.string.screenshot_saved_title))
.setContentText(mResources.getString(R.string.screenshot_saved_text))
.setContentIntent(PendingIntent.getActivity(mContext, 0, launchIntent, 0))
.setWhen(now)
.setAutoCancel(true)
.setColor(mContext.getColor(
com.android.internal.R.color.system_notification_accent_color));
mNotificationBuilder
.setContentTitle(mResources.getString(R.string.screenshot_saved_title))
.setContentText(mResources.getString(R.string.screenshot_saved_text))
.setContentIntent(PendingIntent.getActivity(mContext, 0, launchIntent, 0))
.setWhen(now)
.setAutoCancel(true)
.setColor(mContext.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());
}
/**
* Shows a silent notification with the saved screenshot and actions that can be taken with it.
*

View File

@@ -48,7 +48,6 @@ public class TakeScreenshotService extends Service {
private static final String TAG = "TakeScreenshotService";
private final GlobalScreenshot mScreenshot;
private final GlobalScreenshotLegacy mScreenshotLegacy;
private final UserManager mUserManager;
private final UiEventLogger mUiEventLogger;
@@ -81,9 +80,6 @@ public class TakeScreenshotService extends Service {
return;
}
// TODO: clean up once notifications flow is fully deprecated
boolean useCornerFlow = true;
ScreenshotHelper.ScreenshotRequest screenshotRequest =
(ScreenshotHelper.ScreenshotRequest) msg.obj;
@@ -91,22 +87,10 @@ public class TakeScreenshotService extends Service {
switch (msg.what) {
case WindowManager.TAKE_SCREENSHOT_FULLSCREEN:
if (useCornerFlow) {
mScreenshot.takeScreenshot(uriConsumer, onComplete);
} else {
mScreenshotLegacy.takeScreenshot(
uriConsumer, screenshotRequest.getHasStatusBar(),
screenshotRequest.getHasNavBar());
}
mScreenshot.takeScreenshot(uriConsumer, onComplete);
break;
case WindowManager.TAKE_SCREENSHOT_SELECTED_REGION:
if (useCornerFlow) {
mScreenshot.takeScreenshotPartial(uriConsumer, onComplete);
} else {
mScreenshotLegacy.takeScreenshotPartial(
uriConsumer, screenshotRequest.getHasStatusBar(),
screenshotRequest.getHasNavBar());
}
mScreenshot.takeScreenshotPartial(uriConsumer, onComplete);
break;
case WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE:
Bitmap screenshot = BitmapUtil.bundleToHardwareBitmap(
@@ -116,13 +100,8 @@ public class TakeScreenshotService extends Service {
int taskId = screenshotRequest.getTaskId();
int userId = screenshotRequest.getUserId();
ComponentName topComponent = screenshotRequest.getTopComponent();
if (useCornerFlow) {
mScreenshot.handleImageAsScreenshot(screenshot, screenBounds, insets,
taskId, userId, topComponent, uriConsumer, onComplete);
} else {
mScreenshotLegacy.handleImageAsScreenshot(screenshot, screenBounds, insets,
taskId, userId, topComponent, uriConsumer);
}
mScreenshot.handleImageAsScreenshot(screenshot, screenBounds, insets,
taskId, userId, topComponent, uriConsumer, onComplete);
break;
default:
Log.d(TAG, "Invalid screenshot option: " + msg.what);
@@ -131,11 +110,9 @@ public class TakeScreenshotService extends Service {
};
@Inject
public TakeScreenshotService(GlobalScreenshot globalScreenshot,
GlobalScreenshotLegacy globalScreenshotLegacy, UserManager userManager,
public TakeScreenshotService(GlobalScreenshot globalScreenshot, UserManager userManager,
UiEventLogger uiEventLogger) {
mScreenshot = globalScreenshot;
mScreenshotLegacy = globalScreenshotLegacy;
mUserManager = userManager;
mUiEventLogger = uiEventLogger;
}
@@ -148,8 +125,6 @@ public class TakeScreenshotService extends Service {
@Override
public boolean onUnbind(Intent intent) {
if (mScreenshot != null) mScreenshot.stopScreenshot();
// TODO remove once notifications flow is fully deprecated
if (mScreenshotLegacy != null) mScreenshotLegacy.stopScreenshot();
return true;
}
}