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

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

Snap for 10341497 from 1ca32b91 to udc-qpr1-release

Change-Id: Ie09f0d04ac816a39d4ecf81f16926b45c97dffcd
parents 78a65040 1ca32b91
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ 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
@@ -39,8 +40,8 @@ private val TAG = SettingsAwareViewCapture::class.java.simpleName
 */
class SettingsAwareViewCapture
@VisibleForTesting
internal constructor(private val context: Context, executor: Executor)
    : ViewCapture(DEFAULT_MEMORY_SIZE, DEFAULT_INIT_POOL_SIZE, executor) {
internal constructor(private val context: Context, choreographer: Choreographer, executor: Executor)
    : ViewCapture(DEFAULT_MEMORY_SIZE, DEFAULT_INIT_POOL_SIZE, choreographer, 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) {
@@ -90,7 +91,7 @@ internal constructor(private val context: Context, executor: Executor)
        fun getInstance(context: Context): ViewCapture = when {
            INSTANCE != null -> INSTANCE!!
            Looper.myLooper() == Looper.getMainLooper() -> SettingsAwareViewCapture(
                    context.applicationContext,
                    context.applicationContext, Choreographer.getInstance(),
                    createAndStartNewLooperExecutor("SAViewCapture",
                    Process.THREAD_PRIORITY_FOREGROUND)).also { INSTANCE = it }
            else -> try {
+2 −0
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
+9 −16
Original line number Diff line number Diff line
@@ -16,18 +16,15 @@

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;
@@ -54,7 +51,6 @@ 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;

@@ -69,9 +65,6 @@ 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;
@@ -84,13 +77,16 @@ 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, Executor bgExecutor) {
    protected ViewCapture(int memorySize, int initPoolSize, Choreographer choreographer,
            Executor bgExecutor) {
        mMemorySize = memorySize;
        mChoreographer = choreographer;
        mBgExecutor = bgExecutor;
        mBgExecutor.execute(() -> initPool(initPoolSize));
    }
@@ -183,12 +179,9 @@ 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();
    }

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

            ViewPropertyRef recycle = mNodesBg[mFrameIndexBg];

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

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

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

message ExportedData {
  /* 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;
  repeated WindowData windowData = 1;
  optional string package = 2;
  repeated string classname = 3;
}

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

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

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

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

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

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

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