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

Commit e9f5231c authored by Bartosz Chomiński's avatar Bartosz Chomiński Committed by Android (Google) Code Review
Browse files

Merge "On locale change update app name in window caption" into main

parents 90827cb6 699174f5
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -361,6 +361,9 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
        outResult.mRootView = rootView;
        final boolean fontScaleChanged = mWindowDecorConfig != null
                && mWindowDecorConfig.fontScale != mTaskInfo.configuration.fontScale;
        final boolean localeListChanged = mWindowDecorConfig != null
                && !mWindowDecorConfig.getLocales()
                    .equals(mTaskInfo.getConfiguration().getLocales());
        final int oldDensityDpi = mWindowDecorConfig != null
                ? mWindowDecorConfig.densityDpi : DENSITY_DPI_UNDEFINED;
        final int oldNightMode =  mWindowDecorConfig != null
@@ -376,7 +379,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
                || oldLayoutResId != mLayoutResId
                || oldNightMode != newNightMode
                || mDecorWindowContext == null
                || fontScaleChanged) {
                || fontScaleChanged
                || localeListChanged) {
            releaseViews(wct);

            if (!obtainDisplayOrRegisterListener()) {
+15 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.Context
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.os.LocaleList
import android.os.UserHandle
import androidx.tracing.Trace
import com.android.internal.annotations.VisibleForTesting
@@ -80,6 +81,13 @@ class WindowDecorTaskResourceLoader(
     */
    private val existingTasks = mutableSetOf<Int>()

    /**
     * A map of task -> localeList to keep track of the language of app name that's currently
     * cached in |taskToResourceCache|.
     */
    @VisibleForTesting
    val localeListOnCache = ConcurrentHashMap<Int, LocaleList>()

    init {
        shellInit.addInitCallback(this::onInit, this)
    }
@@ -99,11 +107,14 @@ class WindowDecorTaskResourceLoader(
    fun getName(taskInfo: RunningTaskInfo): CharSequence {
        checkWindowDecorExists(taskInfo)
        val cachedResources = taskToResourceCache[taskInfo.taskId]
        if (cachedResources != null) {
        val localeListActiveOnCacheTime = localeListOnCache[taskInfo.taskId]
        if (cachedResources != null &&
            taskInfo.getConfiguration().getLocales().equals(localeListActiveOnCacheTime)) {
            return cachedResources.appName
        }
        val resources = loadAppResources(taskInfo)
        taskToResourceCache[taskInfo.taskId] = resources
        localeListOnCache[taskInfo.taskId] = taskInfo.getConfiguration().getLocales()
        return resources.appName
    }

@@ -117,6 +128,7 @@ class WindowDecorTaskResourceLoader(
        }
        val resources = loadAppResources(taskInfo)
        taskToResourceCache[taskInfo.taskId] = resources
        localeListOnCache[taskInfo.taskId] = taskInfo.getConfiguration().getLocales()
        return resources.appIcon
    }

@@ -130,6 +142,7 @@ class WindowDecorTaskResourceLoader(
        }
        val resources = loadAppResources(taskInfo)
        taskToResourceCache[taskInfo.taskId] = resources
        localeListOnCache[taskInfo.taskId] = taskInfo.getConfiguration().getLocales()
        return resources.veilIcon
    }

@@ -142,6 +155,7 @@ class WindowDecorTaskResourceLoader(
    fun onWindowDecorClosed(taskInfo: RunningTaskInfo) {
        existingTasks.remove(taskInfo.taskId)
        taskToResourceCache.remove(taskInfo.taskId)
        localeListOnCache.remove(taskInfo.taskId)
    }

    private fun checkWindowDecorExists(taskInfo: RunningTaskInfo) {
+46 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Handler;
import android.os.LocaleList;
import android.testing.AndroidTestingRunner;
import android.util.DisplayMetrics;
import android.view.AttachedSurfaceControl;
@@ -97,6 +98,7 @@ import org.mockito.Mockito;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.function.Supplier;

/**
@@ -474,6 +476,50 @@ public class WindowDecorationTests extends ShellTestCase {
        verify(mMockSurfaceControlViewHostFactory).create(any(), eq(defaultDisplay), any());
    }

    @Test
    public void testReinflateViewsOnLocaleListChange() {
        final Display defaultDisplay = mock(Display.class);
        doReturn(defaultDisplay).when(mMockDisplayController)
                .getDisplay(Display.DEFAULT_DISPLAY);

        final ActivityManager.RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
                .setVisible(true)
                .setDisplayId(Display.DEFAULT_DISPLAY)
                .build();
        taskInfo.configuration.setLocales(new LocaleList(Locale.FRANCE, Locale.US));
        final TestWindowDecoration windowDecor = spy(createWindowDecoration(taskInfo));
        windowDecor.relayout(taskInfo, true /* hasGlobalFocus */, Region.obtain());
        clearInvocations(windowDecor);

        final ActivityManager.RunningTaskInfo taskInfo2 = new TestRunningTaskInfoBuilder()
                .setVisible(true)
                .setDisplayId(Display.DEFAULT_DISPLAY)
                .build();
        taskInfo2.configuration.setLocales(new LocaleList(Locale.US, Locale.FRANCE));
        windowDecor.relayout(taskInfo2, true /* hasGlobalFocus */, Region.obtain());
        // WindowDecoration#releaseViews should be called since the locale list has changed.
        verify(windowDecor, times(1)).releaseViews(any());
    }

    @Test
    public void testViewNotReinflatedWhenLocaleListNotChanged() {
        final Display defaultDisplay = mock(Display.class);
        doReturn(defaultDisplay).when(mMockDisplayController)
                .getDisplay(Display.DEFAULT_DISPLAY);

        final ActivityManager.RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
                .setVisible(true)
                .setDisplayId(Display.DEFAULT_DISPLAY)
                .build();
        taskInfo.configuration.setLocales(new LocaleList(Locale.FRANCE, Locale.US));
        final TestWindowDecoration windowDecor = spy(createWindowDecoration(taskInfo));
        windowDecor.relayout(taskInfo, true /* hasGlobalFocus */, Region.obtain());
        clearInvocations(windowDecor);
        windowDecor.relayout(taskInfo, true /* hasGlobalFocus */, Region.obtain());
        // WindowDecoration#releaseViews should not be called since nothing has changed.
        verify(windowDecor, never()).releaseViews(any());
    }

    @Test
    public void testLayoutResultCalculation_fullWidthCaption() {
        final Display defaultDisplay = mock(Display.class);
+17 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.content.pm.ActivityInfo
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.os.LocaleList
import android.os.UserHandle
import android.testing.AndroidTestingRunner
import android.testing.TestableContext
@@ -39,6 +40,7 @@ import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.sysui.UserChangeListener
import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader.AppResources
import com.google.common.truth.Truth.assertThat
import java.util.Locale
import org.junit.Assert.assertThrows
import org.junit.Before
import org.junit.Test
@@ -116,8 +118,10 @@ class WindowDecorTaskResourceLoaderTest : ShellTestCase() {
    @Test
    fun testGetName_cached_returnsFromCache() {
        val task = createTaskInfo(context.userId)
        task.configuration.setLocales(LocaleList(Locale.US))
        loader.onWindowDecorCreated(task)
        loader.taskToResourceCache[task.taskId] = AppResources("App Name", mock(), mock())
        loader.localeListOnCache[task.taskId] = LocaleList(Locale.US)

        loader.getName(task)

@@ -129,6 +133,19 @@ class WindowDecorTaskResourceLoaderTest : ShellTestCase() {
        )
    }

    @Test
    fun testGetName_cached_localesChanged_loadsResourceAndCaches() {
        val task = createTaskInfo(context.userId)
        loader.onWindowDecorCreated(task)
        loader.taskToResourceCache[task.taskId] = AppResources("App Name", mock(), mock())
        loader.localeListOnCache[task.taskId] = LocaleList(Locale.US, Locale.FRANCE)
        task.configuration.setLocales(LocaleList(Locale.FRANCE, Locale.US))
        doReturn("App Name but in French").whenever(mockPackageManager).getApplicationLabel(any())

        assertThat(loader.getName(task)).isEqualTo("App Name but in French")
        assertThat(loader.taskToResourceCache[task.taskId]?.appName).isEqualTo("App Name but in French")
    }

    @Test
    fun testGetHeaderIcon_notCached_loadsResourceAndCaches() {
        val task = createTaskInfo(context.userId)