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

Commit 6bb5bf89 authored by Miranda Kephart's avatar Miranda Kephart Committed by Android (Google) Code Review
Browse files

Merge "Fix image loading in clipboard UI for secondary user" into main

parents d665b9ff 65105a24
Loading
Loading
Loading
Loading
+57 −8
Original line number Diff line number Diff line
@@ -17,14 +17,17 @@ package com.android.systemui.clipboardoverlay

import android.content.ContentResolver
import android.content.Context
import android.content.pm.UserInfo
import android.net.Uri
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.Flags.FLAG_CLIPBOARD_OVERLAY_MULTIUSER
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.mockito.whenever
import com.android.systemui.settings.FakeUserTracker
import java.io.IOException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertNull
@@ -36,44 +39,90 @@ import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.whenever

@SmallTest
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(AndroidJUnit4::class)
class ClipboardImageLoaderTest : SysuiTestCase() {
    @Mock private lateinit var mockContext: Context

    @Mock private lateinit var mockContentResolver: ContentResolver
    @Mock private lateinit var mockSecondaryContentResolver: ContentResolver

    private lateinit var clipboardImageLoader: ClipboardImageLoader
    private var fakeUserTracker: FakeUserTracker =
        FakeUserTracker(userContentResolverProvider = { mockContentResolver })

    private val userInfos = listOf(UserInfo(0, "system", 0), UserInfo(50, "secondary", 0))

    @Before
    fun setup() {
        MockitoAnnotations.initMocks(this)

        fakeUserTracker.set(userInfos, 0)
    }

    @Test
    @Throws(IOException::class)
    @DisableFlags(FLAG_CLIPBOARD_OVERLAY_MULTIUSER)
    fun test_imageLoadSuccess_legacy() = runTest {
        val testDispatcher = StandardTestDispatcher(this.testScheduler)
        fakeUserTracker =
            FakeUserTracker(userContentResolverProvider = { mockSecondaryContentResolver })
        fakeUserTracker.set(userInfos, 1)

        clipboardImageLoader =
            ClipboardImageLoader(
                mockContext,
                fakeUserTracker,
                testDispatcher,
                CoroutineScope(testDispatcher),
            )
        val testUri = Uri.parse("testUri")
        whenever<ContentResolver?>(mockContext.contentResolver)
            .thenReturn(mockSecondaryContentResolver)
        whenever(mockContext.resources).thenReturn(context.resources)

        clipboardImageLoader.load(testUri)

        verify(mockSecondaryContentResolver).loadThumbnail(eq(testUri), any(), any())
    }

    @Test
    @Throws(IOException::class)
    @EnableFlags(FLAG_CLIPBOARD_OVERLAY_MULTIUSER)
    fun test_imageLoadSuccess() = runTest {
        val testDispatcher = StandardTestDispatcher(this.testScheduler)
        fakeUserTracker =
            FakeUserTracker(userContentResolverProvider = { mockSecondaryContentResolver })
        fakeUserTracker.set(userInfos, 1)

        clipboardImageLoader =
            ClipboardImageLoader(mockContext, testDispatcher, CoroutineScope(testDispatcher))
            ClipboardImageLoader(
                mockContext,
                fakeUserTracker,
                testDispatcher,
                CoroutineScope(testDispatcher),
            )
        val testUri = Uri.parse("testUri")
        whenever(mockContext.contentResolver).thenReturn(mockContentResolver)
        whenever(mockContext.resources).thenReturn(context.resources)

        clipboardImageLoader.load(testUri)

        verify(mockContentResolver).loadThumbnail(eq(testUri), any(), any())
        verify(mockSecondaryContentResolver).loadThumbnail(eq(testUri), any(), any())
    }

    @OptIn(ExperimentalCoroutinesApi::class)
    @Test
    @Throws(IOException::class)
    fun test_imageLoadFailure() = runTest {
        val testDispatcher = StandardTestDispatcher(this.testScheduler)
        clipboardImageLoader =
            ClipboardImageLoader(mockContext, testDispatcher, CoroutineScope(testDispatcher))
            ClipboardImageLoader(
                mockContext,
                fakeUserTracker,
                testDispatcher,
                CoroutineScope(testDispatcher),
            )
        val testUri = Uri.parse("testUri")
        whenever(mockContext.contentResolver).thenReturn(mockContentResolver)
        whenever(mockContext.resources).thenReturn(context.resources)
+15 −4
Original line number Diff line number Diff line
@@ -20,15 +20,17 @@ import android.graphics.Bitmap
import android.net.Uri
import android.util.Log
import android.util.Size
import com.android.systemui.res.R
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.Flags.clipboardOverlayMultiuser
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.res.R
import com.android.systemui.settings.UserTracker
import java.io.IOException
import java.util.function.Consumer
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import com.android.app.tracing.coroutines.launchTraced as launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeoutOrNull

@@ -36,8 +38,9 @@ class ClipboardImageLoader
@Inject
constructor(
    private val context: Context,
    private val userTracker: UserTracker,
    @Background private val bgDispatcher: CoroutineDispatcher,
    @Application private val mainScope: CoroutineScope
    @Application private val mainScope: CoroutineScope,
) {
    private val TAG: String = "ClipboardImageLoader"

@@ -46,7 +49,15 @@ constructor(
            withContext(bgDispatcher) {
                try {
                    val size = context.resources.getDimensionPixelSize(R.dimen.overlay_x_scale)
                    if (clipboardOverlayMultiuser()) {
                        userTracker.userContentResolver.loadThumbnail(
                            uri,
                            Size(size, size * 4),
                            null,
                        )
                    } else {
                        context.contentResolver.loadThumbnail(uri, Size(size, size * 4), null)
                    }
                } catch (e: IOException) {
                    Log.e(TAG, "Thumbnail loading failed!", e)
                    null