summaryrefslogtreecommitdiffstats
path: root/src/com/android/settings/development
diff options
context:
space:
mode:
authorYiwei Zhang <zzyiwei@google.com>2018-12-29 08:52:31 +0800
committerYiwei Zhang <zzyiwei@google.com>2019-04-18 13:37:44 -0700
commitdc62028e85a7142755e2fd5641d46c7b26862826 (patch)
tree566d9738d06a48c824445942a50ee5d0f8c25c09 /src/com/android/settings/development
parenta2754c515bcc94ff4738c98e7e68a1d621660946 (diff)
downloadpackages_apps_Settings-dc62028e85a7142755e2fd5641d46c7b26862826.tar.gz
packages_apps_Settings-dc62028e85a7142755e2fd5641d46c7b26862826.tar.bz2
packages_apps_Settings-dc62028e85a7142755e2fd5641d46c7b26862826.zip
GUP: Display a list of Apps and dialogs
1) Add preference controller for gup dashboard and add list preferences for each entry of the apps 2) Add gup dashboard page to search index 3) Add comprehensive tests for GupPreferenceController Bug: 119221883 Test: make RunSettingsRoboTests Change-Id: Ide4934c0dd3901532723e77e74663e5a7b639026 Merged-In: Ide4934c0dd3901532723e77e74663e5a7b639026
Diffstat (limited to 'src/com/android/settings/development')
-rw-r--r--src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java2
-rw-r--r--src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java1
-rw-r--r--src/com/android/settings/development/GameUpdatePackageDevOptInPreferenceController.java121
-rw-r--r--src/com/android/settings/development/gup/GupPreferenceController.java206
4 files changed, 206 insertions, 124 deletions
diff --git a/src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java b/src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java
index a7bce1451f..b7b27591df 100644
--- a/src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java
+++ b/src/com/android/settings/development/DevelopmentOptionsActivityRequestCodes.java
@@ -25,6 +25,4 @@ public interface DevelopmentOptionsActivityRequestCodes {
int REQUEST_CODE_DEBUG_APP = 1;
int REQUEST_MOCK_LOCATION_APP = 2;
-
- int REQUEST_CODE_GUP_DEV_OPT_IN_APPS = 6;
}
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 575e8fe1ca..8518c7446e 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -400,7 +400,6 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
controllers.add(new SelectDebugAppPreferenceController(context, fragment));
controllers.add(new WaitForDebuggerPreferenceController(context));
controllers.add(new EnableGpuDebugLayersPreferenceController(context));
- controllers.add(new GameUpdatePackageDevOptInPreferenceController(context, fragment));
controllers.add(new VerifyAppsOverUsbPreferenceController(context));
controllers.add(new LogdSizePreferenceController(context));
controllers.add(new LogPersistPreferenceController(context, fragment, lifecycle));
diff --git a/src/com/android/settings/development/GameUpdatePackageDevOptInPreferenceController.java b/src/com/android/settings/development/GameUpdatePackageDevOptInPreferenceController.java
deleted file mode 100644
index be2c7a5dac..0000000000
--- a/src/com/android/settings/development/GameUpdatePackageDevOptInPreferenceController.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2018 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.development;
-
-import static com.android.settings.development.DevelopmentOptionsActivityRequestCodes
- .REQUEST_CODE_GUP_DEV_OPT_IN_APPS;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.provider.Settings;
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
-
-import com.android.settings.R;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.development.DeveloperOptionsPreferenceController;
-
-// TODO(b/119221883): Need to override isAvailable() to return false when updatable graphics driver is not supported.
-public class GameUpdatePackageDevOptInPreferenceController
- extends DeveloperOptionsPreferenceController
- implements PreferenceControllerMixin, OnActivityResultListener {
-
- private static final String GUP_DEV_OPT_IN_APP_KEY = "gup_dev_opt_in_app";
-
- private final DevelopmentSettingsDashboardFragment mFragment;
- private final PackageManager mPackageManager;
-
- public GameUpdatePackageDevOptInPreferenceController(Context context,
- DevelopmentSettingsDashboardFragment fragment) {
- super(context);
- mFragment = fragment;
- mPackageManager = mContext.getPackageManager();
- }
-
- @Override
- public String getPreferenceKey() {
- return GUP_DEV_OPT_IN_APP_KEY;
- }
-
- @Override
- public boolean handlePreferenceTreeClick(Preference preference) {
- if (GUP_DEV_OPT_IN_APP_KEY.equals(preference.getKey())) {
- // pass it on to settings
- final Intent intent = getActivityStartIntent();
- mFragment.startActivityForResult(intent, REQUEST_CODE_GUP_DEV_OPT_IN_APPS);
- return true;
- }
- return false;
- }
-
- @Override
- public void updateState(Preference preference) {
- updatePreferenceSummary();
- }
-
- @Override
- public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode != REQUEST_CODE_GUP_DEV_OPT_IN_APPS
- || resultCode != Activity.RESULT_OK) {
- return false;
- }
- Settings.Global.putString(mContext.getContentResolver(),
- Settings.Global.GUP_DEV_OPT_IN_APPS, data.getAction());
- updatePreferenceSummary();
- return true;
- }
-
- @Override
- protected void onDeveloperOptionsSwitchDisabled() {
- super.onDeveloperOptionsSwitchDisabled();
- mPreference.setSummary(mContext.getResources().getString(
- R.string.gup_dev_opt_in_app_not_set));
- }
-
- @VisibleForTesting
- Intent getActivityStartIntent() {
- Intent intent = new Intent(mContext, AppPicker.class);
- intent.putExtra(AppPicker.EXTRA_DEBUGGABLE, true /* value */);
- return intent;
- }
-
- private void updatePreferenceSummary() {
- final String optInApp = Settings.Global.getString(
- mContext.getContentResolver(), Settings.Global.GUP_DEV_OPT_IN_APPS);
- if (optInApp != null && !optInApp.isEmpty()) {
- mPreference.setSummary(mContext.getResources().getString(
- R.string.gup_dev_opt_in_app_set, getAppLabel(optInApp)));
- } else {
- mPreference.setSummary(mContext.getResources().getString(
- R.string.gup_dev_opt_in_app_not_set));
- }
- }
-
- private String getAppLabel(String applicationPackageName) {
- try {
- final ApplicationInfo ai = mPackageManager.getApplicationInfo(applicationPackageName,
- PackageManager.GET_DISABLED_COMPONENTS);
- final CharSequence lab = mPackageManager.getApplicationLabel(ai);
- return lab != null ? lab.toString() : applicationPackageName;
- } catch (PackageManager.NameNotFoundException e) {
- return applicationPackageName;
- }
- }
-}
diff --git a/src/com/android/settings/development/gup/GupPreferenceController.java b/src/com/android/settings/development/gup/GupPreferenceController.java
new file mode 100644
index 0000000000..762314474e
--- /dev/null
+++ b/src/com/android/settings/development/gup/GupPreferenceController.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2019 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.development.gup;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.provider.Settings;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceGroup;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.development.DevelopmentSettingsEnabler;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class GupPreferenceController
+ extends BasePreferenceController implements Preference.OnPreferenceChangeListener {
+ private final CharSequence[] mEntryList;
+ private final String mPreferenceTitle;
+ private final String mPreferenceDefault;
+ private final String mPreferenceGup;
+ private final String mPreferenceNative;
+
+ private final List<AppInfo> mAppInfos;
+ private final Set<String> mDevOptInApps;
+ private final Set<String> mDevOptOutApps;
+
+ public GupPreferenceController(Context context, String key) {
+ super(context, key);
+
+ final Resources resources = context.getResources();
+ mEntryList = resources.getStringArray(R.array.gup_app_preference_values);
+ mPreferenceTitle = resources.getString(R.string.gup_app_preference_title);
+ mPreferenceDefault = resources.getString(R.string.gup_app_preference_default);
+ mPreferenceGup = resources.getString(R.string.gup_app_preference_gup);
+ mPreferenceNative = resources.getString(R.string.gup_app_preference_native);
+
+ // TODO: Move this task to background if there's potential ANR/Jank.
+ // Update the UI when all the app infos are ready.
+ mAppInfos = getAppInfos(context);
+
+ final ContentResolver contentResolver = context.getContentResolver();
+ mDevOptInApps =
+ getGlobalSettingsString(contentResolver, Settings.Global.GUP_DEV_OPT_IN_APPS);
+ mDevOptOutApps =
+ getGlobalSettingsString(contentResolver, Settings.Global.GUP_DEV_OPT_OUT_APPS);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)
+ ? AVAILABLE
+ : DISABLED_DEPENDENT_SETTING;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ final PreferenceGroup preferenceGroup =
+ (PreferenceGroup) screen.findPreference(getPreferenceKey());
+ if (preferenceGroup == null) {
+ return;
+ }
+
+ for (AppInfo appInfo : mAppInfos) {
+ preferenceGroup.addPreference(
+ createListPreference(appInfo.info.packageName, appInfo.label));
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final ListPreference listPref = (ListPreference) preference;
+ final String value = newValue.toString();
+ final String packageName = preference.getKey();
+
+ // When user choose a new preference, update both Sets for
+ // opt-in and opt-out apps. Then set the new summary text.
+ if (value.equals(mPreferenceNative)) {
+ mDevOptInApps.remove(packageName);
+ mDevOptOutApps.add(packageName);
+ listPref.setSummary(mPreferenceNative);
+ } else if (value.equals(mPreferenceGup)) {
+ mDevOptInApps.add(packageName);
+ mDevOptOutApps.remove(packageName);
+ listPref.setSummary(mPreferenceGup);
+ } else {
+ mDevOptInApps.remove(packageName);
+ mDevOptOutApps.remove(packageName);
+ listPref.setSummary(mPreferenceDefault);
+ }
+
+ // Push the updated Sets for opt-in and opt-out apps to
+ // corresponding Settings.Global.GUP_DEV_OPT_(IN|OUT)_APPS
+ Settings.Global.putString(mContext.getContentResolver(),
+ Settings.Global.GUP_DEV_OPT_IN_APPS, String.join(",", mDevOptInApps));
+ Settings.Global.putString(mContext.getContentResolver(),
+ Settings.Global.GUP_DEV_OPT_OUT_APPS, String.join(",", mDevOptOutApps));
+
+ return true;
+ }
+
+ // AppInfo class to achieve loading the application label only once
+ class AppInfo {
+ AppInfo(PackageManager packageManager, ApplicationInfo applicationInfo) {
+ info = applicationInfo;
+ label = packageManager.getApplicationLabel(applicationInfo).toString();
+ }
+ final ApplicationInfo info;
+ final String label;
+ }
+
+ // List of non-system packages that are installed for the current user.
+ private List<AppInfo> getAppInfos(Context context) {
+ final PackageManager packageManager = context.getPackageManager();
+ final List<ApplicationInfo> applicationInfos =
+ packageManager.getInstalledApplications(0 /* flags */);
+
+ final List<AppInfo> appInfos = new ArrayList<>();
+ for (ApplicationInfo applicationInfo : applicationInfos) {
+ if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+ appInfos.add(new AppInfo(packageManager, applicationInfo));
+ }
+ }
+
+ Collections.sort(appInfos, appInfoComparator);
+
+ return appInfos;
+ }
+
+ // Parse the raw comma separated package names into a String Set
+ private Set<String> getGlobalSettingsString(ContentResolver contentResolver, String name) {
+ final String settingsValue = Settings.Global.getString(contentResolver, name);
+ if (settingsValue == null) {
+ return new HashSet<>();
+ }
+
+ final Set<String> valueSet = new HashSet<>(Arrays.asList(settingsValue.split(",")));
+ valueSet.remove("");
+
+ return valueSet;
+ }
+
+ private final Comparator<AppInfo> appInfoComparator = new Comparator<AppInfo>() {
+ public final int compare(AppInfo a, AppInfo b) {
+ return Collator.getInstance().compare(a.label, b.label);
+ }
+ };
+
+ @VisibleForTesting
+ protected ListPreference createListPreference(String packageName, String appName) {
+ final ListPreference listPreference = new ListPreference(mContext);
+
+ listPreference.setKey(packageName);
+ listPreference.setTitle(appName);
+ listPreference.setDialogTitle(mPreferenceTitle);
+ listPreference.setEntries(mEntryList);
+ listPreference.setEntryValues(mEntryList);
+
+ // Initialize preference default and summary with the opt in/out choices
+ // from Settings.Global.GUP_DEV_OPT_(IN|OUT)_APPS
+ if (mDevOptOutApps.contains(packageName)) {
+ listPreference.setValue(mPreferenceNative);
+ listPreference.setSummary(mPreferenceNative);
+ } else if (mDevOptInApps.contains(packageName)) {
+ listPreference.setValue(mPreferenceGup);
+ listPreference.setSummary(mPreferenceGup);
+ } else {
+ listPreference.setValue(mPreferenceDefault);
+ listPreference.setSummary(mPreferenceDefault);
+ }
+
+ listPreference.setOnPreferenceChangeListener(this);
+
+ return listPreference;
+ }
+}