diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index 2113b5d2c62..eeca13941e7 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -42,7 +42,6 @@ import android.content.pm.IPackageManager; import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; import android.content.pm.UserProperties; import android.content.res.Configuration; @@ -107,8 +106,6 @@ import androidx.core.graphics.drawable.RoundedBitmapDrawable; import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; import androidx.fragment.app.Fragment; import androidx.lifecycle.Lifecycle; -import androidx.preference.Preference; -import androidx.preference.PreferenceGroup; import com.android.internal.app.UnlaunchableAppActivity; import com.android.internal.util.ArrayUtils; @@ -179,61 +176,6 @@ public final class Utils extends com.android.settingslib.Utils { public static final String PROPERTY_DELETE_ALL_APP_CLONES_ENABLED = "delete_all_app_clones_enabled"; - /** - * Finds a matching activity for a preference's intent. If a matching - * activity is not found, it will remove the preference. - * - * @param context The context. - * @param parentPreferenceGroup The preference group that contains the - * preference whose intent is being resolved. - * @param preferenceKey The key of the preference whose intent is being - * resolved. - * @param flags 0 or one or more of - * {@link #UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY} - * . - * @return Whether an activity was found. If false, the preference was - * removed. - */ - public static boolean updatePreferenceToSpecificActivityOrRemove(Context context, - PreferenceGroup parentPreferenceGroup, String preferenceKey, int flags) { - - final Preference preference = parentPreferenceGroup.findPreference(preferenceKey); - if (preference == null) { - return false; - } - - final Intent intent = preference.getIntent(); - if (intent != null) { - // Find the activity that is in the system image - final PackageManager pm = context.getPackageManager(); - final List list = pm.queryIntentActivities(intent, 0); - final int listSize = list.size(); - for (int i = 0; i < listSize; i++) { - final ResolveInfo resolveInfo = list.get(i); - if ((resolveInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) - != 0) { - - // Replace the intent with this specific activity - preference.setIntent(new Intent().setClassName( - resolveInfo.activityInfo.packageName, - resolveInfo.activityInfo.name)); - - if ((flags & UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY) != 0) { - // Set the preference title to the activity's label - preference.setTitle(resolveInfo.loadLabel(pm)); - } - - return true; - } - } - } - - // Did not find a matching activity, so remove the preference - parentPreferenceGroup.removePreference(preference); - - return false; - } - /** * Returns true if Monkey is running. */ diff --git a/src/com/android/settings/system/SystemUpdatePreferenceController.kt b/src/com/android/settings/system/SystemUpdatePreferenceController.kt index fa135aa2a9f..87a402e2236 100644 --- a/src/com/android/settings/system/SystemUpdatePreferenceController.kt +++ b/src/com/android/settings/system/SystemUpdatePreferenceController.kt @@ -28,7 +28,6 @@ import androidx.lifecycle.repeatOnLifecycle import androidx.preference.Preference import androidx.preference.PreferenceScreen import com.android.settings.R -import com.android.settings.Utils import com.android.settings.core.BasePreferenceController import com.android.settingslib.spaprivileged.framework.common.userManager import kotlinx.coroutines.launch @@ -36,6 +35,7 @@ import kotlinx.coroutines.launch open class SystemUpdatePreferenceController(context: Context, preferenceKey: String) : BasePreferenceController(context, preferenceKey) { private val userManager: UserManager = context.userManager + private val systemUpdateRepository = SystemUpdateRepository(context) private val clientInitiatedActionRepository = ClientInitiatedActionRepository(context) private lateinit var preference: Preference @@ -48,12 +48,12 @@ open class SystemUpdatePreferenceController(context: Context, preferenceKey: Str super.displayPreference(screen) preference = screen.findPreference(preferenceKey)!! if (isAvailable) { - Utils.updatePreferenceToSpecificActivityOrRemove( - mContext, - screen, - preferenceKey, - Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY, - ) + val intent = systemUpdateRepository.getSystemUpdateIntent() + if (intent != null) { // Replace the intent with this specific activity + preference.intent = intent + } else { // Did not find a matching activity, so remove the preference + screen.removePreference(preference) + } } } diff --git a/src/com/android/settings/system/SystemUpdateRepository.kt b/src/com/android/settings/system/SystemUpdateRepository.kt new file mode 100644 index 00000000000..f8804bea08f --- /dev/null +++ b/src/com/android/settings/system/SystemUpdateRepository.kt @@ -0,0 +1,38 @@ +/* + * 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.settings.system + +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.provider.Settings + +class SystemUpdateRepository(context: Context) { + private val packageManager = context.packageManager + + /** + * Finds a matching activity for the system update intent. + */ + fun getSystemUpdateIntent(): Intent? { + val intent = Intent(Settings.ACTION_SYSTEM_UPDATE_SETTINGS) + return packageManager.resolveActivity(intent, PackageManager.MATCH_SYSTEM_ONLY) + ?.activityInfo + ?.let { activityInfo -> + Intent().setClassName(activityInfo.packageName, activityInfo.name) + } + } +} diff --git a/tests/spa_unit/src/com/android/settings/system/SystemUpdateRepositoryTest.kt b/tests/spa_unit/src/com/android/settings/system/SystemUpdateRepositoryTest.kt new file mode 100644 index 00000000000..ea4617a14fb --- /dev/null +++ b/tests/spa_unit/src/com/android/settings/system/SystemUpdateRepositoryTest.kt @@ -0,0 +1,80 @@ +/* + * 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.settings.system + +import android.content.Context +import android.content.pm.ActivityInfo +import android.content.pm.PackageManager +import android.content.pm.ResolveInfo +import android.provider.Settings +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.eq +import org.mockito.kotlin.argThat +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import org.mockito.kotlin.spy +import org.mockito.kotlin.stub + +@RunWith(AndroidJUnit4::class) +class SystemUpdateRepositoryTest { + private val mockPackageManager = mock() + + private val context: Context = spy(ApplicationProvider.getApplicationContext()) { + on { packageManager } doReturn mockPackageManager + } + + private val repository = SystemUpdateRepository(context) + + @Test + fun getSystemUpdateIntent_noResolveActivity_returnNull() { + val intent = repository.getSystemUpdateIntent() + + assertThat(intent).isNull() + } + + @Test + fun getSystemUpdateIntent_hasResolveActivity_returnIntent() { + mockPackageManager.stub { + on { + resolveActivity( + argThat { action == Settings.ACTION_SYSTEM_UPDATE_SETTINGS }, + eq(PackageManager.MATCH_SYSTEM_ONLY), + ) + } doReturn RESOLVE_INFO + } + + val intent = repository.getSystemUpdateIntent() + + assertThat(intent?.component?.packageName).isEqualTo(PACKAGE_NAME) + assertThat(intent?.component?.className).isEqualTo(ACTIVITY_NAME) + } + + private companion object { + const val PACKAGE_NAME = "package.name" + const val ACTIVITY_NAME = "ActivityName" + val RESOLVE_INFO = ResolveInfo().apply { + activityInfo = ActivityInfo().apply { + packageName = PACKAGE_NAME + name = ACTIVITY_NAME + } + } + } +}