Merge "Move navigation bar to right-hand-side of seascape."
diff --git a/api/current.txt b/api/current.txt
index 1e90e47..1e16b6ce 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -179,6 +179,9 @@
public static final class R.attr {
ctor public R.attr();
field public static final int absListViewStyle = 16842858; // 0x101006a
+ field public static final int accessibilityEventTypes = 16843642; // 0x101037a
+ field public static final int accessibilityFeedbackType = 16843644; // 0x101037c
+ field public static final int accessibilityFlags = 16843646; // 0x101037e
field public static final int accountPreferences = 16843423; // 0x101029f
field public static final int accountType = 16843407; // 0x101028f
field public static final int action = 16842797; // 0x101002d
@@ -269,6 +272,7 @@
field public static final int cacheColorHint = 16843009; // 0x1010101
field public static final int calendarViewShown = 16843596; // 0x101034c
field public static final int calendarViewStyle = 16843613; // 0x101035d
+ field public static final int canRetrieveWindowContent = 16843647; // 0x101037f
field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230
field public static final deprecated int capitalize = 16843113; // 0x1010169
field public static final int centerBright = 16842956; // 0x10100cc
@@ -655,6 +659,7 @@
field public static final int nextFocusUp = 16842979; // 0x10100e3
field public static final int noHistory = 16843309; // 0x101022d
field public static final int normalScreens = 16843397; // 0x1010285
+ field public static final int notificationTimeout = 16843645; // 0x101037d
field public static final int numColumns = 16843032; // 0x1010118
field public static final int numStars = 16843076; // 0x1010144
field public static final deprecated int numeric = 16843109; // 0x1010165
@@ -671,6 +676,7 @@
field public static final int overScrollFooter = 16843459; // 0x10102c3
field public static final int overScrollHeader = 16843458; // 0x10102c2
field public static final int overScrollMode = 16843457; // 0x10102c1
+ field public static final int packageNames = 16843643; // 0x101037b
field public static final int padding = 16842965; // 0x10100d5
field public static final int paddingBottom = 16842969; // 0x10100d9
field public static final int paddingLeft = 16842966; // 0x10100d6
@@ -1693,11 +1699,18 @@
method protected void onServiceConnected();
method public final void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo);
field public static final java.lang.String SERVICE_INTERFACE = "android.accessibilityservice.AccessibilityService";
+ field public static final java.lang.String SERVICE_META_DATA = "android.accessibilityservice";
}
public class AccessibilityServiceInfo implements android.os.Parcelable {
ctor public AccessibilityServiceInfo();
method public int describeContents();
+ method public static java.lang.String feedbackTypeToString(int);
+ method public static java.lang.String flagToString(int);
+ method public boolean getCanRetrieveWindowContent();
+ method public java.lang.String getId();
+ method public android.content.pm.ResolveInfo getResolveInfo();
+ method public java.lang.String getSettingsActivityName();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
field public static final int DEFAULT = 1; // 0x1
@@ -22250,6 +22263,7 @@
public final class AccessibilityEvent extends android.view.accessibility.AccessibilityRecord implements android.os.Parcelable {
method public void appendRecord(android.view.accessibility.AccessibilityRecord);
method public int describeContents();
+ method public static java.lang.String eventTypeToString(int);
method public long getEventTime();
method public int getEventType();
method public java.lang.CharSequence getPackageName();
@@ -22285,8 +22299,9 @@
}
public final class AccessibilityManager {
- method public java.util.List<android.content.pm.ServiceInfo> getAccessibilityServiceList();
- method public java.util.List<android.content.pm.ServiceInfo> getEnabledAccessibilityServiceList(int);
+ method public deprecated java.util.List<android.content.pm.ServiceInfo> getAccessibilityServiceList();
+ method public java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int);
+ method public java.util.List<android.accessibilityservice.AccessibilityServiceInfo> getInstalledAccessibilityServiceList();
method public void interrupt();
method public boolean isEnabled();
method public void sendAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 03346fe..28fc21a 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -39,21 +39,57 @@
* <p>
* <code>
* <service android:name=".MyAccessibilityService"><br>
- * <intent-filter><br>
- * <action android:name="android.accessibilityservice.AccessibilityService" /><br>
- * </intent-filter><br>
+ * <intent-filter><br>
+ * <action android:name="android.accessibilityservice.AccessibilityService" /><br>
+ * </intent-filter><br>
* </service><br>
* </code>
+ * </p>
* <p>
* The lifecycle of an accessibility service is managed exclusively by the system. Starting
* or stopping an accessibility service is triggered by an explicit user action through
* enabling or disabling it in the device settings. After the system binds to a service it
* calls {@link AccessibilityService#onServiceConnected()}. This method can be
- * overriden by clients that want to perform post binding setup. An accessibility service
- * is configured though setting an {@link AccessibilityServiceInfo} by calling
- * {@link AccessibilityService#setServiceInfo(AccessibilityServiceInfo)}. You can call this
- * method any time to change the service configuration but it is good practice to do that
- * in the overriden {@link AccessibilityService#onServiceConnected()}.
+ * overriden by clients that want to perform post binding setup.
+ * <p>
+ * </p>
+ * There are two approaches for configuring an accessibility service:
+ * <ul>
+ * <li>
+ * Providing a {@link #SERVICE_META_DATA meta-data} entry in the manifest when declaring
+ * the service. A service declaration with a meta-data tag is presented below:
+ * <p>
+ * <code>
+ * <service android:name=".MyAccessibilityService"><br>
+ * <intent-filter><br>
+ * <action android:name="android.accessibilityservice.AccessibilityService" /><br>
+ * </intent-filter><br>
+ * <meta-data android:name="android.accessibilityservice.as" android:resource="@xml/accessibilityservice" /><br>
+ * </service><br>
+ * </code>
+ * </p>
+ * <p>
+ * <strong>
+ * This approach enables setting all accessibility service properties.
+ * </strong>
+ * </p>
+ * </li>
+ * <li>
+ * Calling {@link AccessibilityService#setServiceInfo(AccessibilityServiceInfo)}. Note
+ * that this method can be called any time to change the service configuration.<br>
+ * <p>
+ * <strong>
+ * This approach enables setting only dynamically configurable accessibility
+ * service properties:
+ * {@link AccessibilityServiceInfo#eventTypes},
+ * {@link AccessibilityServiceInfo#feedbackType},
+ * {@link AccessibilityServiceInfo#flags},
+ * {@link AccessibilityServiceInfo#notificationTimeout},
+ * {@link AccessibilityServiceInfo#packageNames}
+ * </strong>
+ * </p>
+ * </li>
+ * </ul>
* <p>
* An accessibility service can be registered for events in specific packages to provide a
* specific type of feedback and is notified with a certain timeout after the last event
@@ -105,6 +141,29 @@
public static final String SERVICE_INTERFACE =
"android.accessibilityservice.AccessibilityService";
+ /**
+ * Name under which an AccessibilityService component publishes information
+ * about itself. This meta-data must reference an XML resource containing
+ * an
+ * <code><{@link android.R.styleable#AccessibilityService accessibility-service}></code>
+ * tag. This is a a sample XML file configuring an accessibility service:
+ * <p>
+ * <code>
+ * <?xml version="1.0" encoding="utf-8"?><br>
+ * <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"<br>
+ * android:eventTypes="typeViewClicked|typeViewFocused"<br>
+ * android:packageNames="foo.bar, foo.baz"<br>
+ * android:feedbackType="feedbackSpoken"<br>
+ * android:notificationTimeout="100"<br>
+ * android:flags="flagDefault"<br>
+ * android:settingsActivity="foo.bar.TestBackActivity"<br>
+ * . . .<br>
+ * />
+ * </code>
+ * </p>
+ */
+ public static final String SERVICE_META_DATA = "android.accessibilityservice";
+
private static final String LOG_TAG = "AccessibilityService";
private AccessibilityServiceInfo mInfo;
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index bf9e07d..b9878cd 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -16,8 +16,25 @@
package android.accessibilityservice;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.util.Xml;
+import android.view.accessibility.AccessibilityEvent;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
/**
* This class describes an {@link AccessibilityService}. The system
@@ -30,6 +47,8 @@
*/
public class AccessibilityServiceInfo implements Parcelable {
+ private static final String TAG_ACCESSIBILITY_SERVICE = "accessibility-service";
+
/**
* Denotes spoken feedback.
*/
@@ -64,7 +83,9 @@
/**
* The event types an {@link AccessibilityService} is interested in.
- *
+ * <p>
+ * <strong>Can be dynamically set at runtime.</strong>
+ * </p>
* @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED
* @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_LONG_CLICKED
* @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_FOCUSED
@@ -77,13 +98,18 @@
/**
* The package names an {@link AccessibilityService} is interested in. Setting
- * to null is equivalent to all packages.
+ * to null is equivalent to all packages.
+ * <p>
+ * <strong>Can be dynamically set at runtime.</strong>
+ * </p>
*/
public String[] packageNames;
/**
* The feedback type an {@link AccessibilityService} provides.
- *
+ * <p>
+ * <strong>Can be dynamically set at runtime.</strong>
+ * </p>
* @see #FEEDBACK_AUDIBLE
* @see #FEEDBACK_GENERIC
* @see #FEEDBACK_HAPTIC
@@ -96,6 +122,9 @@
* The timeout after the most recent event of a given type before an
* {@link AccessibilityService} is notified.
* <p>
+ * <strong>Can be dynamically set at runtime.</strong>.
+ * </p>
+ * <p>
* Note: The event notification timeout is useful to avoid propagating events to the client
* too frequently since this is accomplished via an expensive interprocess call.
* One can think of the timeout as a criteria to determine when event generation has
@@ -106,11 +135,181 @@
/**
* This field represents a set of flags used for configuring an
* {@link AccessibilityService}.
- *
+ * <p>
+ * <strong>Can be dynamically set at runtime.</strong>
+ * </p>
* @see #DEFAULT
*/
public int flags;
+ /**
+ * The unique string Id to identify the accessibility service.
+ */
+ private String mId;
+
+ /**
+ * The Service that implements this accessibility service component.
+ */
+ private ResolveInfo mResolveInfo;
+
+ /**
+ * The accessibility service setting activity's name, used by the system
+ * settings to launch the setting activity of this accessibility service.
+ */
+ private String mSettingsActivityName;
+
+ /**
+ * Flag whether this accessibility service can retrieve screen content.
+ */
+ private boolean mCanRetrieveWindowContent;
+
+ /**
+ * Creates a new instance.
+ */
+ public AccessibilityServiceInfo() {
+ /* do nothing */
+ }
+
+ /**
+ * Creates a new instance.
+ *
+ * @param resolveInfo The service resolve info.
+ * @param context Context for accessing resources.
+ * @throws XmlPullParserException If a XML parsing error occurs.
+ * @throws IOException If a XML parsing error occurs.
+ *
+ * @hide
+ */
+ public AccessibilityServiceInfo(ResolveInfo resolveInfo, Context context)
+ throws XmlPullParserException, IOException {
+ ServiceInfo serviceInfo = resolveInfo.serviceInfo;
+ mId = new ComponentName(serviceInfo.packageName, serviceInfo.name).flattenToShortString();
+ mResolveInfo = resolveInfo;
+
+ String settingsActivityName = null;
+ boolean retrieveScreenContent = false;
+ XmlResourceParser parser = null;
+
+ try {
+ PackageManager packageManager = context.getPackageManager();
+ parser = serviceInfo.loadXmlMetaData(packageManager,
+ AccessibilityService.SERVICE_META_DATA);
+ if (parser == null) {
+ return;
+ }
+
+ int type = 0;
+ while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) {
+ type = parser.next();
+ }
+
+ String nodeName = parser.getName();
+ if (!TAG_ACCESSIBILITY_SERVICE.equals(nodeName)) {
+ throw new XmlPullParserException( "Meta-data does not start with"
+ + TAG_ACCESSIBILITY_SERVICE + " tag");
+ }
+
+ AttributeSet allAttributes = Xml.asAttributeSet(parser);
+ Resources resources = packageManager.getResourcesForApplication(
+ serviceInfo.applicationInfo);
+ TypedArray asAttributes = resources.obtainAttributes(allAttributes,
+ com.android.internal.R.styleable.AccessibilityService);
+ eventTypes = asAttributes.getInt(
+ com.android.internal.R.styleable.AccessibilityService_accessibilityEventTypes,
+ 0);
+ String packageNamez = asAttributes.getString(
+ com.android.internal.R.styleable.AccessibilityService_packageNames);
+ if (packageNamez != null) {
+ packageNames = packageNamez.split("(\\s)*,(\\s)*");
+ }
+ feedbackType = asAttributes.getInt(
+ com.android.internal.R.styleable.AccessibilityService_accessibilityFeedbackType,
+ 0);
+ notificationTimeout = asAttributes.getInt(
+ com.android.internal.R.styleable.AccessibilityService_notificationTimeout,
+ 0);
+ flags = asAttributes.getInt(
+ com.android.internal.R.styleable.AccessibilityService_accessibilityFlags, 0);
+ mSettingsActivityName = asAttributes.getString(
+ com.android.internal.R.styleable.AccessibilityService_settingsActivity);
+ mCanRetrieveWindowContent = asAttributes.getBoolean(
+ com.android.internal.R.styleable.AccessibilityService_canRetrieveWindowContent,
+ false);
+ asAttributes.recycle();
+ } catch (NameNotFoundException e) {
+ throw new XmlPullParserException( "Unable to create context for: "
+ + serviceInfo.packageName);
+ } finally {
+ if (parser != null) {
+ parser.close();
+ }
+ }
+ }
+
+ /**
+ * Updates the properties that an AccessibilitySerivice can change dynamically.
+ *
+ * @param other The info from which to update the properties.
+ *
+ * @hide
+ */
+ public void updateDynamicallyConfigurableProperties(AccessibilityServiceInfo other) {
+ eventTypes = other.eventTypes;
+ packageNames = other.packageNames;
+ feedbackType = other.feedbackType;
+ notificationTimeout = other.notificationTimeout;
+ flags = other.flags;
+ }
+
+ /**
+ * The accessibility service id.
+ * <p>
+ * <strong>Generated by the system.</strong>
+ * </p>
+ * @return The id.
+ */
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * The service {@link ResolveInfo}.
+ * <p>
+ * <strong>Generated by the system.</strong>
+ * </p>
+ * @return The info.
+ */
+ public ResolveInfo getResolveInfo() {
+ return mResolveInfo;
+ }
+
+ /**
+ * The settings activity name.
+ * <p>
+ * <strong>Statically set from
+ * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
+ * </p>
+ * @return The settings activity name.
+ */
+ public String getSettingsActivityName() {
+ return mSettingsActivityName;
+ }
+
+ /**
+ * Whether this service can retrieve the currently focused window content.
+ * <p>
+ * <strong>Statically set from
+ * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
+ * </p>
+ * @return True screen content is retrieved.
+ */
+ public boolean getCanRetrieveWindowContent() {
+ return mCanRetrieveWindowContent;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public int describeContents() {
return 0;
}
@@ -121,6 +320,142 @@
parcel.writeInt(feedbackType);
parcel.writeLong(notificationTimeout);
parcel.writeInt(flags);
+ parcel.writeString(mId);
+ parcel.writeParcelable(mResolveInfo, 0);
+ parcel.writeString(mSettingsActivityName);
+ parcel.writeInt(mCanRetrieveWindowContent ? 1 : 0);
+ }
+
+ private void initFromParcel(Parcel parcel) {
+ eventTypes = parcel.readInt();
+ packageNames = parcel.readStringArray();
+ feedbackType = parcel.readInt();
+ notificationTimeout = parcel.readLong();
+ flags = parcel.readInt();
+ mId = parcel.readString();
+ mResolveInfo = parcel.readParcelable(null);
+ mSettingsActivityName = parcel.readString();
+ mCanRetrieveWindowContent = (parcel.readInt() == 1);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder();
+ appendEventTypes(stringBuilder, eventTypes);
+ stringBuilder.append(", ");
+ appendPackageNames(stringBuilder, packageNames);
+ stringBuilder.append(", ");
+ appendFeedbackTypes(stringBuilder, feedbackType);
+ stringBuilder.append(", ");
+ stringBuilder.append("notificationTimeout: ").append(notificationTimeout);
+ stringBuilder.append(", ");
+ appendFlags(stringBuilder, flags);
+ stringBuilder.append(", ");
+ stringBuilder.append("id: ").append(mId);
+ stringBuilder.append(", ");
+ stringBuilder.append("resolveInfo: ").append(mResolveInfo);
+ stringBuilder.append(", ");
+ stringBuilder.append("settingsActivityName: ").append(mSettingsActivityName);
+ stringBuilder.append(", ");
+ stringBuilder.append("retrieveScreenContent: ").append(mCanRetrieveWindowContent);
+ return stringBuilder.toString();
+ }
+
+ private static void appendFeedbackTypes(StringBuilder stringBuilder, int feedbackTypes) {
+ stringBuilder.append("feedbackTypes:");
+ stringBuilder.append("[");
+ while (feedbackTypes != 0) {
+ final int feedbackTypeBit = (1 << Integer.numberOfTrailingZeros(feedbackTypes));
+ stringBuilder.append(feedbackTypeToString(feedbackTypeBit));
+ feedbackTypes &= ~feedbackTypeBit;
+ if (feedbackTypes != 0) {
+ stringBuilder.append(", ");
+ }
+ }
+ stringBuilder.append("]");
+ }
+
+ private static void appendPackageNames(StringBuilder stringBuilder, String[] packageNames) {
+ stringBuilder.append("packageNames:");
+ stringBuilder.append("[");
+ if (packageNames != null) {
+ final int packageNameCount = packageNames.length;
+ for (int i = 0; i < packageNameCount; i++) {
+ stringBuilder.append(packageNames[i]);
+ if (i < packageNameCount - 1) {
+ stringBuilder.append(", ");
+ }
+ }
+ }
+ stringBuilder.append("]");
+ }
+
+ private static void appendEventTypes(StringBuilder stringBuilder, int eventTypes) {
+ stringBuilder.append("eventTypes:");
+ stringBuilder.append("[");
+ while (eventTypes != 0) {
+ final int eventTypeBit = (1 << Integer.numberOfTrailingZeros(eventTypes));
+ stringBuilder.append(AccessibilityEvent.eventTypeToString(eventTypeBit));
+ eventTypes &= ~eventTypeBit;
+ if (eventTypes != 0) {
+ stringBuilder.append(", ");
+ }
+ }
+ stringBuilder.append("]");
+ }
+
+ private static void appendFlags(StringBuilder stringBuilder, int flags) {
+ stringBuilder.append("flags:");
+ stringBuilder.append("[");
+ while (flags != 0) {
+ final int flagBit = (1 << Integer.numberOfTrailingZeros(flags));
+ stringBuilder.append(flagToString(flagBit));
+ flags &= ~flagBit;
+ if (flags != 0) {
+ stringBuilder.append(", ");
+ }
+ }
+ stringBuilder.append("]");
+ }
+
+ /**
+ * Returns the string representation of a feedback type. For example,
+ * {@link #FEEDBACK_SPOKEN} is represented by the string FEEDBACK_SPOKEN.
+ *
+ * @param feedbackType The feedback type.
+ * @return The string representation.
+ */
+ public static String feedbackTypeToString(int feedbackType) {
+ switch (feedbackType) {
+ case FEEDBACK_AUDIBLE:
+ return "FEEDBACK_AUDIBLE";
+ case FEEDBACK_HAPTIC:
+ return "FEEDBACK_HAPTIC";
+ case FEEDBACK_GENERIC:
+ return "FEEDBACK_GENERIC";
+ case FEEDBACK_SPOKEN:
+ return "FEEDBACK_SPOKEN";
+ case FEEDBACK_VISUAL:
+ return "FEEDBACK_VISUAL";
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Returns the string representation of a flag. For example,
+ * {@link #DEFAULT} is represented by the string DEFAULT.
+ *
+ * @param flag The flag.
+ * @return The string representation.
+ */
+ public static String flagToString(int flag) {
+ switch (flag) {
+ case DEFAULT:
+ return "DEFAULT";
+ default:
+ return null;
+ }
}
/**
@@ -130,11 +465,7 @@
new Parcelable.Creator<AccessibilityServiceInfo>() {
public AccessibilityServiceInfo createFromParcel(Parcel parcel) {
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
- info.eventTypes = parcel.readInt();
- info.packageNames = parcel.readStringArray();
- info.feedbackType = parcel.readInt();
- info.notificationTimeout = parcel.readLong();
- info.flags = parcel.readInt();
+ info.initFromParcel(parcel);
return info;
}
diff --git a/core/java/android/nfc/tech/MifareUltralight.java b/core/java/android/nfc/tech/MifareUltralight.java
index 87c8d99..42c2e3e 100644
--- a/core/java/android/nfc/tech/MifareUltralight.java
+++ b/core/java/android/nfc/tech/MifareUltralight.java
@@ -18,6 +18,7 @@
import android.nfc.Tag;
import android.nfc.TagLostException;
+import android.os.Bundle;
import android.os.RemoteException;
import java.io.IOException;
@@ -69,6 +70,9 @@
private static final int NXP_MANUFACTURER_ID = 0x04;
private static final int MAX_PAGE_COUNT = 256;
+ /** @hide */
+ public static final String EXTRA_IS_UL_C = "isulc";
+
private int mType;
/**
@@ -101,10 +105,12 @@
mType = TYPE_UNKNOWN;
if (a.getSak() == 0x00 && tag.getId()[0] == NXP_MANUFACTURER_ID) {
- // could be UL or UL-C
- //TODO: stack should use NXP AN1303 procedure to make a best guess
- // attempt at classifying Ultralight vs Ultralight C.
- mType = TYPE_ULTRALIGHT;
+ Bundle extras = tag.getTechExtras(TagTechnology.MIFARE_ULTRALIGHT);
+ if (extras.getBoolean(EXTRA_IS_UL_C)) {
+ mType = TYPE_ULTRALIGHT_C;
+ } else {
+ mType = TYPE_ULTRALIGHT;
+ }
}
}
diff --git a/core/java/android/text/method/WordIterator.java b/core/java/android/text/method/WordIterator.java
index b250414..af524ee 100644
--- a/core/java/android/text/method/WordIterator.java
+++ b/core/java/android/text/method/WordIterator.java
@@ -213,7 +213,8 @@
private void checkOffsetIsValid(int offset) {
if (offset < 0 || offset > mCurrent.length()) {
- final String message = "Valid range is [0, " + mCurrent.length() + "]";
+ final String message = "Invalid offset: " + offset +
+ ". Valid range is [0, " + mCurrent.length() + "]";
throw new IllegalArgumentException(message);
}
}
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java
index 38903ab..1c3709f 100644
--- a/core/java/android/util/Log.java
+++ b/core/java/android/util/Log.java
@@ -20,6 +20,7 @@
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.net.UnknownHostException;
/**
* API for sending log output.
@@ -302,6 +303,17 @@
if (tr == null) {
return "";
}
+
+ // This is to reduce the amount of log spew that apps do in the non-error
+ // condition of the network being unavailable.
+ Throwable t = tr;
+ while (t != null) {
+ if (t instanceof UnknownHostException) {
+ return "";
+ }
+ t = t.getCause();
+ }
+
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
tr.printStackTrace(pw);
diff --git a/core/java/android/view/Gravity.java b/core/java/android/view/Gravity.java
index 176c487..b2a35d3 100644
--- a/core/java/android/view/Gravity.java
+++ b/core/java/android/view/Gravity.java
@@ -345,18 +345,12 @@
* if horizontal direction is LTR, then BEFORE will set LEFT and AFTER will set RIGHT.
* if horizontal direction is RTL, then BEFORE will set RIGHT and AFTER will set LEFT.
*
- * If no horizontal direction is found, then just add LEFT to the existing gravity
- *
* @param gravity The gravity to convert to absolute (horizontal) values.
* @param isRtl Whether the layout is right-to-left.
* @return gravity converted to absolute (horizontal) values.
*/
public static int getAbsoluteGravity(int gravity, boolean isRtl) {
int result = gravity;
- // Set default gravity, if no horizontal gravity is specified
- if ((result & HORIZONTAL_GRAVITY_MASK) == 0) {
- result |= Gravity.LEFT;
- }
// If layout is script specific and gravity is horizontal relative (BEFORE or AFTER)
if ((result & RELATIVE_HORIZONTAL_DIRECTION) > 0) {
if ((result & Gravity.BEFORE) == Gravity.BEFORE) {
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 5e18f55..7b80797b 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -516,9 +516,9 @@
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
- builder.append("; EventType: " + mEventType);
- builder.append("; EventTime: " + mEventTime);
- builder.append("; PackageName: " + mPackageName);
+ builder.append("; EventType: ").append(eventTypeToString(mEventType));
+ builder.append("; EventTime: ").append(mEventTime);
+ builder.append("; PackageName: ").append(mPackageName);
builder.append(" \n{\n");
builder.append(super.toString());
builder.append("\n");
@@ -535,6 +535,42 @@
}
/**
+ * Returns the string representation of an event type. For example,
+ * {@link #TYPE_VIEW_CLICKED} is represented by the string TYPE_VIEW_CLICKED.
+ *
+ * @param feedbackType The event type
+ * @return The string representation.
+ */
+ public static String eventTypeToString(int feedbackType) {
+ switch (feedbackType) {
+ case TYPE_VIEW_CLICKED:
+ return "TYPE_VIEW_CLICKED";
+ case TYPE_VIEW_LONG_CLICKED:
+ return "TYPE_VIEW_LONG_CLICKED";
+ case TYPE_VIEW_SELECTED:
+ return "TYPE_VIEW_SELECTED";
+ case TYPE_VIEW_FOCUSED:
+ return "TYPE_VIEW_FOCUSED";
+ case TYPE_VIEW_TEXT_CHANGED:
+ return "TYPE_VIEW_TEXT_CHANGED";
+ case TYPE_WINDOW_STATE_CHANGED:
+ return "TYPE_WINDOW_STATE_CHANGED";
+ case TYPE_VIEW_HOVER_ENTER:
+ return "TYPE_VIEW_HOVER_ENTER";
+ case TYPE_VIEW_HOVER_EXIT:
+ return "TYPE_VIEW_HOVER_EXIT";
+ case TYPE_NOTIFICATION_STATE_CHANGED:
+ return "TYPE_NOTIFICATION_STATE_CHANGED";
+ case TYPE_TOUCH_EXPLORATION_GESTURE_START:
+ return "TYPE_TOUCH_EXPLORATION_GESTURE_START";
+ case TYPE_TOUCH_EXPLORATION_GESTURE_END:
+ return "TYPE_TOUCH_EXPLORATION_GESTURE_END";
+ default:
+ return null;
+ }
+ }
+
+ /**
* @see Parcelable.Creator
*/
public static final Parcelable.Creator<AccessibilityEvent> CREATOR =
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index dd77193..88f8878 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -16,7 +16,6 @@
package android.view.accessibility;
-import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.Context;
import android.content.pm.ServiceInfo;
@@ -30,6 +29,7 @@
import android.os.SystemClock;
import android.util.Log;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -201,11 +201,30 @@
* Returns the {@link ServiceInfo}s of the installed accessibility services.
*
* @return An unmodifiable list with {@link ServiceInfo}s.
+ *
+ * @deprecated Use {@link #getInstalledAccessibilityServiceList()}
*/
+ @Deprecated
public List<ServiceInfo> getAccessibilityServiceList() {
- List<ServiceInfo> services = null;
+ List<AccessibilityServiceInfo> infos = getInstalledAccessibilityServiceList();
+ List<ServiceInfo> services = new ArrayList<ServiceInfo>();
+ final int infoCount = infos.size();
+ for (int i = 0; i < infoCount; i++) {
+ AccessibilityServiceInfo info = infos.get(i);
+ services.add(info.getResolveInfo().serviceInfo);
+ }
+ return Collections.unmodifiableList(services);
+ }
+
+ /**
+ * Returns the {@link AccessibilityServiceInfo}s of the installed accessibility services.
+ *
+ * @return An unmodifiable list with {@link AccessibilityServiceInfo}s.
+ */
+ public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList() {
+ List<AccessibilityServiceInfo> services = null;
try {
- services = mService.getAccessibilityServiceList();
+ services = mService.getInstalledAccessibilityServiceList();
if (DEBUG) {
Log.i(LOG_TAG, "Installed AccessibilityServices " + services);
}
@@ -216,20 +235,14 @@
}
/**
- * Returns the {@link ServiceInfo}s of the enabled accessibility services
+ * Returns the {@link AccessibilityServiceInfo}s of the enabled accessibility services
* for a given feedback type.
*
- * @param feedbackType The type of feedback.
- * @return An unmodifiable list with {@link ServiceInfo}s.
- *
- * @see AccessibilityServiceInfo#FEEDBACK_AUDIBLE
- * @see AccessibilityServiceInfo#FEEDBACK_HAPTIC
- * @see AccessibilityServiceInfo#FEEDBACK_SPOKEN
- * @see AccessibilityServiceInfo#FEEDBACK_VISUAL
- * @see AccessibilityServiceInfo#FEEDBACK_GENERIC
+ * @param feedbackType The feedback type (can be bitwise or of multiple types).
+ * @return An unmodifiable list with {@link AccessibilityServiceInfo}s.
*/
- public List<ServiceInfo> getEnabledAccessibilityServiceList(int feedbackType) {
- List<ServiceInfo> services = null;
+ public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType) {
+ List<AccessibilityServiceInfo> services = null;
try {
services = mService.getEnabledAccessibilityServiceList(feedbackType);
if (DEBUG) {
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index aaaae32..6b2aae2 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -17,9 +17,9 @@
package android.view.accessibility;
+import android.accessibilityservice.AccessibilityServiceInfo;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.IAccessibilityManagerClient;
-import android.content.pm.ServiceInfo;
/**
* Interface implemented by the AccessibilityManagerService called by
@@ -33,9 +33,9 @@
boolean sendAccessibilityEvent(in AccessibilityEvent uiEvent);
- List<ServiceInfo> getAccessibilityServiceList();
+ List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList();
- List<ServiceInfo> getEnabledAccessibilityServiceList(int feedbackType);
+ List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType);
void interrupt();
}
diff --git a/core/java/android/webkit/JWebCoreJavaBridge.java b/core/java/android/webkit/JWebCoreJavaBridge.java
index 12391df..5b78586 100644
--- a/core/java/android/webkit/JWebCoreJavaBridge.java
+++ b/core/java/android/webkit/JWebCoreJavaBridge.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.net.ProxyProperties;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
@@ -294,6 +295,20 @@
mContentUriToFilePathMap.put(contentUri, path);
}
+ public void updateProxy(ProxyProperties proxyProperties) {
+ if (proxyProperties == null) {
+ nativeUpdateProxy("", "");
+ return;
+ }
+
+ String host = proxyProperties.getHost();
+ int port = proxyProperties.getPort();
+ if (port != 0)
+ host += ":" + port;
+
+ nativeUpdateProxy(host, proxyProperties.getExclusionList());
+ }
+
private native void nativeConstructor();
private native void nativeFinalize();
private native void sharedTimerFired();
@@ -304,5 +319,5 @@
public native void addPackageNames(Set<String> packageNames);
public native void addPackageName(String packageName);
public native void removePackageName(String packageName);
- public native void updateProxy(String newProxy);
+ public native void nativeUpdateProxy(String newProxy, String exclusionList);
}
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index a480b84..d54230c 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -34,6 +34,7 @@
import android.text.DynamicLayout;
import android.text.Editable;
import android.text.InputFilter;
+import android.text.InputType;
import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
@@ -853,7 +854,7 @@
public void setAdapterCustom(AutoCompleteAdapter adapter) {
if (adapter != null) {
setInputType(getInputType()
- | EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE);
+ | InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE);
adapter.setTextView(this);
if (mAutoFillable) {
setOnItemClickListener(this);
@@ -934,7 +935,7 @@
*/
/* package */ void setInPassword(boolean inPassword) {
if (inPassword) {
- setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.
+ setInputType(InputType.TYPE_CLASS_TEXT | EditorInfo.
TYPE_TEXT_VARIATION_WEB_PASSWORD);
createBackground();
}
@@ -1146,8 +1147,8 @@
boolean single = true;
boolean inPassword = false;
int maxLength = -1;
- int inputType = EditorInfo.TYPE_CLASS_TEXT
- | EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT;
+ int inputType = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT;
int imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
| EditorInfo.IME_FLAG_NO_FULLSCREEN;
if (TEXT_AREA != type
@@ -1160,9 +1161,9 @@
break;
case TEXT_AREA:
single = false;
- inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
- | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES
- | EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT;
+ inputType |= InputType.TYPE_TEXT_FLAG_MULTI_LINE
+ | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
+ | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
imeOptions |= EditorInfo.IME_ACTION_NONE;
break;
case PASSWORD:
@@ -1173,17 +1174,21 @@
imeOptions |= EditorInfo.IME_ACTION_SEARCH;
break;
case EMAIL:
- inputType |= EditorInfo.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
+ // inputType needs to be overwritten because of the different text variation.
+ inputType = InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
imeOptions |= EditorInfo.IME_ACTION_GO;
break;
case NUMBER:
- inputType |= EditorInfo.TYPE_CLASS_NUMBER;
+ // inputType needs to be overwritten because of the different class.
+ inputType = InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_NORMAL;
// Number and telephone do not have both a Tab key and an
// action, so set the action to NEXT
imeOptions |= EditorInfo.IME_ACTION_NEXT;
break;
case TELEPHONE:
- inputType |= EditorInfo.TYPE_CLASS_PHONE;
+ // inputType needs to be overwritten because of the different class.
+ inputType = InputType.TYPE_CLASS_PHONE;
imeOptions |= EditorInfo.IME_ACTION_NEXT;
break;
case URL:
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 61a69ca..3c2c8f6 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1067,20 +1067,10 @@
private static void handleProxyBroadcast(Intent intent) {
ProxyProperties proxyProperties = (ProxyProperties)intent.getExtra(Proxy.EXTRA_PROXY_INFO);
if (proxyProperties == null || proxyProperties.getHost() == null) {
- WebViewCore.sendStaticMessage(EventHub.PROXY_CHANGED, "");
+ WebViewCore.sendStaticMessage(EventHub.PROXY_CHANGED, null);
return;
}
-
- String host = proxyProperties.getHost();
- int port = proxyProperties.getPort();
- if (port != 0)
- host += ":" + port;
-
- // TODO: Handle exclusion list
- // The plan is to make an AndroidProxyResolver, and handle the blacklist
- // there
- String exclusionList = proxyProperties.getExclusionList();
- WebViewCore.sendStaticMessage(EventHub.PROXY_CHANGED, host);
+ WebViewCore.sendStaticMessage(EventHub.PROXY_CHANGED, proxyProperties);
}
/*
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index db5ff54..13a9793 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -24,6 +24,7 @@
import android.graphics.Rect;
import android.graphics.Region;
import android.media.MediaFile;
+import android.net.ProxyProperties;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
@@ -708,7 +709,7 @@
throw new IllegalStateException(
"No WebView has been created in this process!");
}
- BrowserFrame.sJavaBridge.updateProxy((String) msg.obj);
+ BrowserFrame.sJavaBridge.updateProxy((ProxyProperties)msg.obj);
break;
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a73a6cf..9ec3a26 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -9163,6 +9163,13 @@
public abstract void updatePosition(float x, float y);
protected void positionAtCursorOffset(int offset) {
+ // A HandleView relies on the layout, which may be nulled by external methods.
+ if (mLayout == null) {
+ // Will update controllers' state, hiding them and stopping selection mode if needed
+ prepareCursorControllers();
+ return;
+ }
+
addPositionToTouchUpFilter(offset);
final int line = mLayout.getLineForOffset(offset);
final int lineBottom = mLayout.getLineBottom(line);
diff --git a/core/jni/android/graphics/Picture.cpp b/core/jni/android/graphics/Picture.cpp
index 5ab6dd3..f28fc26 100644
--- a/core/jni/android/graphics/Picture.cpp
+++ b/core/jni/android/graphics/Picture.cpp
@@ -48,7 +48,7 @@
static void killPicture(JNIEnv* env, jobject, SkPicture* picture) {
SkASSERT(picture);
- delete picture;
+ picture->unref();
}
static void draw(JNIEnv* env, jobject, SkCanvas* canvas,
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index bbbca37..e325b8d 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2147,6 +2147,82 @@
<attr name="imeSubtypeExtraValue" format="string" />
</declare-styleable>
+ <!-- Use <code>accessibility-service</code> as the root tag of the XML resource that
+ describes an {@link android.accessibilityservice.AccessibilityService} service,
+ which is referenced from its
+ {@link android.accessibilityservice.AccessibilityService#SERVICE_META_DATA}
+ meta-data entry. -->
+ <declare-styleable name="AccessibilityService">
+ <!-- The event types this serivce would like to receive as specified in
+ {@link android.view.accessibility.AccessibilityEvent}. This setting
+ can be changed at runtime by calling
+ {@link android.accessibilityservice.AccessibilityService#setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)}. -->
+ <attr name="accessibilityEventTypes">
+ <!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED} events.-->
+ <flag name="typeViewClicked" value="0x00000001" />
+ <!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_LONG_CLICKED} events. -->
+ <flag name="typeViewLongClicked" value="0x00000002" />
+ <!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SELECTED} events. -->
+ <flag name="typeViewSelected" value="0x00000004" />
+ <!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_FOCUSED} events. -->
+ <flag name="typeViewFocused" value="0x00000008" />
+ <!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED} events. -->
+ <flag name="typeViewTextChanged" value="0x00000010" />
+ <!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED} events. -->
+ <flag name="typeWindowStateChanged" value="0x00000020" />
+ <!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED} events. -->
+ <flag name="typeNotificationStateChanged" value="0x00000040" />
+ <!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER} events. -->
+ <flag name="typeViewHoverEnter" value="0x00000080" />
+ <!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_EXIT} events. -->
+ <flag name="typeViewHoverExit" value="0x00000100" />
+ <!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START} events. -->
+ <flag name="typeTouchExplorationGestureStart" value="0x00000200" />
+ <!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END} events. -->
+ <flag name="typeTouchExplorationGestureEnd" value="0x00000400" />
+ <!-- Receives {@link android.view.accessibility.AccessibilityEvent#TYPES_ALL_MASK} i.e. all events. -->
+ <flag name="typeAllMask" value="0xffffffff" />
+ </attr>
+ <!-- Comma separated package names from which this serivce would like to receive events (leave out for all packages).
+ This setting can be changed at runtime by calling
+ {@link android.accessibilityservice.AccessibilityService#setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)}. -->
+ <attr name="packageNames" format="string" />
+ <!-- The feedback types this serivce provides as specified in
+ {@link android.accessibilityservice.AccessibilityServiceInfo}. This setting
+ can be changed at runtime by calling
+ {@link android.accessibilityservice.AccessibilityService#setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)}. -->
+ <attr name="accessibilityFeedbackType">
+ <!-- Provides {@link android.accessibilityservice.AccessibilityServiceInfo#FEEDBACK_SPOKEN} feedback. -->
+ <flag name="feedbackSpoken" value="0x00000001" />
+ <!-- Provides {@link android.accessibilityservice.AccessibilityServiceInfo#FEEDBACK_HAPTIC} feedback. -->
+ <flag name="feedbackHaptic" value="0x00000002" />
+ <!-- Provides {@link android.accessibilityservice.AccessibilityServiceInfo#FEEDBACK_AUDIBLE} feedback. -->
+ <flag name="feedbackAudible" value="0x00000004" />
+ <!-- Provides {@link android.accessibilityservice.AccessibilityServiceInfo#FEEDBACK_VISUAL} feedback. -->
+ <flag name="feedbackVisual" value="0x00000008" />
+ <!-- Provides {@link android.accessibilityservice.AccessibilityServiceInfo#FEEDBACK_GENERIC} feedback. -->
+ <flag name="feedbackGeneric" value="0x00000010" />
+ </attr>
+ <!-- The minimal period in milliseconds between two accessibility events are sent
+ to this serivce. This setting can be changed at runtime by calling
+ {@link android.accessibilityservice.AccessibilityService#setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)}. -->
+ <attr name="notificationTimeout" format="integer" />
+ <!-- Additional flags as specified in
+ {@link android.accessibilityservice.AccessibilityServiceInfo}.
+ This setting can be changed at runtime by calling
+ {@link android.accessibilityservice.AccessibilityService#setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)}. -->
+ <attr name="accessibilityFlags">
+ <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#DEFAULT} -->
+ <flag name="flagDefault" value="0x00000001" />
+ </attr>
+ <!-- Component name of an activity that allows the user to modify
+ the settings for this service. This setting cannot be changed at runtime. -->
+ <attr name="settingsActivity" />
+ <!-- Flag whether the accessibility service wants to be able to retrieve the
+ focused window content. This setting cannot be changed at runtime. -->
+ <attr name="canRetrieveWindowContent" format="boolean" />
+ </declare-styleable>
+
<!-- =============================== -->
<!-- Widget package class attributes -->
<!-- =============================== -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 5f72da5..41a566c 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1686,4 +1686,12 @@
<public type="attr" name="layout_columnWeight" />
<public type="attr" name="isAuxiliary" />
+
+ <public type="attr" name="accessibilityEventTypes" />
+ <public type="attr" name="packageNames" />
+ <public type="attr" name="accessibilityFeedbackType" />
+ <public type="attr" name="notificationTimeout" />
+ <public type="attr" name="accessibilityFlags" />
+ <public type="attr" name="canRetrieveWindowContent" />
+
</resources>
diff --git a/core/tests/coretests/src/android/view/GravityTest.java b/core/tests/coretests/src/android/view/GravityTest.java
index 010127f..180a390 100644
--- a/core/tests/coretests/src/android/view/GravityTest.java
+++ b/core/tests/coretests/src/android/view/GravityTest.java
@@ -29,14 +29,14 @@
assertOneGravity(Gravity.RIGHT, Gravity.RIGHT, false);
assertOneGravity(Gravity.RIGHT, Gravity.RIGHT, true);
- assertOneGravity(Gravity.TOP|Gravity.LEFT, Gravity.TOP, false);
- assertOneGravity(Gravity.TOP|Gravity.LEFT, Gravity.TOP, true);
+ assertOneGravity(Gravity.TOP, Gravity.TOP, false);
+ assertOneGravity(Gravity.TOP, Gravity.TOP, true);
- assertOneGravity(Gravity.BOTTOM|Gravity.LEFT, Gravity.BOTTOM, false);
- assertOneGravity(Gravity.BOTTOM|Gravity.LEFT, Gravity.BOTTOM, true);
+ assertOneGravity(Gravity.BOTTOM, Gravity.BOTTOM, false);
+ assertOneGravity(Gravity.BOTTOM, Gravity.BOTTOM, true);
- assertOneGravity(Gravity.CENTER_VERTICAL|Gravity.LEFT, Gravity.CENTER_VERTICAL, false);
- assertOneGravity(Gravity.CENTER_VERTICAL|Gravity.LEFT, Gravity.CENTER_VERTICAL, true);
+ assertOneGravity(Gravity.CENTER_VERTICAL, Gravity.CENTER_VERTICAL, false);
+ assertOneGravity(Gravity.CENTER_VERTICAL, Gravity.CENTER_VERTICAL, true);
assertOneGravity(Gravity.CENTER_HORIZONTAL, Gravity.CENTER_HORIZONTAL, false);
assertOneGravity(Gravity.CENTER_HORIZONTAL, Gravity.CENTER_HORIZONTAL, true);
@@ -44,8 +44,8 @@
assertOneGravity(Gravity.CENTER, Gravity.CENTER, false);
assertOneGravity(Gravity.CENTER, Gravity.CENTER, true);
- assertOneGravity(Gravity.FILL_VERTICAL|Gravity.LEFT, Gravity.FILL_VERTICAL, false);
- assertOneGravity(Gravity.FILL_VERTICAL|Gravity.LEFT, Gravity.FILL_VERTICAL, true);
+ assertOneGravity(Gravity.FILL_VERTICAL, Gravity.FILL_VERTICAL, false);
+ assertOneGravity(Gravity.FILL_VERTICAL, Gravity.FILL_VERTICAL, true);
assertOneGravity(Gravity.FILL_HORIZONTAL, Gravity.FILL_HORIZONTAL, false);
assertOneGravity(Gravity.FILL_HORIZONTAL, Gravity.FILL_HORIZONTAL, true);
@@ -53,11 +53,11 @@
assertOneGravity(Gravity.FILL, Gravity.FILL, false);
assertOneGravity(Gravity.FILL, Gravity.FILL, true);
- assertOneGravity(Gravity.CLIP_HORIZONTAL|Gravity.LEFT, Gravity.CLIP_HORIZONTAL, false);
- assertOneGravity(Gravity.CLIP_HORIZONTAL|Gravity.LEFT, Gravity.CLIP_HORIZONTAL, true);
+ assertOneGravity(Gravity.CLIP_HORIZONTAL, Gravity.CLIP_HORIZONTAL, false);
+ assertOneGravity(Gravity.CLIP_HORIZONTAL, Gravity.CLIP_HORIZONTAL, true);
- assertOneGravity(Gravity.CLIP_VERTICAL|Gravity.LEFT, Gravity.CLIP_VERTICAL, false);
- assertOneGravity(Gravity.CLIP_VERTICAL|Gravity.LEFT, Gravity.CLIP_VERTICAL, true);
+ assertOneGravity(Gravity.CLIP_VERTICAL, Gravity.CLIP_VERTICAL, false);
+ assertOneGravity(Gravity.CLIP_VERTICAL, Gravity.CLIP_VERTICAL, true);
assertOneGravity(Gravity.LEFT, Gravity.BEFORE, false);
assertOneGravity(Gravity.RIGHT, Gravity.BEFORE, true);
diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h
index 401638a..dd93fd8 100644
--- a/include/media/AudioEffect.h
+++ b/include/media/AudioEffect.h
@@ -44,50 +44,6 @@
public:
/*
- * Static methods for effect libraries management.
- */
-
- /*
- * Loads the effect library which path is given as first argument.
- * This must be the full path of a dynamic library (.so) implementing one or
- * more effect engines and exposing the effect library interface described in
- * EffectApi.h. The function returns a handle on the library for use by
- * further call to unloadEffectLibrary() to unload the library.
- *
- * Parameters:
- * libPath: full path of the dynamic library file in the file system.
- * handle: address where to return the library handle
- *
- * Returned status (from utils/Errors.h) can be:
- * NO_ERROR successful operation.
- * PERMISSION_DENIED could not get AudioFlinger interface or
- * application does not have permission to configure audio
- * NO_INIT effect factory not initialized or
- * library could not be loaded or
- * library does not implement required functions
- * BAD_VALUE invalid libPath string or handle
- *
- * Returned value:
- * *handle updated with library handle
- */
- static status_t loadEffectLibrary(const char *libPath, int *handle);
-
- /*
- * Unloads the effect library which handle is given as argument.
- *
- * Parameters:
- * handle: library handle
- *
- * Returned status (from utils/Errors.h) can be:
- * NO_ERROR successful operation.
- * PERMISSION_DENIED could not get AudioFlinger interface or
- * application does not have permission to configure audio
- * NO_INIT effect factory not initialized
- * BAD_VALUE invalid handle
- */
- static status_t unloadEffectLibrary(int handle);
-
- /*
* Static methods for effects enumeration.
*/
diff --git a/include/media/EffectsFactoryApi.h b/include/media/EffectsFactoryApi.h
index b63fac6..8ae13cc 100644
--- a/include/media/EffectsFactoryApi.h
+++ b/include/media/EffectsFactoryApi.h
@@ -132,50 +132,6 @@
////////////////////////////////////////////////////////////////////////////////
//
-// Function: EffectLoadLibrary
-//
-// Description: Loads the effect library which path is given as first argument.
-// This must be the full path of a dynamic library (.so) implementing one or
-// more effect engines and exposing the effect library interface described in
-// EffectApi.h. The function returns a handle on the library for used by
-// further call to EffectUnloadLibrary() to unload the library.
-//
-// Input:
-// libPath: full path of the dynamic library file in the file system.
-//
-// handle: address where to return the library handle
-//
-// Output:
-// returned value: 0 successful operation.
-// -ENODEV effect factory not initialized or
-// library could not be loaded or
-// library does not implement required functions
-// -EINVAL invalid libPath string or handle
-//
-////////////////////////////////////////////////////////////////////////////////
-int EffectLoadLibrary(const char *libPath, int *handle);
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Function: EffectUnloadLibrary
-//
-// Description: Unloads the effect library which handle is given as argument.
-//
-// Input:
-// handle: library handle
-//
-// Output:
-// returned value: 0 successful operation.
-// -ENODEV effect factory not initialized
-// -ENOENT invalid handle
-//
-////////////////////////////////////////////////////////////////////////////////
-int EffectUnloadLibrary(int handle);
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-//
// Function: EffectGetDescriptor
//
// Description: Returns the descriptor of the effect which uuid is pointed
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 75f3e71..d8fdc27 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -139,10 +139,6 @@
virtual int newAudioSessionId() = 0;
- virtual status_t loadEffectLibrary(const char *libPath, int *handle) = 0;
-
- virtual status_t unloadEffectLibrary(int handle) = 0;
-
virtual status_t queryNumberEffects(uint32_t *numEffects) = 0;
virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) = 0;
diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c
index b541be5..b0e8585 100644
--- a/media/libeffects/factory/EffectsFactory.c
+++ b/media/libeffects/factory/EffectsFactory.c
@@ -332,18 +332,6 @@
return ret;
}
-int EffectLoadLibrary(const char *libPath, int *handle)
-{
- // TODO: see if this interface still makes sense with the use of config files
- return -ENOSYS;
-}
-
-int EffectUnloadLibrary(int handle)
-{
- // TODO: see if this interface still makes sense with the use of config files
- return -ENOSYS;
-}
-
int EffectIsNullUuid(effect_uuid_t *uuid)
{
if (memcmp(uuid, EFFECT_UUID_NULL, sizeof(effect_uuid_t))) {
diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp
index a043329..8d98900 100644
--- a/media/libmedia/AudioEffect.cpp
+++ b/media/libmedia/AudioEffect.cpp
@@ -398,20 +398,6 @@
// -------------------------------------------------------------------------
-status_t AudioEffect::loadEffectLibrary(const char *libPath, int *handle)
-{
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
- if (af == 0) return PERMISSION_DENIED;
- return af->loadEffectLibrary(libPath, handle);
-}
-
-status_t AudioEffect::unloadEffectLibrary(int handle)
-{
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
- if (af == 0) return PERMISSION_DENIED;
- return af->unloadEffectLibrary(handle);
-}
-
status_t AudioEffect::queryNumberEffects(uint32_t *numEffects)
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index eec47c0..158d2f5 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -63,8 +63,6 @@
GET_RENDER_POSITION,
GET_INPUT_FRAMES_LOST,
NEW_AUDIO_SESSION_ID,
- LOAD_EFFECT_LIBRARY,
- UNLOAD_EFFECT_LIBRARY,
QUERY_NUM_EFFECTS,
QUERY_EFFECT,
GET_EFFECT_DESCRIPTOR,
@@ -528,37 +526,6 @@
return id;
}
- virtual status_t loadEffectLibrary(const char *libPath, int *handle)
- {
- if (libPath == NULL || handle == NULL) {
- return BAD_VALUE;
- }
- *handle = 0;
- Parcel data, reply;
- data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
- data.writeCString(libPath);
- status_t status = remote()->transact(LOAD_EFFECT_LIBRARY, data, &reply);
- if (status == NO_ERROR) {
- status = reply.readInt32();
- if (status == NO_ERROR) {
- *handle = reply.readInt32();
- }
- }
- return status;
- }
-
- virtual status_t unloadEffectLibrary(int handle)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
- data.writeInt32(handle);
- status_t status = remote()->transact(UNLOAD_EFFECT_LIBRARY, data, &reply);
- if (status == NO_ERROR) {
- status = reply.readInt32();
- }
- return status;
- }
-
virtual status_t queryNumberEffects(uint32_t *numEffects)
{
Parcel data, reply;
@@ -952,21 +919,6 @@
reply->writeInt32(newAudioSessionId());
return NO_ERROR;
} break;
- case LOAD_EFFECT_LIBRARY: {
- CHECK_INTERFACE(IAudioFlinger, data, reply);
- int handle;
- status_t status = loadEffectLibrary(data.readCString(), &handle);
- reply->writeInt32(status);
- if (status == NO_ERROR) {
- reply->writeInt32(handle);
- }
- return NO_ERROR;
- }
- case UNLOAD_EFFECT_LIBRARY: {
- CHECK_INTERFACE(IAudioFlinger, data, reply);
- reply->writeInt32(unloadEffectLibrary(data.readInt32()));
- return NO_ERROR;
- }
case QUERY_NUM_EFFECTS: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
uint32_t numEffects;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 67c6d96..053854f 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -4615,28 +4615,6 @@
// ----------------------------------------------------------------------------
-status_t AudioFlinger::loadEffectLibrary(const char *libPath, int *handle)
-{
- // check calling permissions
- if (!settingsAllowed()) {
- return PERMISSION_DENIED;
- }
-
- Mutex::Autolock _l(mLock);
- return EffectLoadLibrary(libPath, handle);
-}
-
-status_t AudioFlinger::unloadEffectLibrary(int handle)
-{
- // check calling permissions
- if (!settingsAllowed()) {
- return PERMISSION_DENIED;
- }
-
- Mutex::Autolock _l(mLock);
- return EffectUnloadLibrary(handle);
-}
-
status_t AudioFlinger::queryNumberEffects(uint32_t *numEffects)
{
Mutex::Autolock _l(mLock);
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index f3e1984..0698dcb 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -147,10 +147,6 @@
virtual int newAudioSessionId();
- virtual status_t loadEffectLibrary(const char *libPath, int *handle);
-
- virtual status_t unloadEffectLibrary(int handle);
-
virtual status_t queryNumberEffects(uint32_t *numEffects);
virtual status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor);
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index d96369b..cc9e532 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -21,6 +21,8 @@
import com.android.internal.os.HandlerCaller.SomeArgs;
import com.android.server.wm.WindowManagerService;
+import org.xmlpull.v1.XmlPullParserException;
+
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.IAccessibilityServiceConnection;
@@ -54,6 +56,7 @@
import android.view.accessibility.IAccessibilityManager;
import android.view.accessibility.IAccessibilityManagerClient;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -96,17 +99,16 @@
final List<IAccessibilityManagerClient> mClients =
new ArrayList<IAccessibilityManagerClient>();
- final Map<ComponentName, Service> mComponentNameToServiceMap =
- new HashMap<ComponentName, Service>();
+ final Map<ComponentName, Service> mComponentNameToServiceMap = new HashMap<ComponentName, Service>();
- private final List<ServiceInfo> mInstalledServices = new ArrayList<ServiceInfo>();
+ private final List<AccessibilityServiceInfo> mInstalledServices = new ArrayList<AccessibilityServiceInfo>();
private final Set<ComponentName> mEnabledServices = new HashSet<ComponentName>();
private final SimpleStringSplitter mStringColonSplitter = new SimpleStringSplitter(':');
- private final SparseArray<List<ServiceInfo>> mFeedbackTypeToEnabledServicesMap =
- new SparseArray<List<ServiceInfo>>();
+ private final SparseArray<List<AccessibilityServiceInfo>> mFeedbackTypeToEnabledServicesMap =
+ new SparseArray<List<AccessibilityServiceInfo>>();
private PackageManager mPackageManager;
@@ -298,20 +300,28 @@
return (OWN_PROCESS_ID != Binder.getCallingPid());
}
- public List<ServiceInfo> getAccessibilityServiceList() {
+ public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList() {
synchronized (mLock) {
return mInstalledServices;
}
}
- public List<ServiceInfo> getEnabledAccessibilityServiceList(int feedbackType) {
+ public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType) {
+ SparseArray<List<AccessibilityServiceInfo>> feedbackTypeToEnabledServicesMap =
+ mFeedbackTypeToEnabledServicesMap;
+ List<AccessibilityServiceInfo> enabledServices = new ArrayList<AccessibilityServiceInfo>();
synchronized (mLock) {
- List<ServiceInfo> enabledServices = mFeedbackTypeToEnabledServicesMap.get(feedbackType);
- if (enabledServices == null) {
- return Collections.emptyList();
+ while (feedbackType != 0) {
+ final int feedbackTypeBit = (1 << Integer.numberOfTrailingZeros(feedbackType));
+ feedbackType &= ~feedbackTypeBit;
+ List<AccessibilityServiceInfo> perFeedbackType =
+ feedbackTypeToEnabledServicesMap.get(feedbackTypeBit);
+ if (perFeedbackType != null) {
+ enabledServices.addAll(perFeedbackType);
+ }
}
- return enabledServices;
}
+ return enabledServices;
}
public void interrupt() {
@@ -345,15 +355,16 @@
Service service = (Service) arguments.arg2;
synchronized (mLock) {
- service.mEventTypes = info.eventTypes;
- service.mFeedbackType = info.feedbackType;
- String[] packageNames = info.packageNames;
- if (packageNames != null) {
- service.mPackageNames.addAll(Arrays.asList(packageNames));
+ // If the XML manifest had data to configure the service its info
+ // should be already set. In such a case update only the dynamically
+ // configurable properties.
+ AccessibilityServiceInfo oldInfo = service.mAccessibilityServiceInfo;
+ if (oldInfo != null) {
+ oldInfo.updateDynamicallyConfigurableProperties(info);
+ service.setAccessibilityServiceInfo(oldInfo);
+ } else {
+ service.setAccessibilityServiceInfo(info);
}
- service.mNotificationTimeout = info.notificationTimeout;
- service.mIsDefault = (info.flags & AccessibilityServiceInfo.DEFAULT) != 0;
-
updateStateOnEnabledService(service);
}
return;
@@ -369,10 +380,20 @@
mInstalledServices.clear();
List<ResolveInfo> installedServices = mPackageManager.queryIntentServices(
- new Intent(AccessibilityService.SERVICE_INTERFACE), PackageManager.GET_SERVICES);
+ new Intent(AccessibilityService.SERVICE_INTERFACE),
+ PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
for (int i = 0, count = installedServices.size(); i < count; i++) {
- mInstalledServices.add(installedServices.get(i).serviceInfo);
+ ResolveInfo resolveInfo = installedServices.get(i);
+ AccessibilityServiceInfo accessibilityServiceInfo;
+ try {
+ accessibilityServiceInfo = new AccessibilityServiceInfo(resolveInfo, mContext);
+ mInstalledServices.add(accessibilityServiceInfo);
+ } catch (XmlPullParserException xppe) {
+ Slog.e(LOG_TAG, "Error while initializing AccessibilityServiceInfo", xppe);
+ } catch (IOException ioe) {
+ Slog.e(LOG_TAG, "Error while initializing AccessibilityServiceInfo", ioe);
+ }
}
}
@@ -595,22 +616,22 @@
* @param installedServices All installed {@link AccessibilityService}s.
* @param enabledServices The {@link ComponentName}s of the enabled services.
*/
- private void updateServicesStateLocked(List<ServiceInfo> installedServices,
+ private void updateServicesStateLocked(List<AccessibilityServiceInfo> installedServices,
Set<ComponentName> enabledServices) {
Map<ComponentName, Service> componentNameToServiceMap = mComponentNameToServiceMap;
boolean isEnabled = mIsEnabled;
for (int i = 0, count = installedServices.size(); i < count; i++) {
- ServiceInfo intalledService = installedServices.get(i);
- ComponentName componentName = new ComponentName(intalledService.packageName,
- intalledService.name);
+ AccessibilityServiceInfo installedService = installedServices.get(i);
+ ComponentName componentName = ComponentName.unflattenFromString(
+ installedService.getId());
Service service = componentNameToServiceMap.get(componentName);
if (isEnabled) {
if (enabledServices.contains(componentName)) {
if (service == null) {
- service = new Service(componentName, intalledService);
+ service = new Service(installedService);
}
service.bind();
} else if (!enabledServices.contains(componentName)) {
@@ -671,12 +692,13 @@
*/
private void updateStateOnEnabledService(Service service) {
int feedbackType = service.mFeedbackType;
- List<ServiceInfo> enabledServices = mFeedbackTypeToEnabledServicesMap.get(feedbackType);
+ List<AccessibilityServiceInfo> enabledServices =
+ mFeedbackTypeToEnabledServicesMap.get(feedbackType);
if (enabledServices == null) {
- enabledServices = new ArrayList<ServiceInfo>();
+ enabledServices = new ArrayList<AccessibilityServiceInfo>();
mFeedbackTypeToEnabledServicesMap.put(feedbackType, enabledServices);
}
- enabledServices.add(service.mServiceInfo);
+ enabledServices.add(service.mAccessibilityServiceInfo);
// We enable touch exploration if at least one
// enabled service provides spoken feedback.
@@ -688,12 +710,12 @@
}
private void updateStateOnDisabledService(Service service) {
- List<ServiceInfo> enabledServices =
+ List<AccessibilityServiceInfo> enabledServices =
mFeedbackTypeToEnabledServicesMap.get(service.mFeedbackType);
if (enabledServices == null) {
return;
}
- enabledServices.remove(service.mServiceInfo);
+ enabledServices.remove(service.mAccessibilityServiceInfo);
// We disable touch exploration if no
// enabled service provides spoken feedback.
if (enabledServices.isEmpty()
@@ -714,7 +736,7 @@
class Service extends IAccessibilityServiceConnection.Stub implements ServiceConnection {
int mId = 0;
- ServiceInfo mServiceInfo;
+ AccessibilityServiceInfo mAccessibilityServiceInfo;
IBinder mService;
@@ -740,10 +762,9 @@
final SparseArray<AccessibilityEvent> mPendingEvents =
new SparseArray<AccessibilityEvent>();
- Service(ComponentName componentName, ServiceInfo serviceInfo) {
+ Service(AccessibilityServiceInfo accessibilityServiceInfo) {
mId = sIdCounter++;
- mComponentName = componentName;
- mServiceInfo = serviceInfo;
+ setAccessibilityServiceInfo(accessibilityServiceInfo);
mIntent = new Intent().setComponent(mComponentName);
mIntent.putExtra(Intent.EXTRA_CLIENT_LABEL,
com.android.internal.R.string.accessibility_binding_label);
@@ -751,6 +772,20 @@
mContext, 0, new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 0));
}
+ public void setAccessibilityServiceInfo(AccessibilityServiceInfo info) {
+ mAccessibilityServiceInfo = info;
+ ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo;
+ mComponentName = new ComponentName(serviceInfo.packageName, serviceInfo.name);
+ mEventTypes = info.eventTypes;
+ mFeedbackType = info.feedbackType;
+ String[] packageNames = info.packageNames;
+ if (packageNames != null) {
+ mPackageNames.addAll(Arrays.asList(packageNames));
+ }
+ mNotificationTimeout = info.notificationTimeout;
+ mIsDefault = (info.flags & AccessibilityServiceInfo.DEFAULT) != 0;
+ }
+
/**
* Binds to the accessibility service.
*
@@ -805,6 +840,9 @@
if (!mServices.contains(this)) {
mServices.add(this);
mComponentNameToServiceMap.put(componentName, this);
+ if (isConfigured()) {
+ updateStateOnEnabledService(this);
+ }
}
}
} catch (RemoteException re) {
diff --git a/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java
index 2bc6825..302a2d6 100644
--- a/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java
@@ -150,7 +150,8 @@
String secondMockServiceClassName = MySecondMockAccessibilityService.class.getName();
// look for the two mock services
- for (ServiceInfo serviceInfo : mManagerService.getAccessibilityServiceList()) {
+ for (AccessibilityServiceInfo info : mManagerService.getInstalledAccessibilityServiceList()) {
+ ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo;
if (packageName.equals(serviceInfo.packageName)) {
if (firstMockServiceClassName.equals(serviceInfo.name)) {
firstMockServiceInstalled = true;
diff --git a/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java b/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java
index 38fed22..1463d30 100644
--- a/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java
@@ -25,6 +25,7 @@
import org.easymock.IArgumentMatcher;
+import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.pm.ServiceInfo;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
@@ -62,20 +63,22 @@
@MediumTest
public void testGetAccessibilityServiceList() throws Exception {
// create a list of installed accessibility services the mock service returns
- List<ServiceInfo> expectedServices = new ArrayList<ServiceInfo>();
- ServiceInfo serviceInfo = new ServiceInfo();
- serviceInfo.name = "TestServiceInfoName";
- expectedServices.add(serviceInfo);
+ List<AccessibilityServiceInfo> expectedServices = new ArrayList<AccessibilityServiceInfo>();
+ AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo();
+ accessibilityServiceInfo.packageNames = new String[] { "foo.bar" };
+ expectedServices.add(accessibilityServiceInfo);
// configure the mock service behavior
IAccessibilityManager mockServiceInterface = mMockServiceInterface;
expect(mockServiceInterface.addClient(anyIAccessibilityManagerClient())).andReturn(true);
- expect(mockServiceInterface.getAccessibilityServiceList()).andReturn(expectedServices);
+ expect(mockServiceInterface.getInstalledAccessibilityServiceList()).andReturn(
+ expectedServices);
replay(mockServiceInterface);
// invoke the method under test
AccessibilityManager manager = new AccessibilityManager(mContext, mockServiceInterface);
- List<ServiceInfo> receivedServices = manager.getAccessibilityServiceList();
+ List<AccessibilityServiceInfo> receivedServices =
+ manager.getInstalledAccessibilityServiceList();
// check expected result (list equals() compares it contents as well)
assertEquals("All expected services must be returned", receivedServices, expectedServices);