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

Commit 8c5e7897 authored by Stefan Andonian's avatar Stefan Andonian Committed by Android (Google) Code Review
Browse files

Merge changes from topic "irs-hsum" into main

* changes:
  Make RecordIssueTile's ServiceConnections not injected, but created.
  Explicitly state which user to start Record Issue interactions inside.
  Refactor the TraceurMessenger code into a ServiceConnection class.
parents 2c5b6d7e 70b54e38
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ class IssueRecordingServiceSessionTest : SysuiTestCase() {
    private val bgExecutor = kosmos.fakeExecutor
    private val userContextProvider: UserContextProvider = kosmos.userTracker
    private val dialogTransitionAnimator: DialogTransitionAnimator = kosmos.dialogTransitionAnimator
    private lateinit var traceurMessageSender: TraceurMessageSender
    private lateinit var traceurConnection: TraceurConnection
    private val issueRecordingState =
        IssueRecordingState(kosmos.userTracker, kosmos.userFileManager)

@@ -65,13 +65,13 @@ class IssueRecordingServiceSessionTest : SysuiTestCase() {

    @Before
    fun setup() {
        traceurMessageSender = mock<TraceurMessageSender>()
        traceurConnection = mock<TraceurConnection>()
        underTest =
            IssueRecordingServiceSession(
                bgExecutor,
                dialogTransitionAnimator,
                panelInteractor,
                traceurMessageSender,
                traceurConnection,
                issueRecordingState,
                iActivityManager,
                notificationManager,
@@ -85,7 +85,7 @@ class IssueRecordingServiceSessionTest : SysuiTestCase() {
        bgExecutor.runAllReady()

        Truth.assertThat(issueRecordingState.isRecording).isTrue()
        verify(traceurMessageSender).startTracing(any<TraceConfig>())
        verify(traceurConnection).startTracing(any<TraceConfig>())
    }

    @Test
@@ -94,12 +94,12 @@ class IssueRecordingServiceSessionTest : SysuiTestCase() {
        bgExecutor.runAllReady()

        Truth.assertThat(issueRecordingState.isRecording).isFalse()
        verify(traceurMessageSender).stopTracing()
        verify(traceurConnection).stopTracing()
    }

    @Test
    fun cancelsNotification_afterReceivingShareCommand() {
        underTest.share(0, null, mContext)
        underTest.share(0, null)
        bgExecutor.runAllReady()

        verify(notificationManager).cancelAsUser(isNull(), anyInt(), any<UserHandle>())
@@ -110,7 +110,7 @@ class IssueRecordingServiceSessionTest : SysuiTestCase() {
        issueRecordingState.takeBugreport = true
        val uri = mock<Uri>()

        underTest.share(0, uri, mContext)
        underTest.share(0, uri)
        bgExecutor.runAllReady()

        verify(iActivityManager).requestBugReportWithExtraAttachment(uri)
@@ -121,17 +121,17 @@ class IssueRecordingServiceSessionTest : SysuiTestCase() {
        issueRecordingState.takeBugreport = false
        val uri = mock<Uri>()

        underTest.share(0, uri, mContext)
        underTest.share(0, uri)
        bgExecutor.runAllReady()

        verify(traceurMessageSender).shareTraces(mContext, uri)
        verify(traceurConnection).shareTraces(uri)
    }

    @Test
    fun closesShade_afterReceivingShareCommand() {
        val uri = mock<Uri>()

        underTest.share(0, uri, mContext)
        underTest.share(0, uri)
        bgExecutor.runAllReady()

        verify(panelInteractor).collapsePanels()
+4 −6
Original line number Diff line number Diff line
@@ -78,7 +78,6 @@ class RecordIssueDialogDelegateTest : SysuiTestCase() {
    @Mock private lateinit var sysuiState: SysUiState
    @Mock private lateinit var systemUIDialogManager: SystemUIDialogManager
    @Mock private lateinit var broadcastDispatcher: BroadcastDispatcher
    @Mock private lateinit var traceurMessageSender: TraceurMessageSender
    private val systemClock = FakeSystemClock()
    private val bgExecutor = FakeExecutor(systemClock)
    private val mainExecutor = FakeExecutor(systemClock)
@@ -104,7 +103,7 @@ class RecordIssueDialogDelegateTest : SysuiTestCase() {
                    systemUIDialogManager,
                    sysuiState,
                    broadcastDispatcher,
                    mDialogTransitionAnimator
                    mDialogTransitionAnimator,
                )
            )

@@ -120,7 +119,6 @@ class RecordIssueDialogDelegateTest : SysuiTestCase() {
                    mediaProjectionMetricsLogger,
                    screenCaptureDisabledDialogDelegate,
                    state,
                    traceurMessageSender
                ) {
                    latch.countDown()
                }
@@ -166,7 +164,7 @@ class RecordIssueDialogDelegateTest : SysuiTestCase() {
        verify(mediaProjectionMetricsLogger, never())
            .notifyProjectionInitiated(
                anyInt(),
                eq(SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER)
                eq(SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER),
            )
        assertThat(screenRecordSwitch.isChecked).isFalse()
    }
@@ -188,7 +186,7 @@ class RecordIssueDialogDelegateTest : SysuiTestCase() {
        verify(mediaProjectionMetricsLogger)
            .notifyProjectionInitiated(
                anyInt(),
                eq(SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER)
                eq(SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER),
            )
        verify(factory, times(2)).create(any(SystemUIDialog.Delegate::class.java))
    }
@@ -208,7 +206,7 @@ class RecordIssueDialogDelegateTest : SysuiTestCase() {
        verify(mediaProjectionMetricsLogger)
            .notifyProjectionInitiated(
                anyInt(),
                eq(SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER)
                eq(SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER),
            )
        verify(factory, never()).create()
    }
+77 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.recordissue

import android.os.IBinder
import android.os.Looper
import android.os.Messenger
import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.systemui.SysuiTestCase
import com.android.systemui.settings.UserContextProvider
import com.android.traceur.PresetTraceConfigs
import java.util.concurrent.CountDownLatch
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.mock
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever

@SmallTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class TraceurConnectionTest : SysuiTestCase() {

    @Mock private lateinit var userContextProvider: UserContextProvider

    private lateinit var underTest: TraceurConnection

    @Before
    fun setup() {
        MockitoAnnotations.initMocks(this)
        whenever(userContextProvider.userContext).thenReturn(mContext)
        underTest = TraceurConnection.Provider(userContextProvider, Looper.getMainLooper()).create()
    }

    @Test
    fun onBoundRunnables_areRun_whenServiceIsBound() {
        val latch = CountDownLatch(1)
        underTest.onBound.add { latch.countDown() }

        underTest.onServiceConnected(
            InstrumentationRegistry.getInstrumentation().componentName,
            mock(IBinder::class.java),
        )

        latch.await()
    }

    @Test
    fun startTracing_sendsMsg_toStartTracing() {
        underTest.binder = mock(Messenger::class.java)

        underTest.startTracing(PresetTraceConfigs.getThermalConfig())

        verify(underTest.binder)!!.send(any())
    }
}
+70 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.recordissue

import android.content.Context
import android.content.Intent
import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.settings.UserContextProvider
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito.any
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever

@SmallTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class UserAwareConnectionTest : SysuiTestCase() {

    @Mock private lateinit var userContextProvider: UserContextProvider
    @Mock private lateinit var mockContext: Context

    private lateinit var underTest: UserAwareConnection

    @Before
    fun setup() {
        MockitoAnnotations.initMocks(this)
        whenever(userContextProvider.userContext).thenReturn(mockContext)
        whenever(mockContext.bindService(any(), any(), anyInt())).thenReturn(true)
        underTest = UserAwareConnection(userContextProvider, Intent())
    }

    @Test
    fun doBindService_requestToBindToTheService_viaTheCorrectUserContext() {
        underTest.doBind()

        verify(userContextProvider).userContext
    }

    @Test
    fun doBindService_DoesntRequestToBindToTheService_IfAlreadyRequested() {
        underTest.doBind()
        underTest.doBind()
        underTest.doBind()

        verify(userContextProvider, times(1)).userContext
    }
}
+27 −7
Original line number Diff line number Diff line
@@ -45,10 +45,11 @@ import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.recordissue.IssueRecordingService.Companion.getStartIntent
import com.android.systemui.recordissue.IssueRecordingService.Companion.getStopIntent
import com.android.systemui.recordissue.IssueRecordingServiceConnection
import com.android.systemui.recordissue.IssueRecordingState
import com.android.systemui.recordissue.RecordIssueDialogDelegate
import com.android.systemui.recordissue.RecordIssueModule.Companion.TILE_SPEC
import com.android.systemui.recordissue.TraceurMessageSender
import com.android.systemui.recordissue.TraceurConnection
import com.android.systemui.res.R
import com.android.systemui.screenrecord.RecordingController
import com.android.systemui.screenrecord.RecordingService
@@ -66,7 +67,7 @@ class RecordIssueTile
constructor(
    host: QSHost,
    uiEventLogger: QsEventLogger,
    @Background backgroundLooper: Looper,
    @Background private val backgroundLooper: Looper,
    @Main mainHandler: Handler,
    falsingManager: FalsingManager,
    metricsLogger: MetricsLogger,
@@ -78,7 +79,8 @@ constructor(
    private val dialogTransitionAnimator: DialogTransitionAnimator,
    private val panelInteractor: PanelInteractor,
    private val userContextProvider: UserContextProvider,
    private val traceurMessageSender: TraceurMessageSender,
    irsConnProvider: IssueRecordingServiceConnection.Provider,
    traceurConnProvider: TraceurConnection.Provider,
    @Background private val bgExecutor: Executor,
    private val issueRecordingState: IssueRecordingState,
    private val delegateFactory: RecordIssueDialogDelegate.Factory,
@@ -93,11 +95,20 @@ constructor(
        metricsLogger,
        statusBarStateController,
        activityStarter,
        qsLogger
        qsLogger,
    ) {

    private val onRecordingChangeListener = Runnable { refreshState() }

    private val irsConnection: IssueRecordingServiceConnection = irsConnProvider.create()
    private val traceurConnection =
        traceurConnProvider.create().apply {
            onBound.add {
                getTags(issueRecordingState)
                doUnBind()
            }
        }

    override fun handleSetListening(listening: Boolean) {
        super.handleSetListening(listening)
        if (listening) {
@@ -109,7 +120,7 @@ constructor(

    override fun handleDestroy() {
        super.handleDestroy()
        bgExecutor.execute { traceurMessageSender.unbindFromTraceur(mContext) }
        bgExecutor.execute { irsConnection.doUnBind() }
    }

    override fun getTileLabel(): CharSequence = mContext.getString(R.string.qs_record_issue_label)
@@ -142,7 +153,7 @@ constructor(
            DELAY_MS,
            INTERVAL_MS,
            pendingServiceIntent(getStartIntent(userContextProvider.userContext)),
            pendingServiceIntent(getStopIntent(userContextProvider.userContext))
            pendingServiceIntent(getStopIntent(userContextProvider.userContext)),
        )

    private fun stopIssueRecordingService() =
@@ -154,10 +165,19 @@ constructor(
            userContextProvider.userContext,
            RecordingService.REQUEST_CODE,
            action,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
        )

    private fun showPrompt(expandable: Expandable?) {
        bgExecutor.execute {
            // We only want to get the tags once per session, as this is not likely to change, if at
            // all on a month to month basis. Using onBound's size is a way to verify if the tag
            // retrieval has already happened or not.
            if (traceurConnection.onBound.isNotEmpty()) {
                traceurConnection.doBind()
            }
            irsConnection.doBind()
        }
        val dialog: AlertDialog =
            delegateFactory
                .create {
Loading