summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/layout/long_screenshot.xml102
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ImageTileSet.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java54
3 files changed, 98 insertions, 72 deletions
diff --git a/packages/SystemUI/res/layout/long_screenshot.xml b/packages/SystemUI/res/layout/long_screenshot.xml
index 2a055fc8252f..8f3345f9d85c 100644
--- a/packages/SystemUI/res/layout/long_screenshot.xml
+++ b/packages/SystemUI/res/layout/long_screenshot.xml
@@ -22,35 +22,82 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
+ <Button
+ android:id="@+id/save"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/save"
+ app:layout_constraintEnd_toStartOf="@id/cancel"
+ app:layout_constraintHorizontal_chainStyle="packed"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/guideline" />
+
+ <Button
+ android:id="@+id/cancel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel"
+ app:layout_constraintEnd_toStartOf="@id/edit"
+ app:layout_constraintStart_toEndOf="@id/save"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/guideline" />
+
+ <Button
+ android:id="@+id/edit"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/screenshot_edit_label"
+ app:layout_constraintEnd_toStartOf="@id/share"
+ app:layout_constraintStart_toEndOf="@id/cancel"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/guideline" />
+
+ <Button
+ android:id="@+id/share"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@*android:string/share"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toEndOf="@+id/edit"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/guideline" />
+
+ <androidx.constraintlayout.widget.Guideline
+ android:id="@+id/guideline"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ app:layout_constraintGuide_percent="0.1" />
+
<ImageView
android:id="@+id/preview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginVertical="8dp"
+ android:layout_marginBottom="24dp"
android:layout_marginHorizontal="48dp"
android:adjustViewBounds="true"
app:layout_constrainedHeight="true"
app:layout_constrainedWidth="true"
- app:layout_constraintBottom_toBottomOf="@id/guideline"
+ app:layout_constraintTop_toBottomOf="@id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
tools:background="?android:colorBackground"
tools:minHeight="100dp"
tools:minWidth="100dp" />
<com.android.systemui.screenshot.CropView
android:id="@+id/crop_view"
- android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginVertical="8dp"
+ android:layout_marginBottom="24dp"
app:layout_constrainedHeight="true"
app:layout_constrainedWidth="true"
- app:layout_constraintBottom_toBottomOf="@id/guideline"
+ app:layout_constraintTop_toBottomOf="@id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
app:handleThickness="3dp"
app:handleColor="@*android:color/accent_device_default"
app:scrimColor="#9444"
@@ -58,46 +105,5 @@
tools:minHeight="100dp"
tools:minWidth="100dp" />
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/guideline"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- app:layout_constraintGuide_percent="0.9" />
-
- <Button
- android:id="@+id/close"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="8dp"
- android:text="Close"
- app:layout_constraintEnd_toStartOf="@+id/edit"
- app:layout_constraintHorizontal_bias="0.5"
- app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="@+id/guideline" />
-
- <Button
- android:id="@+id/edit"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="8dp"
- android:text="Edit"
- app:layout_constraintEnd_toStartOf="@+id/share"
- app:layout_constraintHorizontal_bias="0.5"
- app:layout_constraintStart_toEndOf="@+id/close"
- app:layout_constraintTop_toTopOf="@+id/guideline" />
-
- <Button
- android:id="@+id/share"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="8dp"
- android:text="Share"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintHorizontal_bias="0.5"
- app:layout_constraintStart_toEndOf="@+id/edit"
- app:layout_constraintTop_toTopOf="@+id/guideline" />
-
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ImageTileSet.java b/packages/SystemUI/src/com/android/systemui/screenshot/ImageTileSet.java
index 8ff66f548172..20f845103723 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ImageTileSet.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ImageTileSet.java
@@ -108,6 +108,15 @@ class ImageTileSet {
}
Bitmap toBitmap() {
+ return toBitmap(new Rect(0, 0, getWidth(), getHeight()));
+ }
+
+ /**
+ * @param bounds Selected portion of the tile set's bounds (equivalent to tile bounds coord
+ * space). For example, to get the whole doc, use Rect(0, 0, getWidth(),
+ * getHeight()).
+ */
+ Bitmap toBitmap(Rect bounds) {
if (mTiles.isEmpty()) {
return null;
}
@@ -115,6 +124,9 @@ class ImageTileSet {
output.setPosition(0, 0, getWidth(), getHeight());
RecordingCanvas canvas = output.beginRecording();
canvas.translate(-getLeft(), -getTop());
+ // Additional translation to account for the requested bounds
+ canvas.translate(-bounds.left, -bounds.top);
+ canvas.clipRect(bounds);
for (ImageTile tile : mTiles) {
canvas.save();
canvas.translate(tile.getLeft(), tile.getTop());
@@ -122,7 +134,7 @@ class ImageTileSet {
canvas.restore();
}
output.endRecording();
- return HardwareRenderer.createHardwareBitmap(output, getWidth(), getHeight());
+ return HardwareRenderer.createHardwareBitmap(output, bounds.width(), bounds.height());
}
int getLeft() {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
index db295332bbdd..18c379a4650f 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
@@ -21,6 +21,7 @@ import android.annotation.UiThread;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.graphics.Rect;
import android.net.Uri;
import android.os.UserHandle;
import android.text.TextUtils;
@@ -54,7 +55,8 @@ public class ScrollCaptureController implements OnComputeInternalInsetsListener
// TODO: Support saving without additional action.
private enum PendingAction {
SHARE,
- EDIT
+ EDIT,
+ SAVE
}
public static final int MAX_PAGES = 5;
@@ -74,9 +76,11 @@ public class ScrollCaptureController implements OnComputeInternalInsetsListener
private RequestCallback mCallback;
private Window mWindow;
private ImageView mPreview;
- private View mClose;
+ private View mSave;
+ private View mCancel;
private View mEdit;
private View mShare;
+ private CropView mCropView;
public ScrollCaptureController(Context context, Connection connection, Executor uiExecutor,
Executor bgExecutor, ImageExporter exporter, UiEventLogger uiEventLogger) {
@@ -111,11 +115,14 @@ public class ScrollCaptureController implements OnComputeInternalInsetsListener
.addOnComputeInternalInsetsListener(this);
mPreview = findViewById(R.id.preview);
- mClose = findViewById(R.id.close);
+ mSave = findViewById(R.id.save);
+ mCancel = findViewById(R.id.cancel);
mEdit = findViewById(R.id.edit);
mShare = findViewById(R.id.share);
+ mCropView = findViewById(R.id.crop_view);
- mClose.setOnClickListener(this::onClicked);
+ mSave.setOnClickListener(this::onClicked);
+ mCancel.setOnClickListener(this::onClicked);
mEdit.setOnClickListener(this::onClicked);
mShare.setOnClickListener(this::onClicked);
@@ -130,7 +137,8 @@ public class ScrollCaptureController implements OnComputeInternalInsetsListener
}
void disableButtons() {
- mClose.setEnabled(false);
+ mSave.setEnabled(false);
+ mCancel.setEnabled(false);
mEdit.setEnabled(false);
mShare.setEnabled(false);
}
@@ -139,19 +147,17 @@ public class ScrollCaptureController implements OnComputeInternalInsetsListener
Log.d(TAG, "button clicked!");
int id = v.getId();
- if (id == R.id.close) {
- v.setPressed(true);
- disableButtons();
+ v.setPressed(true);
+ disableButtons();
+ if (id == R.id.save) {
+ startExport(PendingAction.SAVE);
+ } else if (id == R.id.cancel) {
doFinish();
} else if (id == R.id.edit) {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_LONG_SCREENSHOT_EDIT);
- v.setPressed(true);
- disableButtons();
startExport(PendingAction.EDIT);
} else if (id == R.id.share) {
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_LONG_SCREENSHOT_SHARE);
- v.setPressed(true);
- disableButtons();
startExport(PendingAction.SHARE);
}
}
@@ -165,8 +171,13 @@ public class ScrollCaptureController implements OnComputeInternalInsetsListener
}
private void startExport(PendingAction action) {
+ Rect croppedPortion = new Rect(
+ 0,
+ (int) (mImageTileSet.getHeight() * mCropView.getTopBoundary()),
+ mImageTileSet.getWidth(),
+ (int) (mImageTileSet.getHeight() * mCropView.getBottomBoundary()));
ListenableFuture<ImageExporter.Result> exportFuture = mImageExporter.export(
- mBgExecutor, mRequestId, mImageTileSet.toBitmap(), mCaptureTime);
+ mBgExecutor, mRequestId, mImageTileSet.toBitmap(croppedPortion), mCaptureTime);
exportFuture.addListener(() -> {
try {
ImageExporter.Result result = exportFuture.get();
@@ -191,24 +202,21 @@ public class ScrollCaptureController implements OnComputeInternalInsetsListener
}
intent.setType("image/png");
intent.setData(uri);
- intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- Intent sharingChooserIntent = Intent.createChooser(intent, null)
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK)
- .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK
+ | Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- mContext.startActivityAsUser(sharingChooserIntent, UserHandle.CURRENT);
+ mContext.startActivityAsUser(intent, UserHandle.CURRENT);
}
private void doShare(Uri uri) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/png");
intent.setData(uri);
- intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK
+ | Intent.FLAG_GRANT_READ_URI_PERMISSION);
Intent sharingChooserIntent = Intent.createChooser(intent, null)
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK)
- .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_GRANT_READ_URI_PERMISSION);
mContext.startActivityAsUser(sharingChooserIntent, UserHandle.CURRENT);
}