List apps which requested the TURN_SCREEN_ON appOp permission

This reverts commit 94f08e4ba1.
Reason for revert: Re-land with fix (b/278739832#comment8)

Bug: 272053372
Change-Id: I945e543b6e17b682bc88e9e9b0a79775a71dd6f7
Test: manually installed an app which requests the permission and verified it shows up correctly in Settings > Apps > special app access > Turn screen on
Test: atest AppFilterRegistryTest
Test: atest TurnScreenOnDetailsTest
Test: m -j RunSettingsRoboTests
Test: adb shell am start -a android.settings.TURN_SCREEN_ON_SETTINGS
This commit is contained in:
Philip Junker
2023-04-19 11:59:19 +00:00
committed by Android (Google) Code Review
parent 94f08e4ba1
commit ded7f45e6a
15 changed files with 331 additions and 540 deletions

View File

@@ -322,6 +322,7 @@ public class Settings extends SettingsActivity {
public static class PremiumSmsAccessActivity extends SettingsActivity { /* empty */ }
public static class PictureInPictureSettingsActivity extends SettingsActivity { /* empty */ }
public static class TurnScreenOnSettingsActivity extends SettingsActivity { /* empty */ }
public static class AppTurnScreenOnSettingsActivity extends SettingsActivity { /* empty */ }
public static class AppPictureInPictureSettingsActivity extends SettingsActivity { /* empty */ }
public static class ZenAccessSettingsActivity extends SettingsActivity { /* empty */ }
public static class ZenAccessDetailSettingsActivity extends SettingsActivity {}

View File

@@ -0,0 +1,86 @@
/*
* 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.applications;
import android.Manifest;
import android.app.AppOpsManager;
import android.content.Context;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.applications.ApplicationsState.AppFilter;
import java.util.List;
/**
* Connects app op info to the ApplicationsState. Extends {@link AppStateAppOpsBridge} to tailor
* to the semantics of {@link Manifest.permission#TURN_SCREEN_ON}.
* Also provides app filters that can use the info.
*/
public class AppStateTurnScreenOnBridge extends AppStateAppOpsBridge {
private static final String APP_OP_STR = AppOpsManager.OPSTR_TURN_SCREEN_ON;
private static final String[] PERMISSIONS = {
Manifest.permission.TURN_SCREEN_ON
};
private AppOpsManager mAppOpsManager;
public AppStateTurnScreenOnBridge(Context context, ApplicationsState appState,
Callback callback) {
super(context, appState, callback, AppOpsManager.strOpToOp(APP_OP_STR), PERMISSIONS);
mAppOpsManager = context.getSystemService(AppOpsManager.class);
}
@Override
protected void updateExtraInfo(AppEntry app, String pkg, int uid) {
app.extraInfo = getPermissionInfo(pkg, uid);
}
@Override
protected void loadAllExtraInfo() {
super.loadAllExtraInfo();
final List<AppEntry> apps = mAppSession.getAllApps();
for (AppEntry app : apps) {
if (app.extraInfo instanceof PermissionState) {
((PermissionState) app.extraInfo).appOpMode = mAppOpsManager.unsafeCheckOpNoThrow(
APP_OP_STR, app.info.uid, app.info.packageName);
}
}
}
@Override
public PermissionState getPermissionInfo(String pkg, int uid) {
PermissionState ps = super.getPermissionInfo(pkg, uid);
ps.appOpMode = mAppOpsManager.unsafeCheckOpNoThrow(APP_OP_STR, uid, pkg);
return ps;
}
public static final AppFilter FILTER_TURN_SCREEN_ON_APPS = new AppFilter() {
@Override
public void init() {
}
@Override
public boolean filterApp(AppEntry info) {
// If extraInfo != null, it means that the app has declared
// Manifest.permission.TURN_SCREEN_ON and therefore it should appear on our
// list
return info.extraInfo != null;
}
};
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2022 The Android Open Source Project
* 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.
@@ -13,14 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.applications.specialaccess.turnscreenon;
package com.android.settings.applications.appinfo;
import static android.app.Activity.RESULT_CANCELED;
import static android.app.Activity.RESULT_OK;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_ERRORED;
import static android.app.AppOpsManager.OP_TURN_SCREEN_ON;
import android.app.AppOpsManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
import androidx.appcompat.app.AlertDialog;
@@ -29,41 +31,51 @@ import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.SwitchPreference;
import com.android.settings.R;
import com.android.settings.Settings;
import com.android.settings.applications.AppInfoWithHeader;
import com.android.settings.applications.AppStateAppOpsBridge;
import com.android.settings.applications.AppStateTurnScreenOnBridge;
import com.android.settingslib.applications.ApplicationsState;
/**
* Detail page for turn screen on special app access.
*/
public class TurnScreenOnDetails extends AppInfoWithHeader
implements OnPreferenceChangeListener {
public class TurnScreenOnDetails extends AppInfoWithHeader implements OnPreferenceChangeListener {
private static final String KEY_APP_OPS_SETTINGS_SWITCH = "app_ops_settings_switch";
private SwitchPreference mSwitchPref;
private AppStateTurnScreenOnBridge mAppBridge;
private AppOpsManager mAppOpsManager;
private SwitchPreference mSwitchPref;
private AppStateAppOpsBridge.PermissionState mPermissionState;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAppOpsManager = this.getSystemService(AppOpsManager.class);
final Context context = getActivity();
mAppBridge = new AppStateTurnScreenOnBridge(context, mState, /*callback=*/ null);
mAppOpsManager = context.getSystemService(AppOpsManager.class);
// find preferences
addPreferencesFromResource(R.xml.turn_screen_on_permissions_details);
mSwitchPref = (SwitchPreference) findPreference(KEY_APP_OPS_SETTINGS_SWITCH);
// set title/summary for all of them
mSwitchPref.setTitle(R.string.allow_turn_screen_on);
// install event listeners
mSwitchPref.setOnPreferenceChangeListener(this);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean checked = (Boolean) newValue;
if (preference == mSwitchPref) {
setTurnScreenOnAppOp(mPackageInfo.applicationInfo.uid, mPackageName,
(Boolean) newValue);
if (mPermissionState != null && checked != mPermissionState.isPermissible()) {
if (Settings.TurnScreenOnSettingsActivity.class.getName().equals(
getIntent().getComponent().getClassName())) {
setResult(checked ? RESULT_OK : RESULT_CANCELED);
}
setCanTurnScreenOn(checked);
refreshUi();
}
return true;
}
return false;
@@ -71,9 +83,13 @@ public class TurnScreenOnDetails extends AppInfoWithHeader
@Override
protected boolean refreshUi() {
boolean isAllowed = isTurnScreenOnAllowed(mAppOpsManager,
mPackageInfo.applicationInfo.uid, mPackageName);
mSwitchPref.setChecked(isAllowed);
if (mPackageInfo == null || mPackageInfo.applicationInfo == null) {
return false;
}
mPermissionState = mAppBridge.getPermissionInfo(mPackageName,
mPackageInfo.applicationInfo.uid);
mSwitchPref.setEnabled(mPermissionState.permissionDeclared);
mSwitchPref.setChecked(mPermissionState.isPermissible());
return true;
}
@@ -91,28 +107,24 @@ public class TurnScreenOnDetails extends AppInfoWithHeader
* Sets whether the app associated with the given {@code packageName} is allowed to turn the
* screen on.
*/
void setTurnScreenOnAppOp(int uid, String packageName, boolean value) {
final int newMode = value ? MODE_ALLOWED : MODE_ERRORED;
mAppOpsManager.setMode(OP_TURN_SCREEN_ON, uid, packageName, newMode);
}
/**
* @return whether the app associated with the given {@code packageName} is allowed to turn the
* screen on.
*/
static boolean isTurnScreenOnAllowed(AppOpsManager appOpsManager, int uid, String packageName) {
return appOpsManager.checkOpNoThrow(OP_TURN_SCREEN_ON, uid, packageName) == MODE_ALLOWED;
void setCanTurnScreenOn(boolean newState) {
mAppOpsManager.setUidMode(AppOpsManager.OPSTR_TURN_SCREEN_ON,
mPackageInfo.applicationInfo.uid, newState ? MODE_ALLOWED : MODE_ERRORED);
}
/**
* @return the summary for the current state of whether the app associated with the given
* packageName is allowed to turn the screen on.
*/
public static int getPreferenceSummary(AppOpsManager appOpsManager, int uid,
String packageName) {
final boolean enabled = TurnScreenOnDetails.isTurnScreenOnAllowed(appOpsManager, uid,
packageName);
return enabled ? R.string.app_permission_summary_allowed
public static int getSummary(Context context, ApplicationsState.AppEntry entry) {
final AppStateAppOpsBridge.PermissionState state;
if (entry.extraInfo instanceof AppStateAppOpsBridge.PermissionState) {
state = (AppStateAppOpsBridge.PermissionState) entry.extraInfo;
} else {
state = new AppStateTurnScreenOnBridge(context, /*appState=*/ null,
/*callback=*/ null).getPermissionInfo(entry.info.packageName, entry.info.uid);
}
return state.isPermissible() ? R.string.app_permission_summary_allowed
: R.string.app_permission_summary_not_allowed;
}
}

View File

@@ -30,6 +30,7 @@ import com.android.settings.applications.AppStateMediaManagementAppsBridge;
import com.android.settings.applications.AppStateNotificationBridge;
import com.android.settings.applications.AppStateOverlayBridge;
import com.android.settings.applications.AppStatePowerBridge;
import com.android.settings.applications.AppStateTurnScreenOnBridge;
import com.android.settings.applications.AppStateUsageBridge;
import com.android.settings.applications.AppStateWriteSettingsBridge;
import com.android.settings.nfc.AppStateNfcTagAppsBridge;
@@ -67,6 +68,7 @@ public class AppFilterRegistry {
FILTER_LONG_BACKGROUND_TASKS,
FILTER_APPS_CLONE,
FILTER_APPS_NFC_TAG,
FILTER_APPS_TURN_SCREEN_ON,
})
@interface FilterType {}
@@ -98,8 +100,9 @@ public class AppFilterRegistry {
public static final int FILTER_LONG_BACKGROUND_TASKS = 24;
public static final int FILTER_APPS_CLONE = 25;
public static final int FILTER_APPS_NFC_TAG = 26;
private static final int NUM_FILTER_ENTRIES = 27;
// Next id: 27. If you add an entry here, please change NUM_FILTER_ENTRIES.
public static final int FILTER_APPS_TURN_SCREEN_ON = 27;
private static final int NUM_FILTER_ENTRIES = 28;
// Next id: 28. If you add an entry here, please change NUM_FILTER_ENTRIES.
private static AppFilterRegistry sRegistry;
@@ -271,6 +274,12 @@ public class AppFilterRegistry {
AppStateNfcTagAppsBridge.FILTER_APPS_NFC_TAG,
FILTER_APPS_NFC_TAG,
R.string.change_nfc_tag_apps_title);
// Apps that are allowed to turn the screen on.
mFilters[FILTER_APPS_TURN_SCREEN_ON] = new AppFilterItem(
AppStateTurnScreenOnBridge.FILTER_TURN_SCREEN_ON_APPS,
FILTER_APPS_TURN_SCREEN_ON,
R.string.turn_screen_on_title);
}
public static AppFilterRegistry getInstance() {
@@ -313,6 +322,8 @@ public class AppFilterRegistry {
return FILTER_APPS_CLONE;
case ManageApplications.LIST_TYPE_NFC_TAG_APPS:
return FILTER_APPS_NFC_TAG;
case ManageApplications.LIST_TYPE_TURN_SCREEN_ON:
return FILTER_APPS_TURN_SCREEN_ON;
default:
return FILTER_APPS_ALL;
}

View File

@@ -110,6 +110,7 @@ import com.android.settings.Settings.MediaManagementAppsActivity;
import com.android.settings.Settings.NotificationAppListActivity;
import com.android.settings.Settings.NotificationReviewPermissionsActivity;
import com.android.settings.Settings.OverlaySettingsActivity;
import com.android.settings.Settings.TurnScreenOnSettingsActivity;
import com.android.settings.Settings.UsageAccessSettingsActivity;
import com.android.settings.Settings.WriteSettingsActivity;
import com.android.settings.SettingsActivity;
@@ -129,6 +130,7 @@ import com.android.settings.applications.AppStateNotificationBridge;
import com.android.settings.applications.AppStateNotificationBridge.NotificationsSentState;
import com.android.settings.applications.AppStateOverlayBridge;
import com.android.settings.applications.AppStatePowerBridge;
import com.android.settings.applications.AppStateTurnScreenOnBridge;
import com.android.settings.applications.AppStateUsageBridge;
import com.android.settings.applications.AppStateUsageBridge.UsageState;
import com.android.settings.applications.AppStateWriteSettingsBridge;
@@ -142,6 +144,7 @@ import com.android.settings.applications.appinfo.ExternalSourcesDetails;
import com.android.settings.applications.appinfo.LongBackgroundTasksDetails;
import com.android.settings.applications.appinfo.ManageExternalStorageDetails;
import com.android.settings.applications.appinfo.MediaManagementAppsDetails;
import com.android.settings.applications.appinfo.TurnScreenOnDetails;
import com.android.settings.applications.appinfo.WriteSettingsDetails;
import com.android.settings.core.InstrumentedFragment;
import com.android.settings.core.SubSettingLauncher;
@@ -268,6 +271,7 @@ public class ManageApplications extends InstrumentedFragment
public static final int LIST_TYPE_LONG_BACKGROUND_TASKS = 16;
public static final int LIST_TYPE_CLONED_APPS = 17;
public static final int LIST_TYPE_NFC_TAG_APPS = 18;
public static final int LIST_TYPE_TURN_SCREEN_ON = 19;
// List types that should show instant apps.
public static final Set<Integer> LIST_TYPES_WITH_INSTANT = new ArraySet<>(Arrays.asList(
@@ -569,6 +573,8 @@ public class ManageApplications extends InstrumentedFragment
return SettingsEnums.CLONED_APPS;
case LIST_TYPE_NFC_TAG_APPS:
return SettingsEnums.CONFIG_NFC_TAG_APP_PREF;
case LIST_TYPE_TURN_SCREEN_ON:
return SettingsEnums.SETTINGS_TURN_SCREEN_ON_ACCESS;
default:
return SettingsEnums.PAGE_UNKNOWN;
}
@@ -739,6 +745,9 @@ public class ManageApplications extends InstrumentedFragment
startAppInfoFragment(ChangeNfcTagAppsStateDetails.class,
R.string.change_nfc_tag_apps_title);
break;
case LIST_TYPE_TURN_SCREEN_ON:
startAppInfoFragment(TurnScreenOnDetails.class, R.string.turn_screen_on_title);
break;
// TODO: Figure out if there is a way where we can spin up the profile's settings
// process ahead of time, to avoid a long load of data when user clicks on a managed
// app. Maybe when they load the list of apps that contains managed profile apps.
@@ -1066,6 +1075,8 @@ public class ManageApplications extends InstrumentedFragment
screenTitle = R.string.cloned_apps_dashboard_title;
} else if (className.equals(ChangeNfcTagAppsActivity.class.getName())) {
screenTitle = R.string.change_nfc_tag_apps_title;
} else if (className.equals(TurnScreenOnSettingsActivity.class.getName())) {
screenTitle = R.string.turn_screen_on_title;
} else {
if (screenTitle == -1) {
screenTitle = R.string.all_apps;
@@ -1276,6 +1287,8 @@ public class ManageApplications extends InstrumentedFragment
mExtraInfoBridge = new AppStateClonedAppsBridge(mContext, mState, this);
} else if (mManageApplications.mListType == LIST_TYPE_NFC_TAG_APPS) {
mExtraInfoBridge = new AppStateNfcTagAppsBridge(mContext, mState, this);
} else if (mManageApplications.mListType == LIST_TYPE_TURN_SCREEN_ON) {
mExtraInfoBridge = new AppStateTurnScreenOnBridge(mContext, mState, this);
} else {
mExtraInfoBridge = null;
}
@@ -1830,6 +1843,9 @@ public class ManageApplications extends InstrumentedFragment
holder.setSummary(
ChangeNfcTagAppsStateDetails.getSummary(mContext, entry));
break;
case LIST_TYPE_TURN_SCREEN_ON:
holder.setSummary(TurnScreenOnDetails.getSummary(mContext, entry));
break;
default:
holder.updateSizeText(entry, mManageApplications.mInvalidSizeStr, mWhichSize);
break;

View File

@@ -33,6 +33,7 @@ import com.android.settings.Settings.NotificationAppListActivity
import com.android.settings.Settings.NotificationReviewPermissionsActivity
import com.android.settings.Settings.OverlaySettingsActivity
import com.android.settings.Settings.StorageUseActivity
import com.android.settings.Settings.TurnScreenOnSettingsActivity
import com.android.settings.Settings.UsageAccessSettingsActivity
import com.android.settings.Settings.WriteSettingsActivity
import com.android.settings.applications.appinfo.AppLocaleDetails
@@ -51,6 +52,7 @@ import com.android.settings.applications.manageapplications.ManageApplications.L
import com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_NOTIFICATION
import com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_OVERLAY
import com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_STORAGE
import com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_TURN_SCREEN_ON
import com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_USAGE_ACCESS
import com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_WIFI_ACCESS
import com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_WRITE_SETTINGS
@@ -88,6 +90,7 @@ object ManageApplicationsUtil {
LongBackgroundTasksActivity::class to LIST_TYPE_LONG_BACKGROUND_TASKS,
ClonedAppsListActivity::class to LIST_TYPE_CLONED_APPS,
ChangeNfcTagAppsActivity::class to LIST_TYPE_NFC_TAG_APPS,
TurnScreenOnSettingsActivity::class to LIST_TYPE_TURN_SCREEN_ON,
)
@JvmField

View File

@@ -1,215 +0,0 @@
/*
* 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.settings.applications.specialaccess.turnscreenon;
import android.Manifest;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.IconDrawableFactory;
import android.util.Pair;
import android.view.View;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceClickListener;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.EmptyTextSettings;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.widget.AppPreference;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/**
* Settings page for providing special app access to turn the screen of the device on.
*/
@SearchIndexable
public class TurnScreenOnSettings extends EmptyTextSettings {
@VisibleForTesting
static final List<String> IGNORE_PACKAGE_LIST = new ArrayList<>();
static {
IGNORE_PACKAGE_LIST.add(Utils.SYSTEMUI_PACKAGE_NAME);
}
/**
* Comparator by name, then user id.
* {@see PackageItemInfo#DisplayNameComparator}
*/
static class AppComparator implements Comparator<Pair<ApplicationInfo, Integer>> {
private final Collator mCollator = Collator.getInstance();
private final PackageManager mPm;
AppComparator(PackageManager pm) {
mPm = pm;
}
public final int compare(Pair<ApplicationInfo, Integer> a,
Pair<ApplicationInfo, Integer> b) {
CharSequence sa = a.first.loadLabel(mPm);
if (sa == null) sa = a.first.name;
CharSequence sb = b.first.loadLabel(mPm);
if (sb == null) sb = b.first.name;
int nameCmp = mCollator.compare(sa.toString(), sb.toString());
if (nameCmp != 0) {
return nameCmp;
} else {
return a.second - b.second;
}
}
}
private AppOpsManager mAppOpsManager;
private Context mContext;
private PackageManager mPackageManager;
private UserManager mUserManager;
private IconDrawableFactory mIconDrawableFactory;
public TurnScreenOnSettings() {
// Do nothing
}
public TurnScreenOnSettings(PackageManager pm, UserManager um) {
mPackageManager = pm;
mUserManager = um;
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mContext = getActivity();
mPackageManager = mContext.getPackageManager();
mUserManager = mContext.getSystemService(UserManager.class);
mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
mIconDrawableFactory = IconDrawableFactory.newInstance(mContext);
}
@Override
public void onResume() {
super.onResume();
// Clear the prefs
final PreferenceScreen screen = getPreferenceScreen();
screen.removeAll();
// Fetch the set of applications for each profile which have the permission required to turn
// the screen on with a wake lock.
final ArrayList<Pair<ApplicationInfo, Integer>> apps = collectTurnScreenOnApps(
UserHandle.myUserId());
apps.sort(new AppComparator(mPackageManager));
// Rebuild the list of prefs
final Context prefContext = getPrefContext();
for (final Pair<ApplicationInfo, Integer> appData : apps) {
final ApplicationInfo appInfo = appData.first;
final int userId = appData.second;
final UserHandle user = UserHandle.of(userId);
final String packageName = appInfo.packageName;
final CharSequence label = appInfo.loadLabel(mPackageManager);
final Preference pref = new AppPreference(prefContext);
pref.setIcon(mIconDrawableFactory.getBadgedIcon(appInfo, userId));
pref.setTitle(mPackageManager.getUserBadgedLabel(label, user));
pref.setSummary(TurnScreenOnDetails.getPreferenceSummary(mAppOpsManager,
appInfo.uid, packageName));
pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
AppInfoBase.startAppInfoFragment(TurnScreenOnDetails.class,
getString(R.string.turn_screen_on_title),
packageName, appInfo.uid,
TurnScreenOnSettings.this, -1, getMetricsCategory());
return true;
}
});
screen.addPreference(pref);
}
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setEmptyText(R.string.no_applications);
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.turn_screen_on_settings;
}
@Override
public int getMetricsCategory() {
return SettingsEnums.SETTINGS_TURN_SCREEN_ON_ACCESS;
}
/**
* @return the list of applications for the given user and all their profiles that can turn on
* the screen with wake locks.
*/
@VisibleForTesting
ArrayList<Pair<ApplicationInfo, Integer>> collectTurnScreenOnApps(int userId) {
final ArrayList<Pair<ApplicationInfo, Integer>> apps = new ArrayList<>();
final ArrayList<Integer> userIds = new ArrayList<>();
for (UserInfo user : mUserManager.getProfiles(userId)) {
userIds.add(user.id);
}
for (int id : userIds) {
final List<PackageInfo> installedPackages = mPackageManager.getInstalledPackagesAsUser(
/* flags= */ 0, id);
for (PackageInfo packageInfo : installedPackages) {
if (hasTurnScreenOnPermission(mPackageManager, packageInfo.packageName)) {
apps.add(new Pair<>(packageInfo.applicationInfo, id));
}
}
}
return apps;
}
/**
* @return true if the package has the permission to turn the screen on.
*/
@VisibleForTesting
static boolean hasTurnScreenOnPermission(PackageManager packageManager, String packageName) {
if (IGNORE_PACKAGE_LIST.contains(packageName)) {
return false;
}
return packageManager.checkPermission(Manifest.permission.TURN_SCREEN_ON, packageName)
== PackageManager.PERMISSION_GRANTED;
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.turn_screen_on_settings);
}

View File

@@ -50,6 +50,7 @@ import com.android.settings.applications.appinfo.ExternalSourcesDetails;
import com.android.settings.applications.appinfo.LongBackgroundTasksDetails;
import com.android.settings.applications.appinfo.ManageExternalStorageDetails;
import com.android.settings.applications.appinfo.MediaManagementAppsDetails;
import com.android.settings.applications.appinfo.TurnScreenOnDetails;
import com.android.settings.applications.appinfo.WriteSettingsDetails;
import com.android.settings.applications.appops.BackgroundCheckSummary;
import com.android.settings.applications.assist.ManageAssist;
@@ -62,8 +63,6 @@ import com.android.settings.applications.specialaccess.notificationaccess.Notifi
import com.android.settings.applications.specialaccess.pictureinpicture.PictureInPictureDetails;
import com.android.settings.applications.specialaccess.pictureinpicture.PictureInPictureSettings;
import com.android.settings.applications.specialaccess.premiumsms.PremiumSmsAccess;
import com.android.settings.applications.specialaccess.turnscreenon.TurnScreenOnDetails;
import com.android.settings.applications.specialaccess.turnscreenon.TurnScreenOnSettings;
import com.android.settings.applications.specialaccess.vrlistener.VrListenerSettings;
import com.android.settings.applications.specialaccess.zenaccess.ZenAccessDetails;
import com.android.settings.backup.PrivacySettings;
@@ -366,7 +365,6 @@ public class SettingsGateway {
OneHandedSettings.class.getName(),
MobileNetworkSettings.class.getName(),
AppLocaleDetails.class.getName(),
TurnScreenOnSettings.class.getName(),
TurnScreenOnDetails.class.getName(),
NfcAndPaymentFragment.class.getName(),
ColorAndMotionFragment.class.getName(),