Merge "Quiet down long screenshots logcat output" into sc-dev

This commit is contained in:
Mark Renouf
2021-07-09 15:29:18 +00:00
committed by Android (Google) Code Review
5 changed files with 53 additions and 72 deletions

View File

@@ -16,11 +16,6 @@
package com.android.internal.view; 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.annotation.NonNull;
import android.graphics.Rect; import android.graphics.Rect;
import android.util.Log; import android.util.Log;
@@ -43,6 +38,7 @@ import android.view.ViewParent;
*/ */
public class RecyclerViewCaptureHelper implements ScrollCaptureViewHelper<ViewGroup> { public class RecyclerViewCaptureHelper implements ScrollCaptureViewHelper<ViewGroup> {
private static final String TAG = "RVCaptureHelper"; private static final String TAG = "RVCaptureHelper";
private int mScrollDelta; private int mScrollDelta;
private boolean mScrollBarWasEnabled; private boolean mScrollBarWasEnabled;
private int mOverScrollMode; private int mOverScrollMode;
@@ -66,7 +62,6 @@ public class RecyclerViewCaptureHelper implements ScrollCaptureViewHelper<ViewGr
result.scrollDelta = mScrollDelta; result.scrollDelta = mScrollDelta;
result.availableArea = new Rect(); // empty result.availableArea = new Rect(); // empty
Log.d(TAG, "current scrollDelta: " + mScrollDelta);
if (!recyclerView.isVisibleToUser() || recyclerView.getChildCount() == 0) { if (!recyclerView.isVisibleToUser() || recyclerView.getChildCount() == 0) {
Log.w(TAG, "recyclerView is empty or not visible, cannot continue"); Log.w(TAG, "recyclerView is empty or not visible, cannot continue");
return result; // result.availableArea == empty Rect return result; // result.availableArea == empty Rect
@@ -76,22 +71,18 @@ public class RecyclerViewCaptureHelper implements ScrollCaptureViewHelper<ViewGr
Rect requestedContainerBounds = new Rect(requestRect); Rect requestedContainerBounds = new Rect(requestRect);
requestedContainerBounds.offset(0, -mScrollDelta); requestedContainerBounds.offset(0, -mScrollDelta);
requestedContainerBounds.offset(scrollBounds.left, scrollBounds.top); requestedContainerBounds.offset(scrollBounds.left, scrollBounds.top);
// requestedContainerBounds is now in recyclerview-local coordinates // requestedContainerBounds is now in recyclerview-local coordinates
Log.d(TAG, "requestedContainerBounds: " + requestedContainerBounds);
// Save a copy for later // Save a copy for later
View anchor = findChildNearestTarget(recyclerView, requestedContainerBounds); View anchor = findChildNearestTarget(recyclerView, requestedContainerBounds);
if (anchor == null) { if (anchor == null) {
Log.d(TAG, "Failed to locate anchor view"); Log.w(TAG, "Failed to locate anchor view");
return result; // result.availableArea == null return result; // result.availableArea == empty rect
} }
Log.d(TAG, "Anchor view:" + anchor);
Rect requestedContentBounds = new Rect(requestedContainerBounds); Rect requestedContentBounds = new Rect(requestedContainerBounds);
recyclerView.offsetRectIntoDescendantCoords(anchor, requestedContentBounds); recyclerView.offsetRectIntoDescendantCoords(anchor, requestedContentBounds);
Log.d(TAG, "requestedContentBounds = " + requestedContentBounds);
int prevAnchorTop = anchor.getTop(); int prevAnchorTop = anchor.getTop();
// Note: requestChildRectangleOnScreen may modify rectangle, must pass pass in a copy here // Note: requestChildRectangleOnScreen may modify rectangle, must pass pass in a copy here
Rect input = new Rect(requestedContentBounds); Rect input = new Rect(requestedContentBounds);
@@ -101,34 +92,27 @@ public class RecyclerViewCaptureHelper implements ScrollCaptureViewHelper<ViewGr
if (remainingHeight > 0) { if (remainingHeight > 0) {
input.inset(0, -remainingHeight / 2); input.inset(0, -remainingHeight / 2);
} }
Log.d(TAG, "input (post center adjustment) = " + input);
if (recyclerView.requestChildRectangleOnScreen(anchor, input, true)) { if (recyclerView.requestChildRectangleOnScreen(anchor, input, true)) {
int scrolled = prevAnchorTop - anchor.getTop(); // inverse of movement 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++ mScrollDelta += scrolled; // view.top-- is equivalent to parent.scrollY++
result.scrollDelta = mScrollDelta; result.scrollDelta = mScrollDelta;
Log.d(TAG, "requestedContentBounds, (post-request-rect) = " + requestedContentBounds);
} }
requestedContainerBounds.set(requestedContentBounds); requestedContainerBounds.set(requestedContentBounds);
recyclerView.offsetDescendantRectToMyCoords(anchor, requestedContainerBounds); recyclerView.offsetDescendantRectToMyCoords(anchor, requestedContainerBounds);
Log.d(TAG, "requestedContainerBounds, (post-scroll): " + requestedContainerBounds);
Rect recyclerLocalVisible = new Rect(scrollBounds); Rect recyclerLocalVisible = new Rect(scrollBounds);
recyclerView.getLocalVisibleRect(recyclerLocalVisible); recyclerView.getLocalVisibleRect(recyclerLocalVisible);
Log.d(TAG, "recyclerLocalVisible: " + recyclerLocalVisible);
if (!requestedContainerBounds.intersect(recyclerLocalVisible)) { if (!requestedContainerBounds.intersect(recyclerLocalVisible)) {
// Requested area is still not visible // Requested area is still not visible
Log.d(TAG, "requested bounds not visible!");
return result; return result;
} }
Rect available = new Rect(requestedContainerBounds); Rect available = new Rect(requestedContainerBounds);
available.offset(-scrollBounds.left, -scrollBounds.top); available.offset(-scrollBounds.left, -scrollBounds.top);
available.offset(0, mScrollDelta); available.offset(0, mScrollDelta);
result.availableArea = available; result.availableArea = available;
Log.d(TAG, "availableArea: " + result.availableArea);
return result; return result;
} }
@@ -154,22 +138,17 @@ public class RecyclerViewCaptureHelper implements ScrollCaptureViewHelper<ViewGr
Rect parentLocalVis = new Rect(); Rect parentLocalVis = new Rect();
parent.getLocalVisibleRect(parentLocalVis); parent.getLocalVisibleRect(parentLocalVis);
Log.d(TAG, "findChildNearestTarget: parentVis=" + parentLocalVis
+ " targetRect=" + targetRect);
Rect frame = new Rect(); Rect frame = new Rect();
for (int i = 0; i < parent.getChildCount(); i++) { for (int i = 0; i < parent.getChildCount(); i++) {
final View child = parent.getChildAt(i); final View child = parent.getChildAt(i);
child.getHitRect(frame); child.getHitRect(frame);
Log.d(TAG, "child #" + i + " hitRect=" + frame);
if (child.getVisibility() != View.VISIBLE) { if (child.getVisibility() != View.VISIBLE) {
Log.d(TAG, "child #" + i + " is not visible");
continue; continue;
} }
int centerDistance = Math.abs(targetRect.centerY() - frame.centerY()); int centerDistance = Math.abs(targetRect.centerY() - frame.centerY());
Log.d(TAG, "child #" + i + " : center to center: " + centerDistance + "px");
if (centerDistance < minCenterDistance) { if (centerDistance < minCenterDistance) {
// closer to center // closer to center

View File

@@ -34,7 +34,7 @@ public class ScrollCaptureInternal {
private static final String TAG = "ScrollCaptureInternal"; private static final String TAG = "ScrollCaptureInternal";
// Log found scrolling views // 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 // Log all investigated views, as well as heuristic checks
private static final boolean DEBUG_VERBOSE = false; private static final boolean DEBUG_VERBOSE = false;

View File

@@ -24,7 +24,6 @@ import android.graphics.Region;
import android.graphics.RenderNode; import android.graphics.RenderNode;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Handler; import android.os.Handler;
import android.util.Log;
import androidx.annotation.UiThread; import androidx.annotation.UiThread;
@@ -140,7 +139,6 @@ class ImageTileSet {
* getHeight()). * getHeight()).
*/ */
Bitmap toBitmap(Rect bounds) { Bitmap toBitmap(Rect bounds) {
Log.d(TAG, "exporting with bounds: " + bounds);
if (mTiles.isEmpty()) { if (mTiles.isEmpty()) {
return null; return null;
} }

View File

@@ -63,7 +63,7 @@ import javax.inject.Inject;
* and bottom before saving/sharing/editing. * and bottom before saving/sharing/editing.
*/ */
public class LongScreenshotActivity extends Activity { 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"; public static final String EXTRA_CAPTURE_RESPONSE = "capture-response";
private static final String KEY_SAVED_IMAGE_PATH = "saved-image-path"; private static final String KEY_SAVED_IMAGE_PATH = "saved-image-path";
@@ -113,7 +113,6 @@ public class LongScreenshotActivity extends Activity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate(savedInstanceState = " + savedInstanceState + ")");
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.long_screenshot); setContentView(R.layout.long_screenshot);
@@ -161,7 +160,6 @@ public class LongScreenshotActivity extends Activity {
@Override @Override
public void onStart() { public void onStart() {
Log.d(TAG, "onStart");
super.onStart(); super.onStart();
if (mCacheLoadFuture != null) { if (mCacheLoadFuture != null) {
@@ -194,7 +192,7 @@ public class LongScreenshotActivity extends Activity {
} }
private void onLongScreenshotReceived(LongScreenshot longScreenshot) { private void onLongScreenshotReceived(LongScreenshot longScreenshot) {
Log.d(TAG, "onLongScreenshotReceived(longScreenshot=" + longScreenshot + ")"); Log.i(TAG, "Completed: " + longScreenshot);
mLongScreenshot = longScreenshot; mLongScreenshot = longScreenshot;
Drawable drawable = mLongScreenshot.getDrawable(); Drawable drawable = mLongScreenshot.getDrawable();
mPreview.setImageDrawable(drawable); mPreview.setImageDrawable(drawable);
@@ -249,7 +247,6 @@ public class LongScreenshotActivity extends Activity {
} }
private void onCachedImageLoaded(ImageLoader.Result imageResult) { private void onCachedImageLoaded(ImageLoader.Result imageResult) {
Log.d(TAG, "onCachedImageLoaded(imageResult=" + imageResult + ")");
BitmapDrawable drawable = new BitmapDrawable(getResources(), imageResult.bitmap); BitmapDrawable drawable = new BitmapDrawable(getResources(), imageResult.bitmap);
mPreview.setImageDrawable(drawable); mPreview.setImageDrawable(drawable);
mPreview.setAlpha(1f); mPreview.setAlpha(1f);
@@ -274,22 +271,14 @@ public class LongScreenshotActivity extends Activity {
@Override @Override
protected void onSaveInstanceState(Bundle outState) { protected void onSaveInstanceState(Bundle outState) {
Log.d(TAG, "onSaveInstanceState");
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
if (mSavedImagePath != null) { if (mSavedImagePath != null) {
outState.putString(KEY_SAVED_IMAGE_PATH, mSavedImagePath.getPath()); outState.putString(KEY_SAVED_IMAGE_PATH, mSavedImagePath.getPath());
} }
} }
@Override
protected void onPause() {
Log.d(TAG, "onPause");
super.onPause();
}
@Override @Override
protected void onStop() { protected void onStop() {
Log.d(TAG, "onStop finishing=" + isFinishing());
super.onStop(); super.onStop();
if (mTransitionStarted) { if (mTransitionStarted) {
finish(); finish();
@@ -311,19 +300,12 @@ public class LongScreenshotActivity extends Activity {
mCacheSaveFuture.cancel(true); mCacheSaveFuture.cancel(true);
} }
if (mSavedImagePath != null) { if (mSavedImagePath != null) {
Log.d(TAG, "Deleting " + mSavedImagePath);
//noinspection ResultOfMethodCallIgnored //noinspection ResultOfMethodCallIgnored
mSavedImagePath.delete(); mSavedImagePath.delete();
mSavedImagePath = null; mSavedImagePath = null;
} }
} }
@Override
protected void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
}
private void setButtonsEnabled(boolean enabled) { private void setButtonsEnabled(boolean enabled) {
mSave.setEnabled(enabled); mSave.setEnabled(enabled);
mEdit.setEnabled(enabled); mEdit.setEnabled(enabled);
@@ -392,7 +374,6 @@ public class LongScreenshotActivity extends Activity {
} }
private void startExport(PendingAction action) { private void startExport(PendingAction action) {
Log.d(TAG, "startExport(action = " + action + ")");
Drawable drawable = mPreview.getDrawable(); Drawable drawable = mPreview.getDrawable();
if (drawable == null) { if (drawable == null) {
Log.e(TAG, "No drawable, skipping export!"); Log.e(TAG, "No drawable, skipping export!");

View File

@@ -43,7 +43,7 @@ import javax.inject.Inject;
* Interaction controller between the UI and ScrollCaptureClient. * Interaction controller between the UI and ScrollCaptureClient.
*/ */
public class ScrollCaptureController { 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 float MAX_PAGES_DEFAULT = 3f;
private static final String SETTING_KEY_MAX_PAGES = "screenshot.scroll_max_pages"; 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. */ /** Releases image resources from the screenshot. */
public void release() { public void release() {
Log.d(TAG, "LongScreenshot :: release()"); if (LogConfig.DEBUG_SCROLL) {
Log.d(TAG, "LongScreenshot :: release()");
}
mImageTileSet.clear(); mImageTileSet.clear();
mSession.release(); mSession.release();
} }
@@ -153,15 +155,11 @@ public class ScrollCaptureController {
* @return a future ImageTile set containing the result * @return a future ImageTile set containing the result
*/ */
ListenableFuture<LongScreenshot> run(ScrollCaptureResponse response) { ListenableFuture<LongScreenshot> run(ScrollCaptureResponse response) {
Log.d(TAG, "run: " + response);
return CallbackToFutureAdapter.getFuture(completer -> { return CallbackToFutureAdapter.getFuture(completer -> {
Log.d(TAG, "getFuture(ImageTileSet) ");
mCaptureCompleter = completer; mCaptureCompleter = completer;
mBgExecutor.execute(() -> { mBgExecutor.execute(() -> {
Log.d(TAG, "bgExecutor.execute");
float maxPages = Settings.Secure.getFloat(mContext.getContentResolver(), float maxPages = Settings.Secure.getFloat(mContext.getContentResolver(),
SETTING_KEY_MAX_PAGES, MAX_PAGES_DEFAULT); SETTING_KEY_MAX_PAGES, MAX_PAGES_DEFAULT);
Log.d(TAG, "client start, maxPages=" + maxPages);
mSessionFuture = mClient.start(response, maxPages); mSessionFuture = mClient.start(response, maxPages);
mSessionFuture.addListener(this::onStartComplete, mContext.getMainExecutor()); mSessionFuture.addListener(this::onStartComplete, mContext.getMainExecutor());
}); });
@@ -172,21 +170,27 @@ public class ScrollCaptureController {
private void onStartComplete() { private void onStartComplete() {
try { try {
mSession = mSessionFuture.get(); mSession = mSessionFuture.get();
Log.d(TAG, "got session " + mSession); if (LogConfig.DEBUG_SCROLL) {
Log.d(TAG, "got session " + mSession);
}
requestNextTile(0); requestNextTile(0);
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
// Failure to start, propagate to caller // Failure to start, propagate to caller
Log.d(TAG, "session start failed!"); Log.e(TAG, "session start failed!");
mCaptureCompleter.setException(e); mCaptureCompleter.setException(e);
} }
} }
private void requestNextTile(int topPx) { private void requestNextTile(int topPx) {
Log.d(TAG, "requestNextTile: " + topPx); if (LogConfig.DEBUG_SCROLL) {
Log.d(TAG, "requestNextTile: " + topPx);
}
mTileFuture = mSession.requestTile(topPx); mTileFuture = mSession.requestTile(topPx);
mTileFuture.addListener(() -> { mTileFuture.addListener(() -> {
try { try {
Log.d(TAG, "onCaptureResult"); if (LogConfig.DEBUG_SCROLL) {
Log.d(TAG, "onCaptureResult");
}
onCaptureResult(mTileFuture.get()); onCaptureResult(mTileFuture.get());
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
Log.e(TAG, "requestTile failed!", e); Log.e(TAG, "requestTile failed!", e);
@@ -196,14 +200,18 @@ public class ScrollCaptureController {
} }
private void onCaptureResult(CaptureResult result) { private void onCaptureResult(CaptureResult result) {
Log.d(TAG, "onCaptureResult: " + result + " scrolling " + (mScrollingUp ? "UP" : "DOWN") if (LogConfig.DEBUG_SCROLL) {
+ " finish on boundary: " + mFinishOnBoundary); Log.d(TAG, "onCaptureResult: " + result + " scrolling " + (mScrollingUp ? "UP" : "DOWN")
+ " finish on boundary: " + mFinishOnBoundary);
}
boolean emptyResult = result.captured.height() == 0; boolean emptyResult = result.captured.height() == 0;
if (emptyResult) { if (emptyResult) {
// Potentially reached a vertical boundary. Extend in the other direction. // Potentially reached a vertical boundary. Extend in the other direction.
if (mFinishOnBoundary) { if (mFinishOnBoundary) {
Log.d(TAG, "Empty: finished!"); if (LogConfig.DEBUG_SCROLL) {
Log.d(TAG, "Empty: finished!");
}
finishCapture(); finishCapture();
return; return;
} else { } else {
@@ -212,13 +220,17 @@ public class ScrollCaptureController {
mImageTileSet.clear(); mImageTileSet.clear();
mFinishOnBoundary = true; mFinishOnBoundary = true;
mScrollingUp = !mScrollingUp; 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 { } else {
// Got a non-empty result, but may already have enough bitmap data now // Got a non-empty result, but may already have enough bitmap data now
int expectedTiles = mImageTileSet.size() + 1; int expectedTiles = mImageTileSet.size() + 1;
if (expectedTiles >= mSession.getMaxTiles()) { 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 // 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). // (even if we weren't sure we'd finish on this pass).
finishCapture(); finishCapture();
@@ -229,7 +241,9 @@ public class ScrollCaptureController {
// by IDEAL_PORTION_ABOVE. // by IDEAL_PORTION_ABOVE.
if (mImageTileSet.getHeight() + result.captured.height() if (mImageTileSet.getHeight() + result.captured.height()
>= mSession.getTargetHeight() * IDEAL_PORTION_ABOVE) { >= 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. // We got enough above the start point, now see how far down it can go.
mImageTileSet.clear(); mImageTileSet.clear();
mScrollingUp = false; mScrollingUp = false;
@@ -241,20 +255,25 @@ public class ScrollCaptureController {
if (!emptyResult) { if (!emptyResult) {
mImageTileSet.addTile(new ImageTile(result.image, result.captured)); mImageTileSet.addTile(new ImageTile(result.image, result.captured));
} }
if (LogConfig.DEBUG_SCROLL) {
Log.d(TAG, "bounds: " + mImageTileSet.getLeft() + "," + mImageTileSet.getTop() Log.d(TAG, "bounds: " + mImageTileSet.getLeft() + "," + mImageTileSet.getTop()
+ " - " + mImageTileSet.getRight() + "," + mImageTileSet.getBottom() + " - " + mImageTileSet.getRight() + "," + mImageTileSet.getBottom()
+ " (" + mImageTileSet.getWidth() + "x" + mImageTileSet.getHeight() + ")"); + " (" + mImageTileSet.getWidth() + "x" + mImageTileSet.getHeight() + ")");
}
Rect gapBounds = mImageTileSet.getGaps(); Rect gapBounds = mImageTileSet.getGaps();
if (!gapBounds.isEmpty()) { 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); requestNextTile(gapBounds.top);
return; return;
} }
if (mImageTileSet.getHeight() >= mSession.getTargetHeight()) { if (mImageTileSet.getHeight() >= mSession.getTargetHeight()) {
Log.d(TAG, "Target height reached."); if (LogConfig.DEBUG_SCROLL) {
Log.d(TAG, "Target height reached.");
}
finishCapture(); finishCapture();
return; return;
} }
@@ -275,10 +294,14 @@ public class ScrollCaptureController {
} }
private void finishCapture() { private void finishCapture() {
Log.d(TAG, "finishCapture()"); if (LogConfig.DEBUG_SCROLL) {
Log.d(TAG, "finishCapture()");
}
mEndFuture = mSession.end(); mEndFuture = mSession.end();
mEndFuture.addListener(() -> { 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 // Provide result to caller and complete the top-level future
// Caller is responsible for releasing this resource (ImageReader/HardwareBuffers) // Caller is responsible for releasing this resource (ImageReader/HardwareBuffers)
mCaptureCompleter.set(new LongScreenshot(mSession, mImageTileSet)); mCaptureCompleter.set(new LongScreenshot(mSession, mImageTileSet));