From 48f4ce1ab452cdc36092d054a86f5d18edbe9b6d Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Fri, 21 Oct 2022 11:24:50 -0700 Subject: [PATCH] [Controls] Update shared pref to be user specific. Update sharedpref object to know about the user id. This will retrieve sharedprefs from secondary users instead of just the system user which will allow preferences to be stored for secondary users. Bug: 254858721 Test: Manual test. Added a structure for system user and secondary user. Observe that they are different. Change-Id: I137727c49f1dcafba0e6ac835d0d9e1035b11a8e --- .../controls/ui/ControlsUiControllerImpl.kt | 15 +- .../policy/DeviceControlsControllerImpl.kt | 2 +- .../ui/ControlsUiControllerImplTest.kt | 155 ++++++++++++++++++ 3 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index bf7d716356942..6cb0e8b048693 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -24,7 +24,6 @@ import android.app.ActivityOptions import android.content.ComponentName import android.content.Context import android.content.Intent -import android.content.SharedPreferences import android.graphics.drawable.Drawable import android.graphics.drawable.LayerDrawable import android.service.controls.Control @@ -59,7 +58,10 @@ import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.globalactions.GlobalActionsPopupMenu import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.settings.UserFileManager +import com.android.systemui.settings.UserTracker import com.android.systemui.shade.ShadeController +import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.concurrency.DelayableExecutor import dagger.Lazy @@ -76,13 +78,14 @@ class ControlsUiControllerImpl @Inject constructor ( @Main val uiExecutor: DelayableExecutor, @Background val bgExecutor: DelayableExecutor, val controlsListingController: Lazy, - @Main val sharedPreferences: SharedPreferences, val controlActionCoordinator: ControlActionCoordinator, private val activityStarter: ActivityStarter, private val shadeController: ShadeController, private val iconCache: CustomIconCache, private val controlsMetricsLogger: ControlsMetricsLogger, - private val keyguardStateController: KeyguardStateController + private val keyguardStateController: KeyguardStateController, + private val userFileManager: UserFileManager, + private val userTracker: UserTracker, ) : ControlsUiController { companion object { @@ -110,6 +113,12 @@ class ControlsUiControllerImpl @Inject constructor ( private lateinit var onDismiss: Runnable private val popupThemedContext = ContextThemeWrapper(context, R.style.Control_ListPopupWindow) private var retainCache = false + private val sharedPreferences + get() = userFileManager.getSharedPreferences( + fileName = DeviceControlsControllerImpl.PREFS_CONTROLS_FILE, + mode = 0, + userId = userTracker.userId + ) private val collator = Collator.getInstance(context.resources.configuration.locales[0]) private val localeComparator = compareBy(collator) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt index bc2ae64dd946d..e3266115f7779 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt @@ -67,7 +67,7 @@ public class DeviceControlsControllerImpl @Inject constructor( internal const val QS_DEFAULT_POSITION = 7 internal const val PREFS_CONTROLS_SEEDING_COMPLETED = "SeedingCompleted" - internal const val PREFS_CONTROLS_FILE = "controls_prefs" + const val PREFS_CONTROLS_FILE = "controls_prefs" internal const val PREFS_SETTINGS_DIALOG_ATTEMPTS = "show_settings_attempts" private const val SEEDING_MAX = 2 } diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt new file mode 100644 index 0000000000000..49c7442b9708a --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2022 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.controls.ui + +import android.content.ComponentName +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.controls.ControlsMetricsLogger +import com.android.systemui.controls.CustomIconCache +import com.android.systemui.controls.controller.ControlsController +import com.android.systemui.controls.controller.StructureInfo +import com.android.systemui.controls.management.ControlsListingController +import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.settings.UserFileManager +import com.android.systemui.settings.UserTracker +import com.android.systemui.shade.ShadeController +import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl +import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.systemui.util.FakeSharedPreferences +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.time.FakeSystemClock +import com.google.common.truth.Truth.assertThat +import dagger.Lazy +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.anyInt +import org.mockito.Mockito.anyString +import org.mockito.Mockito.mock +import org.mockito.Mockito.times +import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper +class ControlsUiControllerImplTest : SysuiTestCase() { + @Mock lateinit var controlsController: ControlsController + @Mock lateinit var controlsListingController: ControlsListingController + @Mock lateinit var controlActionCoordinator: ControlActionCoordinator + @Mock lateinit var activityStarter: ActivityStarter + @Mock lateinit var shadeController: ShadeController + @Mock lateinit var iconCache: CustomIconCache + @Mock lateinit var controlsMetricsLogger: ControlsMetricsLogger + @Mock lateinit var keyguardStateController: KeyguardStateController + @Mock lateinit var userFileManager: UserFileManager + @Mock lateinit var userTracker: UserTracker + val sharedPreferences = FakeSharedPreferences() + + var uiExecutor = FakeExecutor(FakeSystemClock()) + var bgExecutor = FakeExecutor(FakeSystemClock()) + lateinit var underTest: ControlsUiControllerImpl + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + + underTest = + ControlsUiControllerImpl( + Lazy { controlsController }, + context, + uiExecutor, + bgExecutor, + Lazy { controlsListingController }, + controlActionCoordinator, + activityStarter, + shadeController, + iconCache, + controlsMetricsLogger, + keyguardStateController, + userFileManager, + userTracker + ) + `when`( + userFileManager.getSharedPreferences( + DeviceControlsControllerImpl.PREFS_CONTROLS_FILE, + 0, + 0 + ) + ) + .thenReturn(sharedPreferences) + `when`(userFileManager.getSharedPreferences(anyString(), anyInt(), anyInt())) + .thenReturn(sharedPreferences) + `when`(userTracker.userId).thenReturn(0) + } + + @Test + fun testGetPreferredStructure() { + val structureInfo = mock(StructureInfo::class.java) + underTest.getPreferredStructure(listOf(structureInfo)) + verify(userFileManager, times(2)) + .getSharedPreferences( + fileName = DeviceControlsControllerImpl.PREFS_CONTROLS_FILE, + mode = 0, + userId = 0 + ) + } + + @Test + fun testGetPreferredStructure_differentUserId() { + val structureInfo = + listOf( + StructureInfo(ComponentName.unflattenFromString("pkg/.cls1"), "a", ArrayList()), + StructureInfo(ComponentName.unflattenFromString("pkg/.cls2"), "b", ArrayList()), + ) + sharedPreferences + .edit() + .putString("controls_component", structureInfo[0].componentName.flattenToString()) + .putString("controls_structure", structureInfo[0].structure.toString()) + .commit() + + val differentSharedPreferences = FakeSharedPreferences() + differentSharedPreferences + .edit() + .putString("controls_component", structureInfo[1].componentName.flattenToString()) + .putString("controls_structure", structureInfo[1].structure.toString()) + .commit() + + val previousPreferredStructure = underTest.getPreferredStructure(structureInfo) + + `when`( + userFileManager.getSharedPreferences( + DeviceControlsControllerImpl.PREFS_CONTROLS_FILE, + 0, + 1 + ) + ) + .thenReturn(differentSharedPreferences) + `when`(userTracker.userId).thenReturn(1) + + val currentPreferredStructure = underTest.getPreferredStructure(structureInfo) + + assertThat(previousPreferredStructure).isEqualTo(structureInfo[0]) + assertThat(currentPreferredStructure).isEqualTo(structureInfo[1]) + assertThat(currentPreferredStructure).isNotEqualTo(previousPreferredStructure) + } +}