Quiet down long screenshots logcat output
With this change, a long screen shot flow generates only
the following log entries:
D Screenshot: ScrollCapture: connected to window [com.example/.ExampleActivity]
D Screenshot: onCaptureStarted
D Screenshot: end()
I Screenshot: Completed: LongScreenshot{w=1080, h=5339}
Tags covered:
LongScreenshotActivity
Screenshot
ScrollCaptureConnection
ScrollCaptureInternal
ScrollCaptureViewSupport
ScrollCaptureController
ViewRenderer
Bug: 190399332
Test: observe logcat during long screenshot
Change-Id: Ia2b018224897ad1ca153967ff9f60340a64f4815
This commit is contained in:
@@ -16,11 +16,6 @@
|
||||
|
||||
package com.android.internal.view;
|
||||
|
||||
import static com.android.internal.view.ScrollCaptureViewSupport.computeScrollAmount;
|
||||
import static com.android.internal.view.ScrollCaptureViewSupport.findScrollingReferenceView;
|
||||
import static com.android.internal.view.ScrollCaptureViewSupport.transformFromContainerToRequest;
|
||||
import static com.android.internal.view.ScrollCaptureViewSupport.transformFromRequestToContainer;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.graphics.Rect;
|
||||
import android.util.Log;
|
||||
@@ -43,6 +38,7 @@ import android.view.ViewParent;
|
||||
*/
|
||||
public class RecyclerViewCaptureHelper implements ScrollCaptureViewHelper<ViewGroup> {
|
||||
private static final String TAG = "RVCaptureHelper";
|
||||
|
||||
private int mScrollDelta;
|
||||
private boolean mScrollBarWasEnabled;
|
||||
private int mOverScrollMode;
|
||||
@@ -66,7 +62,6 @@ public class RecyclerViewCaptureHelper implements ScrollCaptureViewHelper<ViewGr
|
||||
result.scrollDelta = mScrollDelta;
|
||||
result.availableArea = new Rect(); // empty
|
||||
|
||||
Log.d(TAG, "current scrollDelta: " + mScrollDelta);
|
||||
if (!recyclerView.isVisibleToUser() || recyclerView.getChildCount() == 0) {
|
||||
Log.w(TAG, "recyclerView is empty or not visible, cannot continue");
|
||||
return result; // result.availableArea == empty Rect
|
||||
@@ -76,22 +71,18 @@ public class RecyclerViewCaptureHelper implements ScrollCaptureViewHelper<ViewGr
|
||||
Rect requestedContainerBounds = new Rect(requestRect);
|
||||
requestedContainerBounds.offset(0, -mScrollDelta);
|
||||
requestedContainerBounds.offset(scrollBounds.left, scrollBounds.top);
|
||||
|
||||
// requestedContainerBounds is now in recyclerview-local coordinates
|
||||
Log.d(TAG, "requestedContainerBounds: " + requestedContainerBounds);
|
||||
|
||||
// Save a copy for later
|
||||
View anchor = findChildNearestTarget(recyclerView, requestedContainerBounds);
|
||||
if (anchor == null) {
|
||||
Log.d(TAG, "Failed to locate anchor view");
|
||||
return result; // result.availableArea == null
|
||||
Log.w(TAG, "Failed to locate anchor view");
|
||||
return result; // result.availableArea == empty rect
|
||||
}
|
||||
|
||||
Log.d(TAG, "Anchor view:" + anchor);
|
||||
Rect requestedContentBounds = new Rect(requestedContainerBounds);
|
||||
recyclerView.offsetRectIntoDescendantCoords(anchor, requestedContentBounds);
|
||||
|
||||
Log.d(TAG, "requestedContentBounds = " + requestedContentBounds);
|
||||
int prevAnchorTop = anchor.getTop();
|
||||
// Note: requestChildRectangleOnScreen may modify rectangle, must pass pass in a copy here
|
||||
Rect input = new Rect(requestedContentBounds);
|
||||
@@ -101,34 +92,27 @@ public class RecyclerViewCaptureHelper implements ScrollCaptureViewHelper<ViewGr
|
||||
if (remainingHeight > 0) {
|
||||
input.inset(0, -remainingHeight / 2);
|
||||
}
|
||||
Log.d(TAG, "input (post center adjustment) = " + input);
|
||||
|
||||
if (recyclerView.requestChildRectangleOnScreen(anchor, input, true)) {
|
||||
int scrolled = prevAnchorTop - anchor.getTop(); // inverse of movement
|
||||
Log.d(TAG, "RecyclerView scrolled by " + scrolled + " px");
|
||||
mScrollDelta += scrolled; // view.top-- is equivalent to parent.scrollY++
|
||||
result.scrollDelta = mScrollDelta;
|
||||
Log.d(TAG, "requestedContentBounds, (post-request-rect) = " + requestedContentBounds);
|
||||
}
|
||||
|
||||
requestedContainerBounds.set(requestedContentBounds);
|
||||
recyclerView.offsetDescendantRectToMyCoords(anchor, requestedContainerBounds);
|
||||
Log.d(TAG, "requestedContainerBounds, (post-scroll): " + requestedContainerBounds);
|
||||
|
||||
Rect recyclerLocalVisible = new Rect(scrollBounds);
|
||||
recyclerView.getLocalVisibleRect(recyclerLocalVisible);
|
||||
Log.d(TAG, "recyclerLocalVisible: " + recyclerLocalVisible);
|
||||
|
||||
if (!requestedContainerBounds.intersect(recyclerLocalVisible)) {
|
||||
// Requested area is still not visible
|
||||
Log.d(TAG, "requested bounds not visible!");
|
||||
return result;
|
||||
}
|
||||
Rect available = new Rect(requestedContainerBounds);
|
||||
available.offset(-scrollBounds.left, -scrollBounds.top);
|
||||
available.offset(0, mScrollDelta);
|
||||
result.availableArea = available;
|
||||
Log.d(TAG, "availableArea: " + result.availableArea);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -154,22 +138,17 @@ public class RecyclerViewCaptureHelper implements ScrollCaptureViewHelper<ViewGr
|
||||
|
||||
Rect parentLocalVis = new Rect();
|
||||
parent.getLocalVisibleRect(parentLocalVis);
|
||||
Log.d(TAG, "findChildNearestTarget: parentVis=" + parentLocalVis
|
||||
+ " targetRect=" + targetRect);
|
||||
|
||||
Rect frame = new Rect();
|
||||
for (int i = 0; i < parent.getChildCount(); i++) {
|
||||
final View child = parent.getChildAt(i);
|
||||
child.getHitRect(frame);
|
||||
Log.d(TAG, "child #" + i + " hitRect=" + frame);
|
||||
|
||||
if (child.getVisibility() != View.VISIBLE) {
|
||||
Log.d(TAG, "child #" + i + " is not visible");
|
||||
continue;
|
||||
}
|
||||
|
||||
int centerDistance = Math.abs(targetRect.centerY() - frame.centerY());
|
||||
Log.d(TAG, "child #" + i + " : center to center: " + centerDistance + "px");
|
||||
|
||||
if (centerDistance < minCenterDistance) {
|
||||
// closer to center
|
||||
|
||||
@@ -34,7 +34,7 @@ public class ScrollCaptureInternal {
|
||||
private static final String TAG = "ScrollCaptureInternal";
|
||||
|
||||
// Log found scrolling views
|
||||
private static final boolean DEBUG = true;
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
// Log all investigated views, as well as heuristic checks
|
||||
private static final boolean DEBUG_VERBOSE = false;
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.graphics.Region;
|
||||
import android.graphics.RenderNode;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
@@ -140,7 +139,6 @@ class ImageTileSet {
|
||||
* getHeight()).
|
||||
*/
|
||||
Bitmap toBitmap(Rect bounds) {
|
||||
Log.d(TAG, "exporting with bounds: " + bounds);
|
||||
if (mTiles.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ import javax.inject.Inject;
|
||||
* and bottom before saving/sharing/editing.
|
||||
*/
|
||||
public class LongScreenshotActivity extends Activity {
|
||||
private static final String TAG = "LongScreenshotActivity";
|
||||
private static final String TAG = LogConfig.logTag(LongScreenshotActivity.class);
|
||||
|
||||
public static final String EXTRA_CAPTURE_RESPONSE = "capture-response";
|
||||
private static final String KEY_SAVED_IMAGE_PATH = "saved-image-path";
|
||||
@@ -113,7 +113,6 @@ public class LongScreenshotActivity extends Activity {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
Log.d(TAG, "onCreate(savedInstanceState = " + savedInstanceState + ")");
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.long_screenshot);
|
||||
|
||||
@@ -161,7 +160,6 @@ public class LongScreenshotActivity extends Activity {
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
Log.d(TAG, "onStart");
|
||||
super.onStart();
|
||||
|
||||
if (mCacheLoadFuture != null) {
|
||||
@@ -194,7 +192,7 @@ public class LongScreenshotActivity extends Activity {
|
||||
}
|
||||
|
||||
private void onLongScreenshotReceived(LongScreenshot longScreenshot) {
|
||||
Log.d(TAG, "onLongScreenshotReceived(longScreenshot=" + longScreenshot + ")");
|
||||
Log.i(TAG, "Completed: " + longScreenshot);
|
||||
mLongScreenshot = longScreenshot;
|
||||
Drawable drawable = mLongScreenshot.getDrawable();
|
||||
mPreview.setImageDrawable(drawable);
|
||||
@@ -249,7 +247,6 @@ public class LongScreenshotActivity extends Activity {
|
||||
}
|
||||
|
||||
private void onCachedImageLoaded(ImageLoader.Result imageResult) {
|
||||
Log.d(TAG, "onCachedImageLoaded(imageResult=" + imageResult + ")");
|
||||
BitmapDrawable drawable = new BitmapDrawable(getResources(), imageResult.bitmap);
|
||||
mPreview.setImageDrawable(drawable);
|
||||
mPreview.setAlpha(1f);
|
||||
@@ -274,22 +271,14 @@ public class LongScreenshotActivity extends Activity {
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
Log.d(TAG, "onSaveInstanceState");
|
||||
super.onSaveInstanceState(outState);
|
||||
if (mSavedImagePath != null) {
|
||||
outState.putString(KEY_SAVED_IMAGE_PATH, mSavedImagePath.getPath());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
Log.d(TAG, "onPause");
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
Log.d(TAG, "onStop finishing=" + isFinishing());
|
||||
super.onStop();
|
||||
if (mTransitionStarted) {
|
||||
finish();
|
||||
@@ -311,19 +300,12 @@ public class LongScreenshotActivity extends Activity {
|
||||
mCacheSaveFuture.cancel(true);
|
||||
}
|
||||
if (mSavedImagePath != null) {
|
||||
Log.d(TAG, "Deleting " + mSavedImagePath);
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
mSavedImagePath.delete();
|
||||
mSavedImagePath = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
Log.d(TAG, "onDestroy");
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
private void setButtonsEnabled(boolean enabled) {
|
||||
mSave.setEnabled(enabled);
|
||||
mEdit.setEnabled(enabled);
|
||||
@@ -392,7 +374,6 @@ public class LongScreenshotActivity extends Activity {
|
||||
}
|
||||
|
||||
private void startExport(PendingAction action) {
|
||||
Log.d(TAG, "startExport(action = " + action + ")");
|
||||
Drawable drawable = mPreview.getDrawable();
|
||||
if (drawable == null) {
|
||||
Log.e(TAG, "No drawable, skipping export!");
|
||||
|
||||
@@ -43,7 +43,7 @@ import javax.inject.Inject;
|
||||
* Interaction controller between the UI and ScrollCaptureClient.
|
||||
*/
|
||||
public class ScrollCaptureController {
|
||||
private static final String TAG = "ScrollCaptureController";
|
||||
private static final String TAG = LogConfig.logTag(ScrollCaptureController.class);
|
||||
private static final float MAX_PAGES_DEFAULT = 3f;
|
||||
|
||||
private static final String SETTING_KEY_MAX_PAGES = "screenshot.scroll_max_pages";
|
||||
@@ -90,7 +90,9 @@ public class ScrollCaptureController {
|
||||
|
||||
/** Releases image resources from the screenshot. */
|
||||
public void release() {
|
||||
Log.d(TAG, "LongScreenshot :: release()");
|
||||
if (LogConfig.DEBUG_SCROLL) {
|
||||
Log.d(TAG, "LongScreenshot :: release()");
|
||||
}
|
||||
mImageTileSet.clear();
|
||||
mSession.release();
|
||||
}
|
||||
@@ -153,15 +155,11 @@ public class ScrollCaptureController {
|
||||
* @return a future ImageTile set containing the result
|
||||
*/
|
||||
ListenableFuture<LongScreenshot> run(ScrollCaptureResponse response) {
|
||||
Log.d(TAG, "run: " + response);
|
||||
return CallbackToFutureAdapter.getFuture(completer -> {
|
||||
Log.d(TAG, "getFuture(ImageTileSet) ");
|
||||
mCaptureCompleter = completer;
|
||||
mBgExecutor.execute(() -> {
|
||||
Log.d(TAG, "bgExecutor.execute");
|
||||
float maxPages = Settings.Secure.getFloat(mContext.getContentResolver(),
|
||||
SETTING_KEY_MAX_PAGES, MAX_PAGES_DEFAULT);
|
||||
Log.d(TAG, "client start, maxPages=" + maxPages);
|
||||
mSessionFuture = mClient.start(response, maxPages);
|
||||
mSessionFuture.addListener(this::onStartComplete, mContext.getMainExecutor());
|
||||
});
|
||||
@@ -172,21 +170,27 @@ public class ScrollCaptureController {
|
||||
private void onStartComplete() {
|
||||
try {
|
||||
mSession = mSessionFuture.get();
|
||||
Log.d(TAG, "got session " + mSession);
|
||||
if (LogConfig.DEBUG_SCROLL) {
|
||||
Log.d(TAG, "got session " + mSession);
|
||||
}
|
||||
requestNextTile(0);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
// Failure to start, propagate to caller
|
||||
Log.d(TAG, "session start failed!");
|
||||
Log.e(TAG, "session start failed!");
|
||||
mCaptureCompleter.setException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void requestNextTile(int topPx) {
|
||||
Log.d(TAG, "requestNextTile: " + topPx);
|
||||
if (LogConfig.DEBUG_SCROLL) {
|
||||
Log.d(TAG, "requestNextTile: " + topPx);
|
||||
}
|
||||
mTileFuture = mSession.requestTile(topPx);
|
||||
mTileFuture.addListener(() -> {
|
||||
try {
|
||||
Log.d(TAG, "onCaptureResult");
|
||||
if (LogConfig.DEBUG_SCROLL) {
|
||||
Log.d(TAG, "onCaptureResult");
|
||||
}
|
||||
onCaptureResult(mTileFuture.get());
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
Log.e(TAG, "requestTile failed!", e);
|
||||
@@ -196,14 +200,18 @@ public class ScrollCaptureController {
|
||||
}
|
||||
|
||||
private void onCaptureResult(CaptureResult result) {
|
||||
Log.d(TAG, "onCaptureResult: " + result + " scrolling " + (mScrollingUp ? "UP" : "DOWN")
|
||||
+ " finish on boundary: " + mFinishOnBoundary);
|
||||
if (LogConfig.DEBUG_SCROLL) {
|
||||
Log.d(TAG, "onCaptureResult: " + result + " scrolling " + (mScrollingUp ? "UP" : "DOWN")
|
||||
+ " finish on boundary: " + mFinishOnBoundary);
|
||||
}
|
||||
boolean emptyResult = result.captured.height() == 0;
|
||||
|
||||
if (emptyResult) {
|
||||
// Potentially reached a vertical boundary. Extend in the other direction.
|
||||
if (mFinishOnBoundary) {
|
||||
Log.d(TAG, "Empty: finished!");
|
||||
if (LogConfig.DEBUG_SCROLL) {
|
||||
Log.d(TAG, "Empty: finished!");
|
||||
}
|
||||
finishCapture();
|
||||
return;
|
||||
} else {
|
||||
@@ -212,13 +220,17 @@ public class ScrollCaptureController {
|
||||
mImageTileSet.clear();
|
||||
mFinishOnBoundary = true;
|
||||
mScrollingUp = !mScrollingUp;
|
||||
Log.d(TAG, "Empty: cleared, switch direction to finish");
|
||||
if (LogConfig.DEBUG_SCROLL) {
|
||||
Log.d(TAG, "Empty: cleared, switch direction to finish");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Got a non-empty result, but may already have enough bitmap data now
|
||||
int expectedTiles = mImageTileSet.size() + 1;
|
||||
if (expectedTiles >= mSession.getMaxTiles()) {
|
||||
Log.d(TAG, "Hit max tiles: finished");
|
||||
if (LogConfig.DEBUG_SCROLL) {
|
||||
Log.d(TAG, "Hit max tiles: finished");
|
||||
}
|
||||
// If we ever hit the max tiles, we've got enough bitmap data to finish
|
||||
// (even if we weren't sure we'd finish on this pass).
|
||||
finishCapture();
|
||||
@@ -229,7 +241,9 @@ public class ScrollCaptureController {
|
||||
// by IDEAL_PORTION_ABOVE.
|
||||
if (mImageTileSet.getHeight() + result.captured.height()
|
||||
>= mSession.getTargetHeight() * IDEAL_PORTION_ABOVE) {
|
||||
Log.d(TAG, "Hit ideal portion above: clear and switch direction");
|
||||
if (LogConfig.DEBUG_SCROLL) {
|
||||
Log.d(TAG, "Hit ideal portion above: clear and switch direction");
|
||||
}
|
||||
// We got enough above the start point, now see how far down it can go.
|
||||
mImageTileSet.clear();
|
||||
mScrollingUp = false;
|
||||
@@ -241,20 +255,25 @@ public class ScrollCaptureController {
|
||||
if (!emptyResult) {
|
||||
mImageTileSet.addTile(new ImageTile(result.image, result.captured));
|
||||
}
|
||||
|
||||
Log.d(TAG, "bounds: " + mImageTileSet.getLeft() + "," + mImageTileSet.getTop()
|
||||
+ " - " + mImageTileSet.getRight() + "," + mImageTileSet.getBottom()
|
||||
+ " (" + mImageTileSet.getWidth() + "x" + mImageTileSet.getHeight() + ")");
|
||||
if (LogConfig.DEBUG_SCROLL) {
|
||||
Log.d(TAG, "bounds: " + mImageTileSet.getLeft() + "," + mImageTileSet.getTop()
|
||||
+ " - " + mImageTileSet.getRight() + "," + mImageTileSet.getBottom()
|
||||
+ " (" + mImageTileSet.getWidth() + "x" + mImageTileSet.getHeight() + ")");
|
||||
}
|
||||
|
||||
Rect gapBounds = mImageTileSet.getGaps();
|
||||
if (!gapBounds.isEmpty()) {
|
||||
Log.d(TAG, "Found gaps in tileset: " + gapBounds + ", requesting " + gapBounds.top);
|
||||
if (LogConfig.DEBUG_SCROLL) {
|
||||
Log.d(TAG, "Found gaps in tileset: " + gapBounds + ", requesting " + gapBounds.top);
|
||||
}
|
||||
requestNextTile(gapBounds.top);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mImageTileSet.getHeight() >= mSession.getTargetHeight()) {
|
||||
Log.d(TAG, "Target height reached.");
|
||||
if (LogConfig.DEBUG_SCROLL) {
|
||||
Log.d(TAG, "Target height reached.");
|
||||
}
|
||||
finishCapture();
|
||||
return;
|
||||
}
|
||||
@@ -275,10 +294,14 @@ public class ScrollCaptureController {
|
||||
}
|
||||
|
||||
private void finishCapture() {
|
||||
Log.d(TAG, "finishCapture()");
|
||||
if (LogConfig.DEBUG_SCROLL) {
|
||||
Log.d(TAG, "finishCapture()");
|
||||
}
|
||||
mEndFuture = mSession.end();
|
||||
mEndFuture.addListener(() -> {
|
||||
Log.d(TAG, "endCapture completed");
|
||||
if (LogConfig.DEBUG_SCROLL) {
|
||||
Log.d(TAG, "endCapture completed");
|
||||
}
|
||||
// Provide result to caller and complete the top-level future
|
||||
// Caller is responsible for releasing this resource (ImageReader/HardwareBuffers)
|
||||
mCaptureCompleter.set(new LongScreenshot(mSession, mImageTileSet));
|
||||
|
||||
Reference in New Issue
Block a user