Revert "Adds ChooserPinMigration core startable"
Revert submission 22119004-b223249318-chooser-pin-migrate Reason for revert: <b/275407260> Reverted changes: /q/submissionid:22119004-b223249318-chooser-pin-migrate Change-Id: I86e0a0d7d5cfeb729db26f25b0f41ebb18d7bdb5
This commit is contained in:
committed by
Android (Google) Code Review
parent
03cecc1be6
commit
dad0b271f7
@@ -344,15 +344,6 @@
|
||||
|
||||
<uses-permission android:name="android.permission.MONITOR_KEYBOARD_BACKLIGHT" />
|
||||
|
||||
<!-- Intent Chooser -->
|
||||
<permission
|
||||
android:name="android.permission.ADD_CHOOSER_PINS"
|
||||
android:protectionLevel="signature" />
|
||||
<uses-permission android:name="android.permission.ADD_CHOOSER_PINS" />
|
||||
<permission
|
||||
android:name="android.permission.RECEIVE_CHOOSER_PIN_MIGRATION"
|
||||
android:protectionLevel="signature" />
|
||||
|
||||
<protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
|
||||
<protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
|
||||
<protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Context.MODE_PRIVATE
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.os.storage.StorageManager
|
||||
import android.util.Log
|
||||
import androidx.core.util.Supplier
|
||||
import com.android.internal.R
|
||||
import com.android.systemui.broadcast.BroadcastSender
|
||||
import com.android.systemui.flags.FeatureFlags
|
||||
import com.android.systemui.flags.Flags
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Performs a migration of pinned targets to the unbundled chooser if legacy data exists.
|
||||
*
|
||||
* Sends an explicit broadcast with the contents of the legacy pin preferences. The broadcast is
|
||||
* protected by the RECEIVE_CHOOSER_PIN_MIGRATION permission. This class requires the
|
||||
* ADD_CHOOSER_PINS permission in order to be able to send this broadcast.
|
||||
*/
|
||||
class ChooserPinMigration
|
||||
@Inject
|
||||
constructor(
|
||||
private val context: Context,
|
||||
private val featureFlags: FeatureFlags,
|
||||
private val broadcastSender: BroadcastSender,
|
||||
legacyPinPrefsFileSupplier: LegacyPinPrefsFileSupplier,
|
||||
) : CoreStartable {
|
||||
|
||||
private val legacyPinPrefsFile = legacyPinPrefsFileSupplier.get()
|
||||
private val chooserComponent =
|
||||
ComponentName.unflattenFromString(
|
||||
context.resources.getString(R.string.config_chooserActivity)
|
||||
)
|
||||
|
||||
override fun start() {
|
||||
if (migrationIsRequired()) {
|
||||
doMigration()
|
||||
}
|
||||
}
|
||||
|
||||
private fun migrationIsRequired(): Boolean {
|
||||
return featureFlags.isEnabled(Flags.CHOOSER_MIGRATION_ENABLED) &&
|
||||
legacyPinPrefsFile.exists() &&
|
||||
chooserComponent?.packageName != null
|
||||
}
|
||||
|
||||
private fun doMigration() {
|
||||
Log.i(TAG, "Beginning migration")
|
||||
|
||||
val legacyPinPrefs = context.getSharedPreferences(legacyPinPrefsFile, MODE_PRIVATE)
|
||||
|
||||
if (legacyPinPrefs.all.isEmpty()) {
|
||||
Log.i(TAG, "No data to migrate, deleting legacy file")
|
||||
} else {
|
||||
sendSharedPreferences(legacyPinPrefs)
|
||||
Log.i(TAG, "Legacy data sent, deleting legacy preferences")
|
||||
|
||||
val legacyPinPrefsEditor = legacyPinPrefs.edit()
|
||||
legacyPinPrefsEditor.clear()
|
||||
if (!legacyPinPrefsEditor.commit()) {
|
||||
Log.e(TAG, "Failed to delete legacy preferences")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!legacyPinPrefsFile.delete()) {
|
||||
Log.e(TAG, "Legacy preferences deleted, but failed to delete legacy preferences file")
|
||||
return
|
||||
}
|
||||
|
||||
Log.i(TAG, "Legacy preference deletion complete")
|
||||
}
|
||||
|
||||
private fun sendSharedPreferences(sharedPreferences: SharedPreferences) {
|
||||
val bundle = Bundle()
|
||||
|
||||
sharedPreferences.all.entries.forEach { (key, value) ->
|
||||
when (value) {
|
||||
is Boolean -> bundle.putBoolean(key, value)
|
||||
else -> Log.e(TAG, "Unsupported preference type for $key: ${value?.javaClass}")
|
||||
}
|
||||
}
|
||||
|
||||
sendBundle(bundle)
|
||||
}
|
||||
|
||||
private fun sendBundle(bundle: Bundle) {
|
||||
val intent =
|
||||
Intent().apply {
|
||||
`package` = chooserComponent?.packageName!!
|
||||
action = BROADCAST_ACTION
|
||||
putExtras(bundle)
|
||||
}
|
||||
broadcastSender.sendBroadcast(intent, BROADCAST_PERMISSION)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "PinnedShareTargetMigration"
|
||||
private const val BROADCAST_ACTION = "android.intent.action.CHOOSER_PIN_MIGRATION"
|
||||
private const val BROADCAST_PERMISSION = "android.permission.RECEIVE_CHOOSER_PIN_MIGRATION"
|
||||
|
||||
class LegacyPinPrefsFileSupplier @Inject constructor(private val context: Context) :
|
||||
Supplier<File> {
|
||||
|
||||
override fun get(): File {
|
||||
val packageDirectory =
|
||||
Environment.getDataUserCePackageDirectory(
|
||||
StorageManager.UUID_PRIVATE_INTERNAL,
|
||||
context.userId,
|
||||
context.packageName,
|
||||
)
|
||||
val sharedPrefsDirectory = File(packageDirectory, "shared_prefs")
|
||||
return File(sharedPrefsDirectory, "chooser_pin_settings.xml")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.systemui.dagger
|
||||
|
||||
import com.android.keyguard.KeyguardBiometricLockoutLogger
|
||||
import com.android.systemui.ChooserPinMigration
|
||||
import com.android.systemui.ChooserSelector
|
||||
import com.android.systemui.CoreStartable
|
||||
import com.android.systemui.LatencyTester
|
||||
@@ -77,13 +76,6 @@ abstract class SystemUICoreStartableModule {
|
||||
@ClassKey(AuthController::class)
|
||||
abstract fun bindAuthController(service: AuthController): CoreStartable
|
||||
|
||||
/** Inject into ChooserPinMigration. */
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(ChooserPinMigration::class)
|
||||
@PerUser
|
||||
abstract fun bindChooserPinMigration(sysui: ChooserPinMigration): CoreStartable
|
||||
|
||||
/** Inject into ChooserCoreStartable. */
|
||||
@Binds
|
||||
@IntoMap
|
||||
|
||||
@@ -613,9 +613,6 @@ object Flags {
|
||||
val SHARESHEET_SCROLLABLE_IMAGE_PREVIEW =
|
||||
releasedFlag(1504, "sharesheet_scrollable_image_preview")
|
||||
|
||||
// TODO(b/274137694) Tracking Bug
|
||||
val CHOOSER_MIGRATION_ENABLED = unreleasedFlag(1505, "chooser_migration_enabled")
|
||||
|
||||
// 1700 - clipboard
|
||||
@JvmField val CLIPBOARD_REMOTE_BEHAVIOR = releasedFlag(1701, "clipboard_remote_behavior")
|
||||
// TODO(b/267162944): Tracking bug
|
||||
|
||||
@@ -1,255 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.content.res.Resources
|
||||
import android.testing.AndroidTestingRunner
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.broadcast.BroadcastSender
|
||||
import com.android.systemui.flags.FakeFeatureFlags
|
||||
import com.android.systemui.flags.Flags
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.kotlinArgumentCaptor
|
||||
import com.android.systemui.util.mockito.whenever
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import java.io.File
|
||||
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.never
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.verifyZeroInteractions
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@SmallTest
|
||||
class ChooserPinMigrationTest : SysuiTestCase() {
|
||||
|
||||
private val fakeFeatureFlags = FakeFeatureFlags()
|
||||
private val fakePreferences =
|
||||
mutableMapOf(
|
||||
"TestPinnedPackage/TestPinnedClass" to true,
|
||||
"TestUnpinnedPackage/TestUnpinnedClass" to false,
|
||||
)
|
||||
private val intent = kotlinArgumentCaptor<Intent>()
|
||||
private val permission = kotlinArgumentCaptor<String>()
|
||||
|
||||
private lateinit var chooserPinMigration: ChooserPinMigration
|
||||
|
||||
@Mock private lateinit var mockContext: Context
|
||||
@Mock private lateinit var mockResources: Resources
|
||||
@Mock
|
||||
private lateinit var mockLegacyPinPrefsFileSupplier:
|
||||
ChooserPinMigration.Companion.LegacyPinPrefsFileSupplier
|
||||
@Mock private lateinit var mockFile: File
|
||||
@Mock private lateinit var mockSharedPreferences: SharedPreferences
|
||||
@Mock private lateinit var mockSharedPreferencesEditor: SharedPreferences.Editor
|
||||
@Mock private lateinit var mockBroadcastSender: BroadcastSender
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
whenever(mockContext.resources).thenReturn(mockResources)
|
||||
whenever(mockContext.getSharedPreferences(any<File>(), anyInt()))
|
||||
.thenReturn(mockSharedPreferences)
|
||||
whenever(mockResources.getString(anyInt())).thenReturn("TestPackage/TestClass")
|
||||
whenever(mockSharedPreferences.all).thenReturn(fakePreferences)
|
||||
whenever(mockSharedPreferences.edit()).thenReturn(mockSharedPreferencesEditor)
|
||||
whenever(mockSharedPreferencesEditor.commit()).thenReturn(true)
|
||||
whenever(mockLegacyPinPrefsFileSupplier.get()).thenReturn(mockFile)
|
||||
whenever(mockFile.exists()).thenReturn(true)
|
||||
whenever(mockFile.delete()).thenReturn(true)
|
||||
fakeFeatureFlags.set(Flags.CHOOSER_MIGRATION_ENABLED, true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun start_performsMigration() {
|
||||
// Arrange
|
||||
chooserPinMigration =
|
||||
ChooserPinMigration(
|
||||
mockContext,
|
||||
fakeFeatureFlags,
|
||||
mockBroadcastSender,
|
||||
mockLegacyPinPrefsFileSupplier,
|
||||
)
|
||||
|
||||
// Act
|
||||
chooserPinMigration.start()
|
||||
|
||||
// Assert
|
||||
verify(mockBroadcastSender).sendBroadcast(intent.capture(), permission.capture())
|
||||
assertThat(intent.value.action).isEqualTo("android.intent.action.CHOOSER_PIN_MIGRATION")
|
||||
assertThat(intent.value.`package`).isEqualTo("TestPackage")
|
||||
assertThat(intent.value.extras?.keySet()).hasSize(2)
|
||||
assertThat(intent.value.hasExtra("TestPinnedPackage/TestPinnedClass")).isTrue()
|
||||
assertThat(intent.value.getBooleanExtra("TestPinnedPackage/TestPinnedClass", false))
|
||||
.isTrue()
|
||||
assertThat(intent.value.hasExtra("TestUnpinnedPackage/TestUnpinnedClass")).isTrue()
|
||||
assertThat(intent.value.getBooleanExtra("TestUnpinnedPackage/TestUnpinnedClass", true))
|
||||
.isFalse()
|
||||
assertThat(permission.value).isEqualTo("android.permission.RECEIVE_CHOOSER_PIN_MIGRATION")
|
||||
|
||||
// Assert
|
||||
verify(mockSharedPreferencesEditor).clear()
|
||||
verify(mockSharedPreferencesEditor).commit()
|
||||
|
||||
// Assert
|
||||
verify(mockFile).delete()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun start_doesNotDeleteLegacyPreferencesFile_whenClearingItFails() {
|
||||
// Arrange
|
||||
whenever(mockSharedPreferencesEditor.commit()).thenReturn(false)
|
||||
chooserPinMigration =
|
||||
ChooserPinMigration(
|
||||
mockContext,
|
||||
fakeFeatureFlags,
|
||||
mockBroadcastSender,
|
||||
mockLegacyPinPrefsFileSupplier,
|
||||
)
|
||||
|
||||
// Act
|
||||
chooserPinMigration.start()
|
||||
|
||||
// Assert
|
||||
verify(mockBroadcastSender).sendBroadcast(intent.capture(), permission.capture())
|
||||
assertThat(intent.value.action).isEqualTo("android.intent.action.CHOOSER_PIN_MIGRATION")
|
||||
assertThat(intent.value.`package`).isEqualTo("TestPackage")
|
||||
assertThat(intent.value.extras?.keySet()).hasSize(2)
|
||||
assertThat(intent.value.hasExtra("TestPinnedPackage/TestPinnedClass")).isTrue()
|
||||
assertThat(intent.value.getBooleanExtra("TestPinnedPackage/TestPinnedClass", false))
|
||||
.isTrue()
|
||||
assertThat(intent.value.hasExtra("TestUnpinnedPackage/TestUnpinnedClass")).isTrue()
|
||||
assertThat(intent.value.getBooleanExtra("TestUnpinnedPackage/TestUnpinnedClass", true))
|
||||
.isFalse()
|
||||
assertThat(permission.value).isEqualTo("android.permission.RECEIVE_CHOOSER_PIN_MIGRATION")
|
||||
|
||||
// Assert
|
||||
verify(mockSharedPreferencesEditor).clear()
|
||||
verify(mockSharedPreferencesEditor).commit()
|
||||
|
||||
// Assert
|
||||
verify(mockFile, never()).delete()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun start_OnlyDeletesLegacyPreferencesFile_whenEmpty() {
|
||||
// Arrange
|
||||
whenever(mockSharedPreferences.all).thenReturn(emptyMap())
|
||||
chooserPinMigration =
|
||||
ChooserPinMigration(
|
||||
mockContext,
|
||||
fakeFeatureFlags,
|
||||
mockBroadcastSender,
|
||||
mockLegacyPinPrefsFileSupplier,
|
||||
)
|
||||
|
||||
// Act
|
||||
chooserPinMigration.start()
|
||||
|
||||
// Assert
|
||||
verifyZeroInteractions(mockBroadcastSender)
|
||||
|
||||
// Assert
|
||||
verifyZeroInteractions(mockSharedPreferencesEditor)
|
||||
|
||||
// Assert
|
||||
verify(mockFile).delete()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun start_DoesNotDoMigration_whenFlagIsDisabled() {
|
||||
// Arrange
|
||||
fakeFeatureFlags.set(Flags.CHOOSER_MIGRATION_ENABLED, false)
|
||||
chooserPinMigration =
|
||||
ChooserPinMigration(
|
||||
mockContext,
|
||||
fakeFeatureFlags,
|
||||
mockBroadcastSender,
|
||||
mockLegacyPinPrefsFileSupplier,
|
||||
)
|
||||
|
||||
// Act
|
||||
chooserPinMigration.start()
|
||||
|
||||
// Assert
|
||||
verifyZeroInteractions(mockBroadcastSender)
|
||||
|
||||
// Assert
|
||||
verifyZeroInteractions(mockSharedPreferencesEditor)
|
||||
|
||||
// Assert
|
||||
verify(mockFile, never()).delete()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun start_DoesNotDoMigration_whenLegacyPreferenceFileNotPresent() {
|
||||
// Arrange
|
||||
whenever(mockFile.exists()).thenReturn(false)
|
||||
chooserPinMigration =
|
||||
ChooserPinMigration(
|
||||
mockContext,
|
||||
fakeFeatureFlags,
|
||||
mockBroadcastSender,
|
||||
mockLegacyPinPrefsFileSupplier,
|
||||
)
|
||||
|
||||
// Act
|
||||
chooserPinMigration.start()
|
||||
|
||||
// Assert
|
||||
verifyZeroInteractions(mockBroadcastSender)
|
||||
|
||||
// Assert
|
||||
verifyZeroInteractions(mockSharedPreferencesEditor)
|
||||
|
||||
// Assert
|
||||
verify(mockFile, never()).delete()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun start_DoesNotDoMigration_whenConfiguredChooserComponentIsInvalid() {
|
||||
// Arrange
|
||||
whenever(mockResources.getString(anyInt())).thenReturn("InvalidComponent")
|
||||
chooserPinMigration =
|
||||
ChooserPinMigration(
|
||||
mockContext,
|
||||
fakeFeatureFlags,
|
||||
mockBroadcastSender,
|
||||
mockLegacyPinPrefsFileSupplier,
|
||||
)
|
||||
|
||||
// Act
|
||||
chooserPinMigration.start()
|
||||
|
||||
// Assert
|
||||
verifyZeroInteractions(mockBroadcastSender)
|
||||
|
||||
// Assert
|
||||
verifyZeroInteractions(mockSharedPreferencesEditor)
|
||||
|
||||
// Assert
|
||||
verify(mockFile, never()).delete()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user