Add restricted settings UI in Settings accessibility screeen

If OP_ACCESS_RESTRICTED_SETTINGS is rejected, it means accessibility page
for that app is gray out and app info won't show "unlock restricted settings menu"

If OP_ACCESS_RESTRICTED_SETTINGS is ignored, it means accessibility page
for that app is gray out, but app info shows "unlock restricted settings menu"

If OP_ACCESS_RESTRICTED_SETTINGS is allowed(default), it means users can
access accessibility page for that app.

OP_ACCESS_RESTRICTED_SETTINGS will be changed to ignored if user visited
the restricted settings dialog.

OP_ACCESS_RESTRICTED_SETTINGS will be changed to allowed if user passes
the confirmation screen.

Bug: 202130031
Test: Tested the UI and it works correctly
Change-Id: I3dfb94cee440658b4726a1c3f7265f93cd19ed3e
This commit is contained in:
Ricky Wai
2022-01-25 23:04:26 +00:00
parent 8b8b06404c
commit c76a11f0c1
11 changed files with 315 additions and 25 deletions

View File

@@ -21,6 +21,7 @@ import static com.android.internal.accessibility.AccessibilityShortcutController
import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Activity;
import android.app.AppOpsManager;
import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.ComponentName;
@@ -49,6 +50,7 @@ import java.util.Set;
public class AccessibilityDetailsSettingsFragment extends InstrumentedFragment {
private final static String TAG = "A11yDetailsSettings";
private AppOpsManager mAppOps;
@Override
public int getMetricsCategory() {
@@ -59,6 +61,8 @@ public class AccessibilityDetailsSettingsFragment extends InstrumentedFragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAppOps = getActivity().getSystemService(AppOpsManager.class);
// In case the Intent doesn't have component name, go to a11y services list.
final String extraComponentName = getActivity().getIntent().getStringExtra(
Intent.EXTRA_COMPONENT_NAME);
@@ -127,10 +131,11 @@ public class AccessibilityDetailsSettingsFragment extends InstrumentedFragment {
}
// In case this accessibility service isn't permitted, go to a11y services list.
if (!isServiceAllowed(componentName.getPackageName())) {
if (!isServiceAllowed(info.getResolveInfo().serviceInfo.applicationInfo.uid,
componentName.getPackageName())) {
Log.w(TAG,
"openAccessibilityDetailsSettingsAndFinish: target accessibility service is"
+ "prohibited by Device Admin.");
+ "prohibited by Device Admin or App Op.");
return false;
}
openSubSettings(ToggleAccessibilityServicePreferenceFragment.class.getName(),
@@ -148,11 +153,21 @@ public class AccessibilityDetailsSettingsFragment extends InstrumentedFragment {
}
@VisibleForTesting
boolean isServiceAllowed(String packageName) {
boolean isServiceAllowed(int uid, String packageName) {
final DevicePolicyManager dpm = getContext().getSystemService(DevicePolicyManager.class);
final List<String> permittedServices = dpm.getPermittedAccessibilityServices(
UserHandle.myUserId());
return (permittedServices == null || permittedServices.contains(packageName));
if (permittedServices != null && !permittedServices.contains(packageName)) {
return false;
}
try {
final int mode = mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS,
uid, packageName);
return mode != AppOpsManager.MODE_ERRORED && mode != AppOpsManager.MODE_IGNORED;
} catch (Exception e) {
// Fallback in case if app ops is not available in testing.
return true;
}
}
private AccessibilityServiceInfo getAccessibilityServiceInfo(ComponentName componentName) {