diff --git a/res/drawable/ic_pan_tool_18dp.xml b/res/drawable/ic_pan_tool_18dp.xml
new file mode 100644
index 00000000000..3ebfc9ce2c6
--- /dev/null
+++ b/res/drawable/ic_pan_tool_18dp.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
diff --git a/res/drawable/ic_visibility_18dp.xml b/res/drawable/ic_visibility_18dp.xml
new file mode 100644
index 00000000000..9e27815cb76
--- /dev/null
+++ b/res/drawable/ic_visibility_18dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/res/layout/disable_accessibility_service_dialog_content.xml b/res/layout/disable_accessibility_service_dialog_content.xml
new file mode 100644
index 00000000000..e365484d633
--- /dev/null
+++ b/res/layout/disable_accessibility_service_dialog_content.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/enable_accessibility_service_dialog_content.xml b/res/layout/enable_accessibility_service_dialog_content.xml
index e16dc657a30..066c3399621 100644
--- a/res/layout/enable_accessibility_service_dialog_content.xml
+++ b/res/layout/enable_accessibility_service_dialog_content.xml
@@ -23,28 +23,118 @@
android:gravity="top">
+ android:theme="@style/Theme.AlertDialog"
+ style="@style/AccessibilityDialog">
-
+ android:orientation="vertical"
+ android:gravity="center_horizontal"
+ android:paddingLeft="24dp"
+ android:paddingRight="24dp">
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 959a72f1e31..603a34c0fd1 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5065,8 +5065,9 @@
- Use
- %1$s?
+ Allow
+ %1$s to have full contol of your
+ device?
%1$s
needs to:
@@ -5107,11 +5108,43 @@
This level of control is not appropriate for most apps.
+
+ Full control is appropriate for apps
+ that help you with accessibility needs, but not for most apps.
+
+
+
+ View and control screen
+
+
+ It can read all content on the
+ screen and display content over other apps.
+
+
+
+ View and platform actions
+
+
+ It can track your interactions
+ with an app or a hardware sensor, and interact with apps on your behalf.
+
+
+
+ Allow
+
+ Deny
+
+
+ Stop
+
+ Cancel
+
Stop %1$s?
- Tapping OK will
- stop %1$s.
+ Tapping %1$s will
+ stop %2$s.
No services installed
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 8678e6ecec5..80dfeaf05f8 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -562,4 +562,94 @@
- ?android:attr/textColorPrimary
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
index dec734c4c6d..40ac6412d00 100644
--- a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
+++ b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
@@ -22,7 +22,7 @@ import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
-import android.content.DialogInterface;
+import android.graphics.drawable.Drawable;
import android.os.storage.StorageManager;
import android.text.BidiFormatter;
import android.view.LayoutInflater;
@@ -30,10 +30,13 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
+import androidx.core.content.ContextCompat;
import com.android.settings.R;
@@ -44,40 +47,45 @@ import java.util.Locale;
* accessibility service to access user data before the service is enabled
*/
public class AccessibilityServiceWarning {
- public static Dialog createCapabilitiesDialog(Activity parentActivity,
- AccessibilityServiceInfo info, DialogInterface.OnClickListener listener) {
- final AlertDialog ad = new AlertDialog.Builder(parentActivity)
- .setTitle(parentActivity.getString(R.string.enable_service_title,
- getServiceName(parentActivity, info)))
- .setView(createEnableDialogContentView(parentActivity, info))
- .setPositiveButton(android.R.string.ok, listener)
- .setNegativeButton(android.R.string.cancel, listener)
- .create();
-
- final View.OnTouchListener filterTouchListener = (View v, MotionEvent event) -> {
- // Filter obscured touches by consuming them.
- if (((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0)
- || ((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0)) {
- if (event.getAction() == MotionEvent.ACTION_UP) {
- Toast.makeText(v.getContext(), R.string.touch_filtered_warning,
- Toast.LENGTH_SHORT).show();
- }
- return true;
+ private static final View.OnTouchListener filterTouchListener = (View v, MotionEvent event) -> {
+ // Filter obscured touches by consuming them.
+ if (((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0)
+ || ((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0)) {
+ if (event.getAction() == MotionEvent.ACTION_UP) {
+ Toast.makeText(v.getContext(), R.string.touch_filtered_warning,
+ Toast.LENGTH_SHORT).show();
}
- return false;
- };
+ return true;
+ }
+ return false;
+ };
+
+ public static Dialog createCapabilitiesDialog(Activity parentActivity,
+ AccessibilityServiceInfo info, View.OnClickListener listener) {
+ final AlertDialog ad = new AlertDialog.Builder(parentActivity)
+ .setView(createEnableDialogContentView(parentActivity, info, listener))
+ .create();
Window window = ad.getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.privateFlags |= SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
window.setAttributes(params);
ad.create();
- ad.getButton(AlertDialog.BUTTON_POSITIVE).setOnTouchListener(filterTouchListener);
ad.setCanceledOnTouchOutside(true);
return ad;
}
+ public static Dialog createDisableDialog(Activity parentActivity,
+ AccessibilityServiceInfo info, View.OnClickListener listener) {
+ final AlertDialog ad = new AlertDialog.Builder(parentActivity)
+ .setView(createDisableDialogContentView(parentActivity, info, listener))
+ .setCancelable(true)
+ .create();
+
+ return ad;
+ }
+
/**
* Return whether the device is encrypted with legacy full disk encryption. Newer devices
* should be using File Based Encryption.
@@ -96,7 +104,7 @@ public class AccessibilityServiceWarning {
* @return A content view suitable for viewing
*/
private static View createEnableDialogContentView(Context context,
- AccessibilityServiceInfo info) {
+ AccessibilityServiceInfo info, View.OnClickListener listener) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
@@ -114,9 +122,55 @@ public class AccessibilityServiceWarning {
encryptionWarningView.setVisibility(View.GONE);
}
- TextView serviceWarningTextView = content.findViewById(R.id.accessibility_service_warning);
- serviceWarningTextView.setText(context.getString(R.string.accessibility_service_warning,
- getServiceName(context, info)));
+ final Drawable icon;
+ if (info.getResolveInfo().getIconResource() == 0) {
+ icon = ContextCompat.getDrawable(context, R.drawable.ic_accessibility_generic);
+ } else {
+ icon = info.getResolveInfo().loadIcon(context.getPackageManager());
+ }
+
+ ImageView permissionDialogIcon = content.findViewById(
+ R.id.permissionDialog_icon);
+ permissionDialogIcon.setImageDrawable(icon);
+
+ TextView permissionDialogTitle = content.findViewById(R.id.permissionDialog_title);
+ permissionDialogTitle.setText(context.getString(R.string.enable_service_title,
+ getServiceName(context, info)));
+
+ Button permissionAllowButton = content.findViewById(
+ R.id.permission_enable_allow_button);
+ Button permissionDenyButton = content.findViewById(
+ R.id.permission_enable_deny_button);
+ permissionAllowButton.setOnClickListener(listener);
+ permissionAllowButton.setOnTouchListener(filterTouchListener);
+ permissionDenyButton.setOnClickListener(listener);
+
+ return content;
+ }
+
+ private static View createDisableDialogContentView(Context context,
+ AccessibilityServiceInfo info, View.OnClickListener listener) {
+ LayoutInflater inflater = (LayoutInflater) context.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+
+ View content = inflater.inflate(R.layout.disable_accessibility_service_dialog_content,
+ null);
+
+ TextView permissionDialogTitle = content.findViewById(R.id.permissionDialog_disable_title);
+ permissionDialogTitle.setText(context.getString(R.string.disable_service_title,
+ getServiceName(context, info)));
+ TextView permissionDialogMessage = content
+ .findViewById(R.id.permissionDialog_disable_message);
+ permissionDialogMessage.setText(context.getString(R.string.disable_service_message,
+ context.getString(R.string.accessibility_dialog_button_stop),
+ getServiceName(context, info)));
+
+ Button permissionAllowButton = content.findViewById(
+ R.id.permission_disable_stop_button);
+ Button permissionDenyButton = content.findViewById(
+ R.id.permission_disable_cancel_button);
+ permissionAllowButton.setOnClickListener(listener);
+ permissionDenyButton.setOnClickListener(listener);
return content;
}
diff --git a/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java b/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
index 2da4f7a2600..bb262833b42 100644
--- a/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
+++ b/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
@@ -37,6 +37,7 @@ import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
import android.view.accessibility.AccessibilityManager;
+import android.view.View;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
@@ -148,7 +149,7 @@ public class ShortcutServicePickerFragment extends RadioButtonPickerFragment {
}
public static class ConfirmationDialogFragment extends InstrumentedDialogFragment
- implements DialogInterface.OnClickListener {
+ implements View.OnClickListener {
private static final String EXTRA_KEY = "extra_key";
private static final String TAG = "ConfirmationDialogFragment";
private IBinder mToken;
@@ -182,9 +183,10 @@ public class ShortcutServicePickerFragment extends RadioButtonPickerFragment {
}
@Override
- public void onClick(DialogInterface dialog, int which) {
+ public void onClick(View view) {
final Fragment fragment = getTargetFragment();
- if ((which == BUTTON_POSITIVE) && (fragment instanceof ShortcutServicePickerFragment)) {
+ if ((view.getId() == R.id.permission_enable_allow_button)
+ && (fragment instanceof ShortcutServicePickerFragment)) {
final Bundle bundle = getArguments();
((ShortcutServicePickerFragment) fragment).onServiceConfirmed(
bundle.getString(EXTRA_KEY));
diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
index d935d929420..b28d8b5e541 100644
--- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -22,7 +22,6 @@ import android.app.Dialog;
import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.ComponentName;
-import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.net.Uri;
@@ -34,10 +33,9 @@ import android.provider.Settings;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuInflater;
+import android.view.View;
import android.view.accessibility.AccessibilityManager;
-import androidx.appcompat.app.AlertDialog;
-
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.password.ConfirmDeviceCredentialActivity;
@@ -48,7 +46,7 @@ import com.android.settingslib.accessibility.AccessibilityUtils;
import java.util.List;
public class ToggleAccessibilityServicePreferenceFragment
- extends ToggleFeaturePreferenceFragment implements DialogInterface.OnClickListener {
+ extends ToggleFeaturePreferenceFragment implements View.OnClickListener {
private static final int DIALOG_ID_ENABLE_WARNING = 1;
private static final int DIALOG_ID_DISABLE_WARNING = 2;
@@ -67,7 +65,7 @@ public class ToggleAccessibilityServicePreferenceFragment
private ComponentName mComponentName;
- private int mShownDialogId;
+ private Dialog mDialog;
@Override
public int getMetricsCategory() {
@@ -129,35 +127,28 @@ public class ToggleAccessibilityServicePreferenceFragment
public Dialog onCreateDialog(int dialogId) {
switch (dialogId) {
case DIALOG_ID_ENABLE_WARNING: {
- mShownDialogId = DIALOG_ID_ENABLE_WARNING;
final AccessibilityServiceInfo info = getAccessibilityServiceInfo();
if (info == null) {
return null;
}
-
- return AccessibilityServiceWarning
+ mDialog = AccessibilityServiceWarning
.createCapabilitiesDialog(getActivity(), info, this);
+ break;
}
case DIALOG_ID_DISABLE_WARNING: {
- mShownDialogId = DIALOG_ID_DISABLE_WARNING;
AccessibilityServiceInfo info = getAccessibilityServiceInfo();
if (info == null) {
return null;
}
- return new AlertDialog.Builder(getActivity())
- .setTitle(getString(R.string.disable_service_title,
- info.getResolveInfo().loadLabel(getPackageManager())))
- .setMessage(getString(R.string.disable_service_message,
- info.getResolveInfo().loadLabel(getPackageManager())))
- .setCancelable(true)
- .setPositiveButton(android.R.string.ok, this)
- .setNegativeButton(android.R.string.cancel, this)
- .create();
+ mDialog = AccessibilityServiceWarning
+ .createDisableDialog(getActivity(), info, this);
+ break;
}
default: {
throw new IllegalArgumentException();
}
}
+ return mDialog;
}
@Override
@@ -205,30 +196,31 @@ public class ToggleAccessibilityServicePreferenceFragment
}
@Override
- public void onClick(DialogInterface dialog, int which) {
- final boolean checked;
- switch (which) {
- case DialogInterface.BUTTON_POSITIVE:
- if (mShownDialogId == DIALOG_ID_ENABLE_WARNING) {
- if (isFullDiskEncrypted()) {
- String title = createConfirmCredentialReasonMessage();
- Intent intent = ConfirmDeviceCredentialActivity.createIntent(title, null);
- startActivityForResult(intent,
- ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION);
- } else {
- handleConfirmServiceEnabled(true);
- }
+ public void onClick(View view) {
+ switch (view.getId()) {
+ case R.id.permission_enable_allow_button:
+ if (isFullDiskEncrypted()) {
+ String title = createConfirmCredentialReasonMessage();
+ Intent intent = ConfirmDeviceCredentialActivity.createIntent(title, null);
+ startActivityForResult(intent,
+ ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION);
} else {
- handleConfirmServiceEnabled(false);
+ handleConfirmServiceEnabled(true);
}
break;
- case DialogInterface.BUTTON_NEGATIVE:
- checked = (mShownDialogId == DIALOG_ID_DISABLE_WARNING);
- handleConfirmServiceEnabled(checked);
+ case R.id.permission_enable_deny_button:
+ handleConfirmServiceEnabled(false);
+ break;
+ case R.id.permission_disable_stop_button:
+ handleConfirmServiceEnabled(false);
+ break;
+ case R.id.permission_disable_cancel_button:
+ handleConfirmServiceEnabled(true);
break;
default:
throw new IllegalArgumentException();
}
+ mDialog.dismiss();
}
private void handleConfirmServiceEnabled(boolean confirmed) {