Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f1131b42 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 10354447 from d7a73c60 to udc-qpr1-release

Change-Id: If007c9517aac67bf080d9a3a9aa8562dfd225781
parents 04351117 d7a73c60
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import android.os.ParcelFileDescriptor
import android.os.Process
import android.provider.Settings
import android.util.Log
import android.view.Choreographer
import android.window.IDumpCallback
import androidx.annotation.AnyThread
import androidx.annotation.VisibleForTesting
@@ -40,8 +39,8 @@ private val TAG = SettingsAwareViewCapture::class.java.simpleName
 */
class SettingsAwareViewCapture
@VisibleForTesting
internal constructor(private val context: Context, choreographer: Choreographer, executor: Executor)
    : ViewCapture(DEFAULT_MEMORY_SIZE, DEFAULT_INIT_POOL_SIZE, choreographer, executor) {
internal constructor(private val context: Context, executor: Executor)
    : ViewCapture(DEFAULT_MEMORY_SIZE, DEFAULT_INIT_POOL_SIZE, executor) {
    /** Dumps all the active view captures to the wm trace directory via LauncherAppService */
    private val mDumpCallback: IDumpCallback.Stub = object : IDumpCallback.Stub() {
        override fun onDump(out: ParcelFileDescriptor) {
@@ -91,7 +90,7 @@ internal constructor(private val context: Context, choreographer: Choreographer,
        fun getInstance(context: Context): ViewCapture = when {
            INSTANCE != null -> INSTANCE!!
            Looper.myLooper() == Looper.getMainLooper() -> SettingsAwareViewCapture(
                    context.applicationContext, Choreographer.getInstance(),
                    context.applicationContext,
                    createAndStartNewLooperExecutor("SAViewCapture",
                    Process.THREAD_PRIORITY_FOREGROUND)).also { INSTANCE = it }
            else -> try {
+0 −2
Original line number Diff line number Diff line
package com.android.app.viewcapture

import android.os.Process
import android.view.Choreographer

open class SimpleViewCapture(threadName: String) : ViewCapture(DEFAULT_MEMORY_SIZE, DEFAULT_INIT_POOL_SIZE,
    MAIN_EXECUTOR.submit { Choreographer.getInstance() }.get(),
    createAndStartNewLooperExecutor(threadName, Process.THREAD_PRIORITY_FOREGROUND))
 No newline at end of file
+16 −9
Original line number Diff line number Diff line
@@ -16,15 +16,18 @@

package com.android.app.viewcapture;

import static com.android.app.viewcapture.data.ExportedData.MagicNumber.MAGIC_NUMBER_H;
import static com.android.app.viewcapture.data.ExportedData.MagicNumber.MAGIC_NUMBER_L;

import android.content.Context;
import android.content.res.Resources;
import android.media.permission.SafeCloseable;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.SystemClock;
import android.os.Trace;
import android.text.TextUtils;
import android.util.SparseArray;
import android.view.Choreographer;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
@@ -51,6 +54,7 @@ import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Predicate;

@@ -65,6 +69,9 @@ public abstract class ViewCapture {
    private static final int PFLAG_INVALIDATED = 0x80000000;
    private static final int PFLAG_DIRTY_MASK = 0x00200000;

    private static final long MAGIC_NUMBER_FOR_WINSCOPE =
            ((long) MAGIC_NUMBER_H.getNumber() << 32) | MAGIC_NUMBER_L.getNumber();

    // Number of frames to keep in memory
    private final int mMemorySize;
    protected static final int DEFAULT_MEMORY_SIZE = 2000;
@@ -77,16 +84,13 @@ public abstract class ViewCapture {
    private final List<WindowListener> mListeners = new ArrayList<>();

    protected final Executor mBgExecutor;
    private final Choreographer mChoreographer;

    // Pool used for capturing view tree on the UI thread.
    private ViewRef mPool = new ViewRef();
    private boolean mIsEnabled = true;

    protected ViewCapture(int memorySize, int initPoolSize, Choreographer choreographer,
            Executor bgExecutor) {
    protected ViewCapture(int memorySize, int initPoolSize, Executor bgExecutor) {
        mMemorySize = memorySize;
        mChoreographer = choreographer;
        mBgExecutor = bgExecutor;
        mBgExecutor.execute(() -> initPool(initPoolSize));
    }
@@ -179,9 +183,12 @@ public abstract class ViewCapture {
            throws InterruptedException, ExecutionException {
        ArrayList<Class> classList = new ArrayList<>();
        return ExportedData.newBuilder()
                .setMagicNumber(MAGIC_NUMBER_FOR_WINSCOPE)
                .setPackage(context.getPackageName())
                .addAllWindowData(getWindowData(context, classList, l -> l.mIsActive).get())
                .addAllClassname(toStringList(classList))
                .setRealToElapsedTimeOffsetNanos(TimeUnit.MILLISECONDS
                        .toNanos(System.currentTimeMillis()) - SystemClock.elapsedRealtimeNanos())
                .build();
    }

@@ -282,7 +289,7 @@ public abstract class ViewCapture {
            ViewRef captured = mViewRef.next;
            if (captured != null) {
                captured.callback = mCaptureCallback;
                captured.choreographerTimeNanos = mChoreographer.getFrameTimeNanos();
                captured.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos();
                mBgExecutor.execute(captured);
            }
            mIsFirstFrame = false;
@@ -295,12 +302,12 @@ public abstract class ViewCapture {
         */
        @WorkerThread
        private void captureViewPropertiesBg(ViewRef viewRefStart) {
            long choreographerTimeNanos = viewRefStart.choreographerTimeNanos;
            long elapsedRealtimeNanos = viewRefStart.elapsedRealtimeNanos;
            mFrameIndexBg++;
            if (mFrameIndexBg >= mMemorySize) {
                mFrameIndexBg = 0;
            }
            mFrameTimesNanosBg[mFrameIndexBg] = choreographerTimeNanos;
            mFrameTimesNanosBg[mFrameIndexBg] = elapsedRealtimeNanos;

            ViewPropertyRef recycle = mNodesBg[mFrameIndexBg];

@@ -548,7 +555,7 @@ public abstract class ViewCapture {
        public ViewRef next;

        public Consumer<ViewRef> callback = null;
        public long choreographerTimeNanos = 0;
        public long elapsedRealtimeNanos = 0;

        public void transferTo(ViewPropertyRef out) {
            out.childCount = this.childCount;
+18 −4
Original line number Diff line number Diff line
@@ -21,9 +21,23 @@ package com.android.app.viewcapture.data;
option java_multiple_files = true;

message ExportedData {
  repeated WindowData windowData = 1;
  optional string package = 2;
  repeated string classname = 3;
  /* constant; MAGIC_NUMBER = (long) MAGIC_NUMBER_H << 32 | MagicNumber.MAGIC_NUMBER_L
   (this is needed because enums have to be 32 bits and there's no nice way to put 64bit
    constants into .proto files. */
  enum MagicNumber {
    INVALID = 0;
    MAGIC_NUMBER_L = 0x65906578;  /* AZAN (ASCII) */
    MAGIC_NUMBER_H = 0x68658273;  /* DARI (ASCII) */
  }

  optional fixed64 magic_number = 1;  /* Must be the first field, set to value in MagicNumber */
  repeated WindowData windowData = 2;
  optional string package = 3;
  repeated string classname = 4;

  /* offset between real-time clock and elapsed time clock in nanoseconds.
     Calculated as: 1000000 * System.currentTimeMillis() - SystemClock.elapsedRealtimeNanos() */
  optional fixed64 real_to_elapsed_time_offset_nanos = 5;
}

message WindowData {
@@ -37,7 +51,7 @@ message MotionWindowData {
}

message FrameData {
  optional int64 timestamp = 1; // choreographer timestamp in nanoseconds
  optional int64 timestamp = 1; // unit is elapsed realtime nanos
  optional ViewNode node = 2;
}

+2 −4
Original line number Diff line number Diff line
@@ -50,8 +50,7 @@ class SettingsAwareViewCaptureTest {
        Settings.Global.putInt(context.contentResolver, VIEW_CAPTURE_ENABLED, 0)

        activityScenarioRule.scenario.onActivity { activity ->
            val viewCapture: ViewCapture =
                SettingsAwareViewCapture(context, Choreographer.getInstance(), MAIN_EXECUTOR)
            val viewCapture: ViewCapture = SettingsAwareViewCapture(context, MAIN_EXECUTOR)
            val rootView: View = activity.findViewById(android.R.id.content)

            val closeable: SafeCloseable = viewCapture.startCapture(rootView, "rootViewId")
@@ -70,8 +69,7 @@ class SettingsAwareViewCaptureTest {
        Settings.Global.putInt(context.contentResolver, VIEW_CAPTURE_ENABLED, 1)

        activityScenarioRule.scenario.onActivity { activity ->
            val viewCapture: ViewCapture =
                SettingsAwareViewCapture(context, Choreographer.getInstance(), MAIN_EXECUTOR)
            val viewCapture: ViewCapture = SettingsAwareViewCapture(context, MAIN_EXECUTOR)
            val rootView: View = activity.findViewById(android.R.id.content)

            val closeable: SafeCloseable = viewCapture.startCapture(rootView, "rootViewId")
Loading