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

Commit ea178314 authored by Stefan Andonian's avatar Stefan Andonian
Browse files

Move ViewCapture On/Off controls to QuickSettings Tile.

Rather than use a feature flag for this feature, the on/off state will
be stored as a system setting and will be changed via a QuickSettings
tile.

Bug: b/264452057
Test: Verified that the new QuickSettings tile doesn't crash via normal
interactions (pressing, long-pressing, etc.). Also verified that
ViewCapture is turned on when the QuickSettings tile is in the enabled
state and is turned off when it is in the disabled state.

Change-Id: I29c5c44c6df64157c0c35a4ebc45cda74c3e1e1e
parent 046937af
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -43,7 +43,6 @@ dependencies {
    androidTestImplementation project(':SharedTestLib')
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation "androidx.test:rules:1.4.0"

}

protobuf {
+11 −12
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@

package com.android.app.motiontool

import android.os.Process
import android.util.Log
import android.view.Choreographer
import android.view.View
import android.view.WindowManagerGlobal
import androidx.annotation.VisibleForTesting
@@ -41,10 +43,8 @@ import com.android.app.viewcapture.data.nano.ExportedData
 *
 * @see [DdmHandleMotionTool]
 */
class MotionToolManager private constructor(
    private val viewCapture: ViewCapture,
    private val windowManagerGlobal: WindowManagerGlobal
) {
class MotionToolManager private constructor(private val windowManagerGlobal: WindowManagerGlobal) {
    private val viewCapture: ViewCapture = SimpleViewCapture()

    companion object {
        private const val TAG = "MotionToolManager"
@@ -52,13 +52,8 @@ class MotionToolManager private constructor(
        private var INSTANCE: MotionToolManager? = null

        @Synchronized
        fun getInstance(
            viewCapture: ViewCapture,
            windowManagerGlobal: WindowManagerGlobal
        ): MotionToolManager {
            return INSTANCE ?: MotionToolManager(viewCapture, windowManagerGlobal).also {
                INSTANCE = it
            }
        fun getInstance(windowManagerGlobal: WindowManagerGlobal): MotionToolManager {
            return INSTANCE ?: MotionToolManager(windowManagerGlobal).also { INSTANCE = it }
        }
    }

@@ -139,6 +134,10 @@ class MotionToolManager private constructor(
    private fun getRootView(windowId: String): View? {
        return windowManagerGlobal.getRootView(windowId)
    }

    class SimpleViewCapture : ViewCapture(DEFAULT_MEMORY_SIZE, DEFAULT_INIT_POOL_SIZE,
            MAIN_EXECUTOR.submit { Choreographer.getInstance() }.get(),
            createAndStartNewLooperExecutor("MTViewCapture", Process.THREAD_PRIORITY_FOREGROUND))
}

private data class TraceMetadata(
+13 −22
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.app.motiontool

import android.content.Intent
import android.testing.AndroidTestingRunner
import android.view.Choreographer
import android.view.View
import android.view.WindowManagerGlobal
import androidx.test.ext.junit.rules.ActivityScenarioRule
@@ -34,7 +35,6 @@ import com.android.app.motiontool.nano.MotionToolsResponse
import com.android.app.motiontool.nano.PollTraceRequest
import com.android.app.motiontool.nano.WindowIdentifier
import com.android.app.motiontool.util.TestActivity
import com.android.app.viewcapture.ViewCapture
import com.google.protobuf.nano.MessageNano
import junit.framework.Assert
import junit.framework.Assert.assertEquals
@@ -46,17 +46,12 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith


@SmallTest
@RunWith(AndroidTestingRunner::class)
class DdmHandleMotionToolTest {

    private val viewCaptureMemorySize = 100
    private val viewCaptureInitPoolSize = 15
    private val viewCapture =
        ViewCapture.getInstance(false, viewCaptureMemorySize, viewCaptureInitPoolSize)
    private val windowManagerGlobal = WindowManagerGlobal.getInstance()
    private val motionToolManager = MotionToolManager.getInstance(viewCapture, windowManagerGlobal)
    private val motionToolManager = MotionToolManager.getInstance(windowManagerGlobal)
    private val ddmHandleMotionTool = DdmHandleMotionTool.getInstance(motionToolManager)
    private val CLIENT_VERSION = 1

@@ -74,7 +69,6 @@ class DdmHandleMotionToolTest {
    @After
    fun cleanup() {
        ddmHandleMotionTool.unregister()
        motionToolManager.reset()
    }

    @Test
@@ -141,16 +135,13 @@ class DdmHandleMotionToolTest {

    @Test
    fun testOneOnDrawCallReturnsOneFrameResponse() {
        var traceId = 0
        activityScenarioRule.scenario.onActivity {
        activityScenarioRule.scenario.onActivity { activity ->
            val beginTraceResponse = performBeginTraceRequest(getActivityViewRootId())
            traceId = beginTraceResponse.beginTrace.traceId
            val rootView = it.findViewById<View>(android.R.id.content)
            rootView.invalidate()
        }
            val traceId = beginTraceResponse.beginTrace.traceId

            Choreographer.getInstance().postFrameCallback {
                activity.findViewById<View>(android.R.id.content).viewTreeObserver.dispatchOnDraw()

        // waits until main looper has no remaining tasks and is idle
        activityScenarioRule.scenario.onActivity {
                val pollTraceResponse = performPollTraceRequest(traceId)
                assertEquals(1, pollTraceResponse.pollTrace.exportedData.frameData.size)

@@ -158,7 +149,7 @@ class DdmHandleMotionToolTest {
                val endTraceResponse = performEndTraceRequest(traceId)
                assertEquals(0, endTraceResponse.endTrace.exportedData.frameData.size)
            }

        }
    }

    private fun performPollTraceRequest(requestTraceId: Int): MotionToolsResponse {
+12 −27
Original line number Diff line number Diff line
@@ -18,31 +18,25 @@ package com.android.app.motiontool

import android.content.Intent
import android.testing.AndroidTestingRunner
import android.view.Choreographer
import android.view.View
import android.view.WindowManagerGlobal
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.app.motiontool.util.TestActivity
import com.android.app.viewcapture.ViewCapture
import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertTrue
import org.junit.After
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith


@SmallTest
@RunWith(AndroidTestingRunner::class)
class MotionToolManagerTest {

    private val windowManagerGlobal = WindowManagerGlobal.getInstance()
    private val viewCaptureMemorySize = 100
    private val viewCaptureInitPoolSize = 15
    private val viewCapture =
        ViewCapture.getInstance(false, viewCaptureMemorySize, viewCaptureInitPoolSize)
    private val motionToolManager = MotionToolManager.getInstance(viewCapture, windowManagerGlobal)
    private val motionToolManager = MotionToolManager.getInstance(windowManagerGlobal)

    private val activityIntent =
        Intent(InstrumentationRegistry.getInstrumentation().context, TestActivity::class.java)
@@ -50,11 +44,6 @@ class MotionToolManagerTest {
    @get:Rule
    val activityScenarioRule = ActivityScenarioRule<TestActivity>(activityIntent)

    @After
    fun cleanup() {
        motionToolManager.reset()
    }

    @Test(expected = UnknownTraceIdException::class)
    fun testEndTraceThrowsWithoutPrecedingBeginTrace() {
        motionToolManager.endTrace(0)
@@ -93,15 +82,11 @@ class MotionToolManagerTest {

    @Test
    fun testOneOnDrawCallReturnsOneFrameResponse() {
        var traceId = 0
        activityScenarioRule.scenario.onActivity {
            traceId = motionToolManager.beginTrace(getActivityViewRootId())
            val rootView = it.findViewById<View>(android.R.id.content)
            rootView.invalidate()
        }
        activityScenarioRule.scenario.onActivity { activity ->
            val traceId = motionToolManager.beginTrace(getActivityViewRootId())
            Choreographer.getInstance().postFrameCallback {
                activity.findViewById<View>(android.R.id.content).viewTreeObserver.dispatchOnDraw()

        // waits until main looper has no remaining tasks and is idle
        activityScenarioRule.scenario.onActivity {
                val polledExportedData = motionToolManager.pollTrace(traceId)
                assertEquals(1, polledExportedData.frameData.size)

@@ -109,7 +94,7 @@ class MotionToolManagerTest {
                val endExportedData = motionToolManager.endTrace(traceId)
                assertEquals(0, endExportedData.frameData.size)
            }

        }
    }

    private fun getActivityViewRootId(): String {
+3 −0
Original line number Diff line number Diff line
@@ -16,5 +16,8 @@
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.android.app.viewcapture">
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"
        tools:ignore="ProtectedPermissions" />
</manifest>
Loading