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>
  * &lt;service android:name=".MyAccessibilityService"&gt;<br>
- *     &lt;intent-filter&gt;<br>
- *         &lt;action android:name="android.accessibilityservice.AccessibilityService" /&gt;<br>
- *     &lt;/intent-filter&gt;<br>
+ * &nbsp;&nbsp;&lt;intent-filter&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;action android:name="android.accessibilityservice.AccessibilityService" /&gt;<br>
+ * &nbsp;&nbsp;&lt;/intent-filter&gt;<br>
  * &lt;/service&gt;<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>
+ *       &lt;service android:name=".MyAccessibilityService"&gt;<br>
+ *       &nbsp;&nbsp;&lt;intent-filter&gt;<br>
+ *       &nbsp;&nbsp;&nbsp;&nbsp;&lt;action android:name="android.accessibilityservice.AccessibilityService" /&gt;<br>
+ *       &nbsp;&nbsp;&lt;/intent-filter&gt;<br>
+ *       &nbsp;&nbsp;&lt;meta-data android:name="android.accessibilityservice.as" android:resource="@xml/accessibilityservice" /&gt;<br>
+ *       &lt;/service&gt;<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>&lt;{@link android.R.styleable#AccessibilityService accessibility-service}&gt;</code>
+     * tag. This is a a sample XML file configuring an accessibility service:
+     * <p>
+     * <code>
+     *   &lt;?xml version="1.0" encoding="utf-8"?&gt;<br>
+     *   &lt;accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"<br>
+     *   &nbsp;&nbsp;android:eventTypes="typeViewClicked|typeViewFocused"<br>
+     *   &nbsp;&nbsp;android:packageNames="foo.bar, foo.baz"<br>
+     *   &nbsp;&nbsp;android:feedbackType="feedbackSpoken"<br>
+     *   &nbsp;&nbsp;android:notificationTimeout="100"<br>
+     *   &nbsp;&nbsp;android:flags="flagDefault"<br>
+     *   &nbsp;&nbsp;android:settingsActivity="foo.bar.TestBackActivity"<br>
+     *   &nbsp;&nbsp;. . .<br>
+     *   /&gt;
+     * </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);