Replacing accessibility service permissions with capability attributes.
Accessibility services can perform special operations such as retrieve the screen content, enable explore by touch, etc. To ensure the user is aware that the service will perform special operations we were using permissions. However, the special operations cannot be performed unless the service is really enabled by the user and it is at this point that we want to notify the user about the service capabilities. This change adds the list of the service capabilities to the enable warining dialog such that the user can asses whether to he/she is fine with this service performing certain special operations. Main change:https://googleplex-android-review.googlesource.com/#/c/298110/ bug:8633951 Change-Id: I1617fa82126b9a674cb74a15d7004a7cc007c7d3
This commit is contained in:
committed by
Svetoslav Ganov
parent
b0746763ba
commit
8fdc564cd3
45
res/layout/enable_accessibility_service_dialog_content.xml
Normal file
45
res/layout/enable_accessibility_service_dialog_content.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2013 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.
|
||||
-->
|
||||
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:scrollbarStyle="outsideOverlay"
|
||||
android:gravity="top">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="16dip"
|
||||
android:paddingEnd="16dip" >
|
||||
|
||||
<TextView android:id="@+id/capabilities_header"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dip"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<LinearLayout android:id="@+id/capabilities"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="10dip" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
@@ -3177,30 +3177,24 @@
|
||||
<!-- Summary for the disabled state of an accessiblity feature. [CHAR LIMIT=10] -->
|
||||
<string name="accessibility_feature_state_off">Off</string>
|
||||
|
||||
<!-- Title for a warning message about security implications of enabling an accessibility service,
|
||||
displayed as a dialog message when the user selects to enable an accessibility service (tablet). [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_service_security_warning_title">Use
|
||||
<!-- Title for a warning about security implications of enabling an accessibility
|
||||
service. [CHAR LIMIT=NONE] -->
|
||||
<string name="enable_service_title">Use
|
||||
<xliff:g id="service" example="TalkBack">%1$s</xliff:g>?</string>
|
||||
<!-- Summary for a warning message about security implications of enabling an accessibility service,
|
||||
displayed as a dialog message when the user selects to enable an accessibility service (tablet). [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_service_security_warning_summary" product="tablet">
|
||||
<xliff:g id="accessibility_service_name">%1$s</xliff:g> can
|
||||
collect all of the text you type, except passwords. This includes personal data such as credit card
|
||||
numbers. It can also collect data about your interactions with the tablet.</string>
|
||||
<!-- Summary for a warning message about security implications of enabling an accessibility service,
|
||||
displayed as a dialog message when the user selects to enable an accessibility service (phone). [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_service_security_warning_summary" product="default">
|
||||
<xliff:g id="accessibility_service_name">%1$s</xliff:g> can
|
||||
collect all of the text you type, except passwords. This includes personal data such as credit card
|
||||
numbers. It can also collect data about your interactions with the phone.</string>
|
||||
<!-- Title for the list of capabilities of an accessibility service. -->
|
||||
<string name="capabilities_list_title"><xliff:g id="service" example="TalkBack">%1$s</xliff:g>
|
||||
needs to:</string>
|
||||
|
||||
<!-- Title for a warning about disabling an accessibility service displayed as a dialog message when the user
|
||||
selects to disable that service. This avoids accidental disabling. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_service_disable_warning_title">Stop
|
||||
<xliff:g id="service" example="TalkBack">%1$s</xliff:g>?</string>
|
||||
<!-- Summary for a warning about disabling accessibility service displayed as a dialog message when the user
|
||||
selects to disable that service. This avoids accidental disabling. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_service_disable_warning_summary">Touching OK will
|
||||
<!-- Title for the capability of an accessibility service to receive events and keys. -->
|
||||
<string name="capability_title_receiveAccessibilityEvents">Observe your actions</string>
|
||||
<!-- Description for the capability of an accessibility service to receive events and keys. -->
|
||||
<string name="capability_desc_receiveAccessibilityEvents">Receive notifications when you\'re
|
||||
interacting with an app.</string>
|
||||
|
||||
<!-- Title for a warning about disabling an accessibility service. [CHAR LIMIT=NONE] -->
|
||||
<string name="disable_service_title">Stop<xliff:g id="service" example="TalkBack">%1$s</xliff:g>?</string>
|
||||
<!-- Message for a warning about disabling accessibility service. [CHAR LIMIT=NONE] -->
|
||||
<string name="disable_service_message">Touching OK will
|
||||
stop <xliff:g id="service" example="TalkBack">%1$s</xliff:g>.</string>
|
||||
|
||||
<!-- Title for the prompt shown as a placeholder if no accessibility serivices are installed. [CHAR LIMIT=50] -->
|
||||
|
@@ -50,12 +50,14 @@ import android.text.TextUtils.SimpleStringSplitter;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
@@ -118,13 +120,9 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
|
||||
private static final String EXTRA_CHECKED = "checked";
|
||||
private static final String EXTRA_TITLE = "title";
|
||||
private static final String EXTRA_SUMMARY = "summary";
|
||||
private static final String EXTRA_ENABLE_WARNING_TITLE = "enable_warning_title";
|
||||
private static final String EXTRA_ENABLE_WARNING_MESSAGE = "enable_warning_message";
|
||||
private static final String EXTRA_DISABLE_WARNING_TITLE = "disable_warning_title";
|
||||
private static final String EXTRA_DISABLE_WARNING_MESSAGE = "disable_warning_message";
|
||||
private static final String EXTRA_SETTINGS_TITLE = "settings_title";
|
||||
private static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name";
|
||||
private static final String EXTRA_SERVICE_COMPONENT_NAME = "service_component_name";
|
||||
private static final String EXTRA_ACCESSIBILITY_SERVICE_INFO = "accessibility_service_info";
|
||||
|
||||
// Dialog IDs.
|
||||
private static final int DIALOG_ID_NO_ACCESSIBILITY_SERVICES = 1;
|
||||
@@ -409,20 +407,6 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
|
||||
}
|
||||
extras.putString(EXTRA_SUMMARY, description);
|
||||
|
||||
CharSequence applicationLabel = info.getResolveInfo().loadLabel(getPackageManager());
|
||||
|
||||
extras.putString(EXTRA_ENABLE_WARNING_TITLE, getString(
|
||||
R.string.accessibility_service_security_warning_title, applicationLabel));
|
||||
extras.putString(EXTRA_ENABLE_WARNING_MESSAGE, getString(
|
||||
R.string.accessibility_service_security_warning_summary, applicationLabel));
|
||||
|
||||
extras.putString(EXTRA_DISABLE_WARNING_TITLE, getString(
|
||||
R.string.accessibility_service_disable_warning_title,
|
||||
applicationLabel));
|
||||
extras.putString(EXTRA_DISABLE_WARNING_MESSAGE, getString(
|
||||
R.string.accessibility_service_disable_warning_summary,
|
||||
applicationLabel));
|
||||
|
||||
String settingsClassName = info.getSettingsActivityName();
|
||||
if (!TextUtils.isEmpty(settingsClassName)) {
|
||||
extras.putString(EXTRA_SETTINGS_TITLE,
|
||||
@@ -432,7 +416,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
|
||||
settingsClassName).flattenToString());
|
||||
}
|
||||
|
||||
extras.putString(EXTRA_SERVICE_COMPONENT_NAME, componentName.flattenToString());
|
||||
extras.putParcelable(EXTRA_ACCESSIBILITY_SERVICE_INFO, info);
|
||||
|
||||
mServicesCategory.addPreference(preference);
|
||||
}
|
||||
@@ -698,10 +682,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
|
||||
}
|
||||
};
|
||||
|
||||
private CharSequence mEnableWarningTitle;
|
||||
private CharSequence mEnableWarningMessage;
|
||||
private CharSequence mDisableWarningTitle;
|
||||
private CharSequence mDisableWarningMessage;
|
||||
private AccessibilityServiceInfo mAccessibilityServiceInfo;
|
||||
|
||||
private String mComponentName;
|
||||
|
||||
@@ -767,32 +748,113 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
|
||||
Settings.Secure.ACCESSIBILITY_ENABLED, accessibilityEnabled ? 1 : 0);
|
||||
}
|
||||
|
||||
// extras.putString(EXTRA_ENABLE_WARNING_TITLE, getString(
|
||||
// R.string.accessibility_service_security_warning_title, applicationLabel));
|
||||
// extras.putString(EXTRA_ENABLE_WARNING_MESSAGE, getString(
|
||||
// R.string.accessibility_service_security_warning_summary, applicationLabel));
|
||||
//
|
||||
// extras.putString(EXTRA_DISABLE_WARNING_TITLE, getString(
|
||||
// R.string.accessibility_service_disable_warning_title,
|
||||
// applicationLabel));
|
||||
// extras.putString(EXTRA_DISABLE_WARNING_MESSAGE, getString(
|
||||
// R.string.accessibility_service_disable_warning_summary,
|
||||
// applicationLabel));
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(int dialogId) {
|
||||
CharSequence title = null;
|
||||
CharSequence message = null;
|
||||
switch (dialogId) {
|
||||
case DIALOG_ID_ENABLE_WARNING:
|
||||
mShownDialogId = DIALOG_ID_ENABLE_WARNING;
|
||||
title = mEnableWarningTitle;
|
||||
message = mEnableWarningMessage;
|
||||
break;
|
||||
case DIALOG_ID_DISABLE_WARNING:
|
||||
mShownDialogId = DIALOG_ID_DISABLE_WARNING;
|
||||
title = mDisableWarningTitle;
|
||||
message = mDisableWarningMessage;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setTitle(title)
|
||||
.setTitle(getString(R.string.enable_service_title,
|
||||
mAccessibilityServiceInfo.getResolveInfo()
|
||||
.loadLabel(getPackageManager())))
|
||||
.setIconAttribute(android.R.attr.alertDialogIcon)
|
||||
.setMessage(message)
|
||||
.setView(createEnableDialogContentView())
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(android.R.string.ok, this)
|
||||
.setNegativeButton(android.R.string.cancel, this)
|
||||
.create();
|
||||
case DIALOG_ID_DISABLE_WARNING:
|
||||
mShownDialogId = DIALOG_ID_DISABLE_WARNING;
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setTitle(getString(R.string.disable_service_title,
|
||||
mAccessibilityServiceInfo.getResolveInfo()
|
||||
.loadLabel(getPackageManager())))
|
||||
.setIconAttribute(android.R.attr.alertDialogIcon)
|
||||
.setMessage(getString(R.string.disable_service_message,
|
||||
mAccessibilityServiceInfo.getResolveInfo()
|
||||
.loadLabel(getPackageManager())))
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(android.R.string.ok, this)
|
||||
.setNegativeButton(android.R.string.cancel, this)
|
||||
.create();
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
private View createEnableDialogContentView() {
|
||||
LayoutInflater inflater = (LayoutInflater) getSystemService(
|
||||
Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
View content = inflater.inflate(R.layout.enable_accessibility_service_dialog_content,
|
||||
null);
|
||||
|
||||
TextView capabilitiesHeaderView = (TextView) content.findViewById(
|
||||
R.id.capabilities_header);
|
||||
capabilitiesHeaderView.setText(getString(R.string.capabilities_list_title,
|
||||
mAccessibilityServiceInfo.getResolveInfo().loadLabel(getPackageManager())));
|
||||
|
||||
LinearLayout capabilitiesView = (LinearLayout) content.findViewById(R.id.capabilities);
|
||||
|
||||
// This capability is implicit for all services.
|
||||
View capabilityView = inflater.inflate(
|
||||
com.android.internal.R.layout.app_permission_item_old, null);
|
||||
|
||||
ImageView imageView = (ImageView) capabilityView.findViewById(
|
||||
com.android.internal.R.id.perm_icon);
|
||||
imageView.setImageDrawable(getResources().getDrawable(
|
||||
com.android.internal.R.drawable.ic_text_dot));
|
||||
|
||||
TextView labelView = (TextView) capabilityView.findViewById(
|
||||
com.android.internal.R.id.permission_group);
|
||||
labelView.setText(getString(R.string.capability_title_receiveAccessibilityEvents));
|
||||
|
||||
TextView descriptionView = (TextView) capabilityView.findViewById(
|
||||
com.android.internal.R.id.permission_list);
|
||||
descriptionView.setText(getString(R.string.capability_desc_receiveAccessibilityEvents));
|
||||
|
||||
List<AccessibilityServiceInfo.CapabilityInfo> capabilities =
|
||||
mAccessibilityServiceInfo.getCapabilityInfos();
|
||||
|
||||
capabilitiesView.addView(capabilityView);
|
||||
|
||||
// Service specific capabilities.
|
||||
final int capabilityCount = capabilities.size();
|
||||
for (int i = 0; i < capabilityCount; i++) {
|
||||
AccessibilityServiceInfo.CapabilityInfo capability = capabilities.get(i);
|
||||
|
||||
capabilityView = inflater.inflate(
|
||||
com.android.internal.R.layout.app_permission_item_old, null);
|
||||
|
||||
imageView = (ImageView) capabilityView.findViewById(
|
||||
com.android.internal.R.id.perm_icon);
|
||||
imageView.setImageDrawable(getResources().getDrawable(
|
||||
com.android.internal.R.drawable.ic_text_dot));
|
||||
|
||||
labelView = (TextView) capabilityView.findViewById(
|
||||
com.android.internal.R.id.permission_group);
|
||||
labelView.setText(getString(capability.titleResId));
|
||||
|
||||
descriptionView = (TextView) capabilityView.findViewById(
|
||||
com.android.internal.R.id.permission_list);
|
||||
descriptionView.setText(getString(capability.descResId));
|
||||
|
||||
capabilitiesView.addView(capabilityView);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -823,24 +885,16 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
|
||||
@Override
|
||||
public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) {
|
||||
if (checked) {
|
||||
if (!TextUtils.isEmpty(mEnableWarningMessage)) {
|
||||
toggleSwitch.setCheckedInternal(false);
|
||||
getArguments().putBoolean(EXTRA_CHECKED, false);
|
||||
showDialog(DIALOG_ID_ENABLE_WARNING);
|
||||
return true;
|
||||
}
|
||||
onPreferenceToggled(mPreferenceKey, true);
|
||||
} else {
|
||||
if (!TextUtils.isEmpty(mDisableWarningMessage)) {
|
||||
toggleSwitch.setCheckedInternal(true);
|
||||
getArguments().putBoolean(EXTRA_CHECKED, true);
|
||||
showDialog(DIALOG_ID_DISABLE_WARNING);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
onPreferenceToggled(mPreferenceKey, false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -859,20 +913,12 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
}
|
||||
// Enable warning title.
|
||||
mEnableWarningTitle = arguments.getCharSequence(
|
||||
AccessibilitySettings.EXTRA_ENABLE_WARNING_TITLE);
|
||||
// Enable warning message.
|
||||
mEnableWarningMessage = arguments.getCharSequence(
|
||||
AccessibilitySettings.EXTRA_ENABLE_WARNING_MESSAGE);
|
||||
// Disable warning title.
|
||||
mDisableWarningTitle = arguments.getString(
|
||||
AccessibilitySettings.EXTRA_DISABLE_WARNING_TITLE);
|
||||
// Disable warning message.
|
||||
mDisableWarningMessage = arguments.getString(
|
||||
AccessibilitySettings.EXTRA_DISABLE_WARNING_MESSAGE);
|
||||
// Component name.
|
||||
mComponentName = arguments.getString(EXTRA_SERVICE_COMPONENT_NAME);
|
||||
|
||||
mAccessibilityServiceInfo = arguments.getParcelable(EXTRA_ACCESSIBILITY_SERVICE_INFO);
|
||||
|
||||
ServiceInfo serviceInfo = mAccessibilityServiceInfo.getResolveInfo().serviceInfo;
|
||||
mComponentName = new ComponentName(serviceInfo.packageName,
|
||||
serviceInfo.name).flattenToString();
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user