Loading core/java/com/android/internal/view/RecyclerViewCaptureHelper.java +3 −24 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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 Loading @@ -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); Loading @@ -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; } Loading @@ -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 Loading core/java/com/android/internal/view/ScrollCaptureInternal.java +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading packages/SystemUI/src/com/android/systemui/screenshot/ImageTileSet.java +0 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -140,7 +139,6 @@ class ImageTileSet { * getHeight()). */ Bitmap toBitmap(Rect bounds) { Log.d(TAG, "exporting with bounds: " + bounds); if (mTiles.isEmpty()) { return null; } Loading packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java +2 −21 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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); Loading Loading @@ -161,7 +160,6 @@ public class LongScreenshotActivity extends Activity { @Override public void onStart() { Log.d(TAG, "onStart"); super.onStart(); if (mCacheLoadFuture != null) { Loading Loading @@ -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); Loading Loading @@ -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); Loading @@ -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(); Loading @@ -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); Loading Loading @@ -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!"); Loading packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java +47 −24 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -90,7 +90,9 @@ public class ScrollCaptureController { /** Releases image resources from the screenshot. */ public void release() { if (LogConfig.DEBUG_SCROLL) { Log.d(TAG, "LongScreenshot :: release()"); } mImageTileSet.clear(); mSession.release(); } Loading Loading @@ -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()); }); Loading @@ -172,21 +170,27 @@ public class ScrollCaptureController { private void onStartComplete() { try { mSession = mSessionFuture.get(); 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) { if (LogConfig.DEBUG_SCROLL) { Log.d(TAG, "requestNextTile: " + topPx); } mTileFuture = mSession.requestTile(topPx); mTileFuture.addListener(() -> { try { if (LogConfig.DEBUG_SCROLL) { Log.d(TAG, "onCaptureResult"); } onCaptureResult(mTileFuture.get()); } catch (InterruptedException | ExecutionException e) { Log.e(TAG, "requestTile failed!", e); Loading @@ -196,14 +200,18 @@ public class ScrollCaptureController { } private void onCaptureResult(CaptureResult result) { 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) { if (LogConfig.DEBUG_SCROLL) { Log.d(TAG, "Empty: finished!"); } finishCapture(); return; } else { Loading @@ -212,13 +220,17 @@ public class ScrollCaptureController { mImageTileSet.clear(); mFinishOnBoundary = true; mScrollingUp = !mScrollingUp; 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()) { 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(); Loading @@ -229,7 +241,9 @@ public class ScrollCaptureController { // by IDEAL_PORTION_ABOVE. if (mImageTileSet.getHeight() + result.captured.height() >= mSession.getTargetHeight() * IDEAL_PORTION_ABOVE) { 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; Loading @@ -241,20 +255,25 @@ public class ScrollCaptureController { if (!emptyResult) { mImageTileSet.addTile(new ImageTile(result.image, result.captured)); } 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()) { if (LogConfig.DEBUG_SCROLL) { Log.d(TAG, "Found gaps in tileset: " + gapBounds + ", requesting " + gapBounds.top); } requestNextTile(gapBounds.top); return; } if (mImageTileSet.getHeight() >= mSession.getTargetHeight()) { if (LogConfig.DEBUG_SCROLL) { Log.d(TAG, "Target height reached."); } finishCapture(); return; } Loading @@ -275,10 +294,14 @@ public class ScrollCaptureController { } private void finishCapture() { if (LogConfig.DEBUG_SCROLL) { Log.d(TAG, "finishCapture()"); } mEndFuture = mSession.end(); mEndFuture.addListener(() -> { 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)); Loading Loading
core/java/com/android/internal/view/RecyclerViewCaptureHelper.java +3 −24 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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 Loading @@ -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); Loading @@ -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; } Loading @@ -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 Loading
core/java/com/android/internal/view/ScrollCaptureInternal.java +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading
packages/SystemUI/src/com/android/systemui/screenshot/ImageTileSet.java +0 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -140,7 +139,6 @@ class ImageTileSet { * getHeight()). */ Bitmap toBitmap(Rect bounds) { Log.d(TAG, "exporting with bounds: " + bounds); if (mTiles.isEmpty()) { return null; } Loading
packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java +2 −21 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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); Loading Loading @@ -161,7 +160,6 @@ public class LongScreenshotActivity extends Activity { @Override public void onStart() { Log.d(TAG, "onStart"); super.onStart(); if (mCacheLoadFuture != null) { Loading Loading @@ -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); Loading Loading @@ -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); Loading @@ -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(); Loading @@ -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); Loading Loading @@ -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!"); Loading
packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java +47 −24 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -90,7 +90,9 @@ public class ScrollCaptureController { /** Releases image resources from the screenshot. */ public void release() { if (LogConfig.DEBUG_SCROLL) { Log.d(TAG, "LongScreenshot :: release()"); } mImageTileSet.clear(); mSession.release(); } Loading Loading @@ -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()); }); Loading @@ -172,21 +170,27 @@ public class ScrollCaptureController { private void onStartComplete() { try { mSession = mSessionFuture.get(); 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) { if (LogConfig.DEBUG_SCROLL) { Log.d(TAG, "requestNextTile: " + topPx); } mTileFuture = mSession.requestTile(topPx); mTileFuture.addListener(() -> { try { if (LogConfig.DEBUG_SCROLL) { Log.d(TAG, "onCaptureResult"); } onCaptureResult(mTileFuture.get()); } catch (InterruptedException | ExecutionException e) { Log.e(TAG, "requestTile failed!", e); Loading @@ -196,14 +200,18 @@ public class ScrollCaptureController { } private void onCaptureResult(CaptureResult result) { 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) { if (LogConfig.DEBUG_SCROLL) { Log.d(TAG, "Empty: finished!"); } finishCapture(); return; } else { Loading @@ -212,13 +220,17 @@ public class ScrollCaptureController { mImageTileSet.clear(); mFinishOnBoundary = true; mScrollingUp = !mScrollingUp; 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()) { 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(); Loading @@ -229,7 +241,9 @@ public class ScrollCaptureController { // by IDEAL_PORTION_ABOVE. if (mImageTileSet.getHeight() + result.captured.height() >= mSession.getTargetHeight() * IDEAL_PORTION_ABOVE) { 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; Loading @@ -241,20 +255,25 @@ public class ScrollCaptureController { if (!emptyResult) { mImageTileSet.addTile(new ImageTile(result.image, result.captured)); } 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()) { if (LogConfig.DEBUG_SCROLL) { Log.d(TAG, "Found gaps in tileset: " + gapBounds + ", requesting " + gapBounds.top); } requestNextTile(gapBounds.top); return; } if (mImageTileSet.getHeight() >= mSession.getTargetHeight()) { if (LogConfig.DEBUG_SCROLL) { Log.d(TAG, "Target height reached."); } finishCapture(); return; } Loading @@ -275,10 +294,14 @@ public class ScrollCaptureController { } private void finishCapture() { if (LogConfig.DEBUG_SCROLL) { Log.d(TAG, "finishCapture()"); } mEndFuture = mSession.end(); mEndFuture.addListener(() -> { 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)); Loading